Dicken Constructor auslagern + Vererbungsmöglichkeit erhalten?
-
Okay. Cool, danke, ich geh Mal der Reihe nach durch

hustbaer:
Das Wort natürlich scheint beim leeren ctor die Hauptrolle zu spielen, okay.Für mich besteht dann weiterhin hauptsächlich die Frage, was die Vorteile davon sind, den Loader auszulagern, wenn man nur ein erzeugtes Objekt (im Ggs. zu dem üblichen Anwendungsfall von Factoryfunktionen/klassen) hat. Mir fällt es schwer, da die Vorteile zu sehen, wenn man von schlankerem Header absieht, da es für einige Aspekte (z.B. Vererbung) ja doch praktisch ist, wenn das Objekt sich selbst erstellt.
Ich bin ja auf der Suche nach der besten Lösung, aber nicht sicher, wie ich diese finden kann.
Insgesamt habe ich den ctor jetzt glaube ich etwas besser verstanden. Ich glaube, ich muss einfach mehr in Objekten denken, keine Ahnung.
Und wenn ich mehrere Erzeuger habe? Die Abstract Factory läuft im klassischen Klassendesign ja auch nicht so gut mit Vererbung, oder? Was haltet ihr denn dann von der Implementierung:
class ModelDataLoader { public: void LoadModelData(Model* model, const string& str) = 0; }; class ModelDataLoader1 : public ModelDataLoader { public: void LoadModelData(Model * model, const string& str); }; class ModelDataLoader2 : public ModelDataLoader { public: void LoadModelData(Model* model, const string& str); }; class Model { private: // attributes // mit friend zu ModelDataLoader public: Model() {} }; class ViewedModel : public Model { private: // attributes und zusätzliche attribute public: ViewedModel() {} // zusätzliche setter für Attribute, die nur ViewedModel hat? (X) }; int main() { typedef boost::scoped_ptr<Model*> ModelPtr; typedef boost::scoped_ptr<ViewedModel*> ViewedModelPtr; ModelDataLoader l1; ModelDataLoader l2; ModelPtr model1(new Model); ModelViewedPtr model2(new ViewedModel); l1.LoadModelData(model1); l2.LoadModelData(model2); return 0; }Also Loader1/2 hat jetzt nix mit Model/ViewedModel zu tun. Nachteil dieser Methode hier ist, dass ein Model eigentlich im leeren Zustand eigentlich sinnfrei ist. Vorteil ist aber, dass ich vererben kann wie blöd.
- Was haltet ihr davon?
- Eigentlich ist ViewedModel ein Model, was betrachtet werden kann. Man könnte aber auch formulieren, ein ModelView ist ein Model, das mit Positionsdaten versehen ist, d.h. ich könnte das auch über Komposition statt Vererbung lösen. Was haltet ihr von so was?
Danke so weit!
-
- Eigentlich ist ViewedModel ein Model, was betrachtet werden kann. Man könnte aber auch formulieren, ein ModelView ist ein Model, das mit Positionsdaten versehen ist, d.h. ich könnte das auch über Komposition statt Vererbung lösen. Was haltet ihr von so was?
Ich würde weder das eine noch das andere machen.
Eher eine "ModelInstance" Klasse:
class ModelInstance { public: ModelInstance(shared_ptr<Model> const& model, Matrix4x4 const& position /* ... */); private: shared_ptr<Model> m_model; Matrix4x4 m_position; // evtl. weitere Daten für Vertex-Blending, ... };Also ein Verweis auf ein Model + Position wo es zu sehen sein soll.
-
Scheiße, ja! Das macht ja sowieso Sinn, weil die Anzeige eines Models zum Model selbst ja 1 : n ist. Das muss ich mir nochmal durch den Kopf gehen lassen, danke.

Und zu folgender Frage:
Für mich besteht dann weiterhin hauptsächlich die Frage, was die Vorteile davon sind, den Loader auszulagern, wenn man nur ein erzeugtes Objekt (im Ggs. zu dem üblichen Anwendungsfall von Factoryfunktionen/klassen) hat.
?
-
Eisflamme schrieb:
Für mich besteht dann weiterhin hauptsächlich die Frage, was die Vorteile davon sind, den Loader auszulagern, wenn man nur ein erzeugtes Objekt (im Ggs. zu dem üblichen Anwendungsfall von Factoryfunktionen/klassen) hat.
?
Naja... pfuh.
Kommt jetzt drauf an.
Wenn das Datenformat wie es im File steht quasi nur eine 1:1 Serialisierung von dem ist wie die Daten im Speicher liegen, dann ist der Sinn erstmal fraglich.
Was man immer heraustrennen sollte sind Dinge wie der "Formattierer" (bei Boost.Serialization übernehmen den Job IIRC die Archiv-Klassen), damit man z.B. wahlweise XML oder Binärdateien speichern/laden kann.Wenn das Datenformat im File nicht 1:1 dem enstpricht wie's im Speicher liegt, dann gehört das IMO in eine eigene Klasse. Die Model Klasse ist das Model, und kümmert sich um Model-Angelegenheiten. Dem Model kann es egal sein wie das .obj, .x, .fbx etc. File-Format aussieht.
Die Aufgabe des Loaders/Parsert/... ist es dann jeweils "sein" File-Format zu kennen. D.h. du hast einen XFileLoader, einen ObjFileLoder, einen FbxFileLoader etc.
Und selbst wenn du nur ein Dateiformat unterstützen willst/musst: das "dekodieren" eines bestimmten Formats hat IMO in der Daten-Klasse nichts verloren.
Denk einfach an das Beispiel Textur- oder Image-Klasse. Die Textur- oder Image-Klasse sollte sich IMO nicht darum kümmern müssen wie ein PNG, JPEG, BMP etc. zu lesen geht. Das macht je eine eigene Klasse pro File-Format.
-
Okay, das macht Sinn, vielen Dank.

Aber das wird bei mir jetzt wohl doch darauf hinauslaufen, dass ich allen meinen Loaderklassen einfach friend-Zugriff auf Model erlaube. Dafür muss Model natürlich auch die Header der Loaderklassen kennen. Damit kennt Model seine Erzeuger, ist das unerwünscht?
-
Vielleicht kannst du ja
friendauf eine kleine interne (nicht zum API gehörende) Zwischenklasse beschränken, um so eine Abstraktionsschicht zu haben.
-
Also da die Fremd-API ja nicht direkt in mein Format konvertiert, habe ich eh eine Vermittlerklasse, die halt trotzdem einer der möglichen ModelLoader ist. Zumindest wäre das Einführen von einer Zwischenklasse wohl nicht mehr als 1 : 1. Und auslagern aus Model würde das Model etwas sehr entschlacken, da wär dann halt auch nix mehr drin.
-
Eisflamme schrieb:
Und auslagern aus Model würde das Model etwas sehr entschlacken, da wär dann halt auch nix mehr drin.
Macht ja nix.
"Weil Klasse X dann fast leer wird" kann ja wohl kein Argument sein.
-
Hi,
Mein Problem ist heute: Ich habe einen dicken Constructor.
Tja da hast du wohl Pech gehabt.
Mein Konstruktor is viel c00l3eR als deiner.
-
Aber die Klasse kapselt dann nur noch 1:1 die neue Zwischenklasse und ist damit nicht mehr als ein Wrapper. Ich finde schon, das verschiebt die Zustaendigkeiten zu sehr, zumal ich fuer jedes kleine Rendern dann zig Getter auf die andere Klasse nutzen muss. Klar, das geht alles. Aber da ist mir der Mehrwert durch die Zwischenklasse nicht gross genug, fuerchte ich.