2013-06-07 5 views
10

Ich habe eine C++ - Klasse, die die Ausrichtung eines Objekts im 3D-Raum beschreibt - Position, Drehung, Skalierung usw. Ich habe andere Klassen, die unbedingt Informationen wie diese (oder eine Teilmenge davon) benötigen - Modelle, Terrains, Kameras, usw. Nun kann ich diese Unterklassen meiner Orientierungsklasse machen, aber die Googles haben mir gesagt, dass ich Komposition über Vererbung bevorzuge. Das macht philosophisch Sinn - ein Modell ist keine Orientierung, es hat man (und ja ich weiß, das ist-a hat-eine Sache ist nur eine Heuristik). Dennoch scheint es unnötig, fast komisch unelegant, die gleichen Wrapper-Methoden für all diese Möchtegern-Unterklassen einfach auf diese Funktionalität zu bringen. Dinge wie model.getOrientation().set_x(1) scheinen albern zu sein.C++ - Zusammensetzung - muss ich all diese Funktionen einpacken?

Ich kann sehen, warum dies nicht "zu schlecht" für kleine Objekte wäre, aber für dieses Beispiel (und andere mögen es), was ist der Punkt der Zusammensetzung, wenn Sie sowieso durch Reifen gehen müssen, um so zu tun, dass Sie Vererbung verwenden? Soll ich es jetzt auch benutzen? Ich bin mir fast sicher, dass ich falsch darüber nachdenke.

+3

Was ist los mit 'model.orientation.set_x (1)'? – Lol4t0

+0

@ Lol4t0 Es scheint ausführlich. Und solltest du einem Objekt nicht sagen können, etwas zu tun, ohne es sozusagen zu zerlegen? Vielleicht würde eine ähnliche Entwurfsmusterinstanz helfen? – GraphicsMuncher

+0

Die Sache ist, dass das Setzen der Orientierung kein aussagekräftiges Objekt ist, was zu tun ist (wenn Objekt nicht Orientierung ist). Das! ist eigentlich ein Problem. Du solltest keine Orientierung für Objekte festlegen, stattdessen solltest du mit ihnen reden, wie 'Monster-> attack()' oder 'camera-> zoom()'. – Lol4t0

Antwort

6

Es mag albern erscheinen, aber Ihre model.getOrientation().set_x(1) ist wahrscheinlich der Weg zu gehen.

Wenn Sie den getOrientation() Teil des Tippens müde sind, könnten Sie so etwas wie dies versuchen:

Orientation & orient = model.getOrientation(); 
orient.set_x(1); 
orient.set_y(1); 
if(orient.check_something()) { 
    //whatever 
} 
//etc. 
+0

Ich lehne mich dazu. Andere Leute scheinen Ihrer Antwort zuzustimmen. Können Sie näher erläutern, warum dies der beste/bevorzugte Weg ist? – GraphicsMuncher

+0

1. Wenig oder kein Vorsatz 2. Behält richtige Beziehungen zwischen i-a/has-a bei. 3. Ist idiomatisch: wird andere Programmierer nicht verwirren – zindorsky

3

Schreiben Sie eine Klasse für Dinge, die eine Orientierung haben. Lassen Sie Modelle, Terrains, Kameras usw. von dieser Klasse erben. Wenn Sie ein Wrapping durchführen möchten, müssen Sie es nur in einer Klasse durchführen. Die Verwendung von Gettern wird durchgeführt, damit Sie die Art ändern können, in der die Ausrichtung im Objekt gespeichert wird.

+0

Wie ist das anders als nur die Orientierungsklasse zu erweitern? – GraphicsMuncher

+1

Es drückt die Ideen klarer aus. Wie Sie sagten, ist ein Modell keine Orientierung. – Oswald

+0

Ich mag diese Idee. Sie werden nicht mit allem verknüpft, was die 'orientation'-Klasse besitzt, indem Sie von ihr erben, Sie können alles, was Sie benötigen, von der' orientation'-Klasse einkapseln und dann diese eingekapselten Eigenschaften/Methoden wiederverwenden, indem Sie von dieser Zwischenklasse erben (vorausgesetzt, dass Modelle, Terrains, Kameras alle die gleiche Untermenge von Merkmalen von einem "Orientierungs" -Objekt verwenden. – Porkbutts

4

Es gibt eine billige Art und Weise ist der größte Teil der Verpackung vorformulierten zu vermeiden.

class model : private orientation { 
    public: 
    using orientation::set_x; 
    ... etc ... 
}; 

Private Vererbung in C++ bedeutet nicht (unbedingt) "ist ein". Es ist für Außenstehende mehr oder weniger unsichtbar und wird manchmal als "in Form von a umgesetzt" beschrieben. Das heißt, Sie erhalten eine eingeschränkte Form der Komposition, die Ihnen hilfreich dabei hilft, einen Teil oder die gesamte Oberfläche des zusammengesetzten Objekts freizulegen.