Sollte sich ein Objekt selber zeichnen?



  • Ich plane eine Anwendung, wo der Nutzer Objekte auf die Anwendung "zeichnen" kann (wie es z.b. bei Visio oder andere Organigramm-Programmen passiert). Diese Objekte möchte ich in Klassen packen.

    Da taucht bei mir aber eine Frage nach dem richtigen OOP-Ansatz auf. Sollten sich die Objekte selber zeichnen (also einen Befehl von der Hauptanwendung bekommen sich zu zeichnen) oder sollte die Hauptanwendung nur nach Daten von den Klassen verlangen wo und wie das Objekt gezeichnet werden soll und das zeichnen dann selbst übernehmen??

    Ich poste das bewusst hier, da ich das rein vom Prinzip her gerne wüsste ohne auf Bibliotheken oder OS einzugehen.

    Mir selbst wäre, die erste Variante plausibler, da ja sonst die Anwendung auch genau wissen müsste, wie das Objekt gezeichnet werden soll. Aber was ist die "richtige" oder "bessere" Variante?



  • Das Objekt sollte eine Member-Funktion Klasse::Draw(...) besitzen.



  • Ich kenne mich zwar nicht sehr mit OOA aus, aber wenn ich das MVC-Modell richtig verstanden habe, sollte das Zeichnen von den Daten getrennt sein.
    Ist auch einleuchtender, weil der Benutzer vielleicht verschiedene Verfahrensweisen für das Zeichnen angeben möchte.



  • Wenn Objekte sich selbst zeichen können, bringt das zwei Probleme mit sich:

    a) Das ganze wird unportabel
    b) Es wird unschön, wenn sie sich in zwei, drei oder mehr Varianten zeichen
    sollen (z.B. in verschiedenen Ansichten)

    Vorschläge:
    Schreibe eine Klasse, die nur die Daten beinhaltet. Davon kannst du weitere
    Objekte ableiten, die sich dann zeichnen können, oder du kannst deine Daten-
    klasse als Member mitgeben.



  • Sollten sich die Objekte selber zeichnen (also einen Befehl von der Hauptanwendung bekommen sich zu zeichnen) oder sollte die Hauptanwendung nur nach Daten von den Klassen verlangen wo und wie das Objekt gezeichnet werden soll und das zeichnen dann selbst übernehmen??

    Ersteres. Wenn es um Objekte geht, hilft der Merksatz: Tell don't ask

    Ich kenne mich zwar nicht sehr mit OOA aus, aber wenn ich das MVC-Modell richtig verstanden habe, sollte das Zeichnen von den Daten getrennt sein.
    Ist auch einleuchtender, weil der Benutzer vielleicht verschiedene Verfahrensweisen für das Zeichnen angeben möchte

    Es ist zwar richtig, dass man die Anwendungsdaten von der Sicht auf selbige trennen sollte, dass ändert aber nichts daran, dass letztlich irgendein Objekt eine draw-Methode haben sollte, die von der Anwendung zu gewissen Zeitpunkten aufgerufen wird. Das ist auf jeden Fall besser, als eine Anwendung die ständig den Zustand ihrer Objekte erfragen muss.



  • Jo, lass Objekte sich selber zeichnen.
    Ich hab in meinem Game ne Klasse für Grafiken, dort gibt es dann eine Funktion DrawGame().
    Die malt zuerst den Untergrund, dann werden die Einheiten in einer for-Schleife alle abgegangen und zeichnen sich selbst.

    Das finde ich sehr übersichtlich und du hast alle Daten (Koordinaten, Bewegungszustand, Animationsstufe) des Objekts gleich griffbereit.

    Es ist doch schwachsinnig, ein Objekt an eine Funktion zu übergeben, die dann ständig alle Eigenschaften des Objekts abfrägt und irgendwann mal was macht. Damit verletzt du außerdem das Prinzip der Kapselung.



  • Yep! Aus dem "Tell, Don't Ask"-Artikel (http://www.pragmaticprogrammer.com/ppllc/papers/1998_05.html): "The fundamental principle of Object Oriented programming is the unification of methods and data. Splitting this up inappropriately gets you right back to procedural programming."

    Trennung von Doc und View in der GUI-Programmierung, siehe:
    http://www.henkessoft.de/mfc_einsteigerbuch_kapitel7.htm



  • Mir scheint, das Tell-don't-ask-Prinzip ist entweder ziemlich übersimplifiziert, oder es läßt sich hier im speziellen nicht anwenden, denn es ignoriert das MVC-Muster, da ich dann den Model-Objekten sagen müsste, dass sie sich zeichnen. Ich frage aber nach dem Zustand des Models, und beauftrage das View-Objekt mit der Zeichenaktion.



  • Man sollte nicht die Daten von den Funktionen trennen. Ich gehe davon aus, dass das Objekt die zum zeichnen nötigen Informationen enthält (Position, Zustand, etc.). Also soll sich das Objekt gefälligst auch selber zeichnen.



  • wie wäre es wenn das objekt ein draw objekt hätte
    z.b.

    class zeichner_base
    {
    public:
        void draw () = 0;
        ~zeichner_base() = 0;
    };
    
    zeichner_base::~zeichner_base()
    {
    }
    
    class win32_zeichner : public zeichner_base
    {
    public:
        void draw()
        {
            //...
        }
    };
    
    class konsole_zeichner : public zeichner_base
    {
    public:
        void draw()
        {
            //...
        }
    };
    
    class foo
    {
    public:
        void draw()
        {
            z->draw();
        }
    private:
        static zeichner_base * const z;
    };
    
    zeichner_base foo::z = new konsole_zeichner();
    //oder
    zeichner_base foo::z = new win32_zeichner();
    

    das objekt kann sich dann auch selbst zeichnen, man hatt aber immer noch die möglichkeit die view-klasse zu wäckseln.
    (irgend wie glaube ich das man das vielleicht besser mit ein template lösen könnte)


Anmelden zum Antworten