Sauberer Klassenentwurf



  • Hallo,

    ich habe mal eine Frage bezüglich eines Klassenentwurfes. Ich versuche das mal an einem Beispiel deutlich zu machen:

    Nehmen wir als Beispiel drei Klassen aus einer 2D Engine. Es gibt folgende Klassen:

    1. GameController
    2. ScenenController
    3. Scene

    In dem GameController wird ein ScenenController erzeugt um die Scenen zu verwalten und z.B. zu rendern etc. Beim Konstruktoraufruf des ScenenControllers wird der GameController selbst mit übergeben. Also z.B.

    //Innerhalb des GameControllers
    SceneController sc = new SceneController(this)
    

    Der Gamecontroller wird an die Scene übergeben, da viele Elemente des GameControllers für den ScenenController wichtig sind. Diese Könnten auch einzelnt als Parameter mit übergeben werden. Dann müßten aber sehr viele Parameter übergeben werden.

    Innerhalb des ScenenControllers wird der GameController welcher das Objekt verwendet in einem Feld gespeichert. Der Konstruktor würde dann in etwa so aussehen

    GameController gameController;
    
    public ScenenController(GameController gc)
    {
      this.gameController = gc; 
    }
    

    Nun kann auf Properties des GameControllers innerhalb des SceneControllers einfach zugegriffen werden.

    😡 An dieser Stelle habe ich schon ein ungutes Gefühl !

    Der Scene, innerhalb des SceneControllers, wird als Parameter des Konstruktors ebenfalls der ScenenController mit übergeben. Wenn in einer Scene dann auf den Gamecontroller zugegrifen werden soll würde das wie folgt aussehen:

    this.sceneController.gameController.Camera
    

    Ok hier mein Problem:

    nachdem was ich in der Schule gelernt habe, ist das hier nicht gerade der schönste Klassenentwurf, da die Klassen alle voneinander abhängig sind. Ich habe dabei, wie bereits erwähnt, ein unangenehmes Gefühl. Allerdings fehlt mir auch die Erfahrung, ob es üblich ist eine solche Herachie zu schaffen, in der die aufrufende Klasse immer selbst mit als Parameter des Konstruktors übergeben wird.

    Daher meine Frage an euch: Sollte man so etwas vermeiden oder kommt es an der ein oder andere Stelle schon mal vor?

    Liebe Grüße und Danke fürs Lesen!



  • mawilab schrieb:

    Hallo,

    ich habe mal eine Frage bezüglich eines Klassenentwurfes. Ich versuche das mal an einem Beispiel deutlich zu machen:

    Nehmen wir als Beispiel drei Klassen aus einer 2D Engine. Es gibt folgende Klassen:

    1. GameController
    2. ScenenController
    3. Scene

    In dem GameController wird ein ScenenController erzeugt um die Scenen zu verwalten und z.B. zu rendern etc. Beim Konstruktoraufruf des ScenenControllers wird der GameController selbst mit übergeben. Also z.B.

    //Innerhalb des GameControllers
    SceneController sc = new SceneController(this)
    

    Der Gamecontroller wird an die Scene übergeben, da viele Elemente des GameControllers für den ScenenController wichtig sind. Diese Könnten auch einzelnt als Parameter mit übergeben werden. Dann müßten aber sehr viele Parameter übergeben werden.

    Innerhalb des ScenenControllers wird der GameController welcher das Objekt verwendet in einem Feld gespeichert. Der Konstruktor würde dann in etwa so aussehen

    GameController gameController;
    
    public ScenenController(GameController gc)
    {
      this.gameController = gc; 
    }
    

    Nun kann auf Properties des GameControllers innerhalb des SceneControllers einfach zugegriffen werden.

    😡 An dieser Stelle habe ich schon ein ungutes Gefühl !

    Der Scene, innerhalb des SceneControllers, wird als Parameter des Konstruktors ebenfalls der ScenenController mit übergeben. Wenn in einer Scene dann auf den Gamecontroller zugegrifen werden soll würde das wie folgt aussehen:

    this.sceneController.gameController.Camera
    

    Ok hier mein Problem:

    nachdem was ich in der Schule gelernt habe, ist das hier nicht gerade der schönste Klassenentwurf, da die Klassen alle voneinander abhängig sind. Ich habe dabei, wie bereits erwähnt, ein unangenehmes Gefühl. Allerdings fehlt mir auch die Erfahrung, ob es üblich ist eine solche Herachie zu schaffen, in der die aufrufende Klasse immer selbst mit als Parameter des Konstruktors übergeben wird.

    Daher meine Frage an euch: Sollte man so etwas vermeiden oder kommt es an der ein oder andere Stelle schon mal vor?

    Liebe Grüße und Danke fürs Lesen!

    Ich fürchte, es gibt keine allgemine Antwort, sondern sie hängt von der verwendeten Programmiersprache ab.


  • Mod

    Was ist das für eine Sprache? Java? Konkrete Stilfragen zu Klassenhierarchien haben nämlich auch etwas mit den Möglichkeiten und üblichen Strategien der Sprache zu tun.

    Insgesamt klingelten bei mir als C++'ler schon im ersten Absatz

    Nehmen wir als Beispiel drei Klassen aus einer 2D Engine. Es gibt folgende Klassen:

    1. GameController
    2. ScenenController
    3. Scene

    alle Alarmglocken. Fehlt bloß noch ein AbstractSceneControllerFactoryDecorationManager. Ich würde daher sagen, dass deine Probleme aus den zu unspezifischen Klassenaufgaben und dem Zwang alles als Klasse zu machen stammen. Aber nicht überall pflegt man diesen Stil und in anderen Sprachen würde man dir sicherlich ein noch extravaganteres, aber besser durchdachtes, Klassengepflecht empfehlen. Und hätte damit im Rahmen der Sprache absolut Recht.

    edit: volkard drückt's mal wieder schneller und in einem einzigen Satz aus.



  • Hallo,

    bei dem Programm handelt es sich um C#.

    Bislang war ich in dem glauben, dass ein Klassenetnwurf in allen objektorientierten Sprachen umgesetzt werden kann. Also ich Plane eine Anwendung mit CRC Karten, zeichne mir ein schönes UML Diagramm und dann geht es los 🙂 !

    Warum unterscheidet sich der Aufbau der Klassen grundsätzlich bei anderen objektorientierten sprachen ?

    Es gibt ja z.B. verschiedene Entwurfsmuster wie z.B. MVC. Wenn ich mit der Anwendung in C# fertig bin würde ich diese gern in Java umsetzen. Spieziel geht es hier um WP und Android Anwendungen. Die Funktion der Klassen soll gleich bleiben so, dass der Umgang mit den einzelnen Elemente z.B. das erstellen einer neuer Scene etc. vom Prinzip gleich bleibt auch, wenn die Sprache sich ändert.

    LG



  • mawilab schrieb:

    Warum unterscheidet sich der Aufbau der Klassen grundsätzlich bei anderen objektorientierten sprachen ?

    Lass uns davon mal kurz absehen.

    mawilab schrieb:

    Es gibt ja z.B. verschiedene Entwurfsmuster wie z.B. MVC. Wenn ich mit der Anwendung in C# fertig bin würde ich diese gern in Java umsetzen.

    Das passt. Die sind Entwurfskompatibel.

    Nu, wo C#/Java klar ist, gehts weiter im Text. Ohne Belehrungen, wie man es in Lisp/PHP/Perl/C++/D/Ocaml/Prolog/Logo ansetzen sollte.


  • Mod

    Bislang war ich in dem glauben, dass ein Klassenetnwurf in allen objektorientierten Sprachen umgesetzt werden kann.

    Gehen geht das schon in alle Sprachen (Eventuelle Ausnahme: Mehrfachvererbung, die es in manchen Sprachen einfach nicht gibt). Die Frage ist bloß, was ist gut und üblich, um die Stärken der Sprache auszuspielen. Zum Beispiel hast du in C++ ganz andere Möglichkeiten, generische Algorithmen zu programmieren als in Java. Java kennt noch nicht einmal freie Funktionen im Sinne von C++ (ich glaube C# auch nicht. Kenne mich mit C# aber nicht aus, daher kann ich dir auch nicht konkret helfen, sondern nur erklären, warum verschiedene Sprachen anders sind). Kein C++-Programmierer käme je auf die Idee, ernsthaft ein Programm ohne diese Mittel zu schreiben. Die Existenz dieser Mittel beeinflusst aber, wie man seine Objekte optimalerweise gestaltet. Java hat dafür wieder andere Mittel. Zum Beispiel fördert die Sprache durch die Interfaces geradezu tiefe Vererbungshierarchien und dadurch dass alles über Pointer und dynamische Erzeugung gemacht wird (im C++-Sinne, keine Ahnung wie das in Java tatsächlich heißt. Wahrscheinlich gar nichts spezielles, da es einfach ganz normal ist), liegt auch irgendwie nahe, dass man oft Polymorphie benutzt. Daher sehen typische Klassendesigns in verschiedenen Sprachen oft sehr unterschiedlich aus. Wenn man versucht, in einer Sprache wie in einer anderen zu programmieren, dann nutzt man nicht die Stärken der Sprache aus, behindert sich möglicherweise sogar selbst.



  • Super, vielen Dank für die tollen Erklärungen 🙂 !



  • SeppJ schrieb:

    Insgesamt klingelten bei mir als C++'ler schon im ersten Absatz

    Nehmen wir als Beispiel drei Klassen aus einer 2D Engine. Es gibt folgende Klassen:

    1. GameController
    2. ScenenController
    3. Scene

    alle Alarmglocken. Fehlt bloß noch ein AbstractSceneControllerFactoryDecorationManager. Ich würde daher sagen, dass deine Probleme aus den zu unspezifischen Klassenaufgaben und dem Zwang alles als Klasse zu machen stammen.

    Ich verfolge eigentlich auch die Strategie möglichst ein Objekt mit nur einer *definierten* Aufgabe zu betrauen. Bei Klassennamen wie "Controller", "Manager", etc. klingeln dementsprechend auch meine Alarmglocken - zeigen sie doch, dass man eigentlich gar nicht weiss, was die Klasse denn tun soll und man gedanklich erst auf dem Stand "ich brauch jetzt irgendeine Klasse um was zu verwalten" ist.

    Mir selbst hilft da ungemein einfach bei der Entwicklung direkt Doxygen-Doku zu schreiben. Erwischt man sich nämlich dabei, sich aus den Fingern saugen zu müssen, was man als Zweck der Klasse denn nun dokumentieren soll, ist das ein sicheres Zeichen für ein "suboptimales" Klassendesign.


Log in to reply