2016-10-11 1 views
1

Ist diese gute/akzeptable Vorgehensweise, um von einem Objekt abzuleiten, nur um die gesamte mit der Erstellung dieses Objekts zusammenhängende Logik auszublenden.Verwenden der Vererbung zum Verkapseln der Komposition

Zum Beispiel (obwohl nicht perfekt Beispiel) Ich habe eine Szene-Klasse. Ich möchte es mit einigen Entitäten, einigen Systemen, Hintergrundfarbe und so weiter initialisieren. Ich könnte Factory für das erstellen, aber stattdessen möchte ich alles im Konstruktor der abgeleiteten Klasse tun.

Statt dessen:

var scene = new Scene(); 
scene.Systems (new ColisionSystem); 
scene.Systems (new MovementSystem); 
scene.SceneGraph = new MyCustomSceneGraph(); 

ich dies tun:

class MyScene : Scene 
{ 
    void MyScene(SceneGraph sceneGraph) 
    { 
     this.Systems (new ColisionSystem); 
     this.Systems (new MovementSystem); 

     this.SceneGraph = sceneGraph; 
    } 
} 

var scene = new MyScene(new MyCustomSceneGraph()); 

Also habe ich alles, was Schöpfung Sachen in der Konstruktor mich verstecke und als Bonus Ich habe separate Datei für jede Szene werde ich schaffen .

Auf der anderen Seite. Wenn ich jemals einen Szeneneditor erstelle, kann das ein Problem sein. Denn in diesem Fall sollte der Client des Szenenobjekts für die Vorbereitung der Szene verantwortlich sein und nicht die Szene selbst.

So ist diese akzeptable Praxis oder verletzt SRP?

+3

scheint nicht eine sehr gute Verwendung der Erbschaft für mich. Warum nicht einfach eine statische Methode erstellen, um all das für dich zu tun? Ich sehe keinen Vorteil darin, die Vererbung hier zu verwenden, da Sie kein Verhalten spezialisieren oder mehr Status hinzufügen. –

+0

Im Allgemeinen sollten Sie [Komposition über Vererbung] (https://en.wikipedia.org/wiki/Composition_over_inheritance) bevorzugen. – Steven

+1

@Steven Die Struktur der OP-Klassen deutet darauf hin, dass er die Komposition bereits der Vererbung vorzieht.Ich denke, seine Frage betrifft die Gültigkeit der Vererbung für * configure * composition, was meiner Meinung nach negative Auswirkungen hat. – dasblinkenlight

Antwort

1

Sie haben das genaue Problem mit dem Ansatz der Unterklasse-pro-Komposition identifiziert: Es ist verpflichtet, die Zeit zu kompilieren, wodurch die Zusammensetzung der Laufzeit viel schwieriger wird.

Darüber hinaus erfordert die hardcodierte Kompositionslogik im Unterklassenkonstruktor, dass Sie jedes Mal neu kompilieren müssen, wenn Sie die Logik ändern müssen, obwohl das Run-Time-Instanzdiagramm in Ihrem System nur geändert wird.

Sie können die Anforderung erfüllen Ihre Objekte zur Laufzeit zu komponieren, indem Sie eine Klasse hinzufügen, die sie Verbindungen ohne Erstellung beschreibt, und dann einen Konstruktor hinzu, dass die Beschreibungen nimmt, und verarbeitet sie zu einem kompletten Scene Objekt.

Um dies weniger abstrakt zu machen, denken Sie an eine Konfigurationsdatei in Ihrem bevorzugten lesbaren Format, z.

{"Systems":["ColisionSystem", "MovementSystem"], "SceneGraph":"MyCustomSceneGraph"} 

und eine Schnittstelle, die Sie auf diese Daten zugreifen kann:

interface SceneConfiguration { 
    IList<String> Systems {get;} 
    String SceneGraph {get;} 
    ... // More configuration items 
} 

nun einen Parser betrachten, die eine Instanz von SceneConfiguration aus dieser Darstellung erzeugt, und einen Konstruktor von Scene die SceneConfiguration als Argument:

Mit dieser Anordnung können Sie die Komposition über eine Konfigurationsdatei "softcodieren". Der Ansatz funktioniert auch gut mit Szeneneditoren: Ihr Szeneneditor erstellt Instanzen von SceneConfiguration, während Scene die Kontrolle über die Erstellung selbst behält.

Verwandte Themen