Fragen zu Klassendesign
-
Das ganze Design sieht für mich ziemlich verquer aus. Kannst du mal beschreiben was diese Simulation macht?
-
ehrlich schrieb:
Das ganze Design sieht für mich ziemlich verquer aus. Kannst du mal beschreiben was diese Simulation macht?
Laser Dynamics simulieren. Aber das ist für die Fragestellung vollkommen unerheblich. Natürlich könnte ich auch alles in eine einzige Datei packen. Aber ich möchte das ganze erst abstrahieren und danach zu einer Klasse mit nur den benötigten Elementen wieder zusammenfassen.
-
pospiech schrieb:
ehrlich schrieb:
Das ganze Design sieht für mich ziemlich verquer aus. Kannst du mal beschreiben was diese Simulation macht?
Laser Dynamics simulieren. Aber das ist für die Fragestellung vollkommen unerheblich.
Ja, so allgemein schon. Ich hätte eigentlich wissen wollen was die A B C D Klassen machen. Wenns um verschiedenen Aktionen geht, könntest du dir mal das Command Pattern anschauen.
-
A B usw wären in dem Fall sowas wie 'Kristall', 'Pumpe', 'Resonator' usw. Alles Komponenten die nicht direkt miteinander zu tun haben. Und in 'Basis' sind alle Variablen und Funktionen enthalten die alle Klassen benötigen, z.B. die Zeitschrittweite der Simulation.
Alles was ich zu Command Pattern finden konnte sah mir nach simpler Multiple Inherence aus (z.B. http://en.wikipedia.org/wiki/Command_pattern). Aber das geht an meinem Problem ja vorbei.
-
Und warum ist eine Simulation ein Kristall, Pumpe oder Resonator? Warum nicht einfach eine Liste von allen benötigten Komponenten halten? Was machst du denn, wenn du für eine Simulation 2 Pumpen brauchst? 2 mal erben?
-
ehrlich schrieb:
Und warum ist eine Simulation ein Kristall, Pumpe oder Resonator? Warum nicht einfach eine Liste von allen benötigten Komponenten halten? Was machst du denn, wenn du für eine Simulation 2 Pumpen brauchst? 2 mal erben?
Stimmt das ist ein Fehler im Design.
Ich könnte genauso auch die Elemente statt zu erben als Objekte in der Klasse haben. Trotzdem müssten alle die Daten aus 'Basis' kennen. Die virtuelle Vererbung würde ich dann beibehalten. Nur die multiple Vererbung nach Simulation würde wegfallen.EDIT:
geht das überhaupt?class ModeLockedLaser : public QThread, virtual public LaserdynamicBasics { ... protected: Absorber absorber; Lasermedium lasermedium; PumpLaser pump; Resonator resonator; ...ModeLockedLaser::ModeLockedLaser( QObject* parent /*= 0*/ ) : QThread(parent), LaserdynamicBasics() { }class Absorber : virtual public LaserdynamicBasics {class LaserdynamicBasics { public: LaserdynamicBasics(); virtual ~LaserdynamicBasics(); protected: double m_T; // Time double m_dt; // Time Resolution int N; // Points of Caluclation (Size of Array) ...Die Variablen
ModeLockedLaser::absorber.N
ModeLockedLaser::Nsollen dabei identisch sein. Funktioniert das damit?
-
Du musst das nicht mit mehrfach und virtueller Vererbung machen. Wenn du Dinge gruppieren willst kannst du das z.B. auch mit dem Composite Pattern oder ähnlichem machen.
-
Du deckst deinen Designfehler doch bereits selbst auf! Du schreibst die Komponenten sollen die "Basis" kennen. Das ist definitiv keine Ist-Ein- oder Verhält-Sich-Wie-Beziehung. Eine Kennt-Beziehung implmentiert man mit einem Verweis auf das entsprechende Objekt (Zeiger, falls es variabel sein soll; Referenz, wenn eine Komponente während der gesamten Laufzeit mit einer "Basis" verbunden ist.).
Gruß
Don06
-
Don06 schrieb:
Du deckst deinen Designfehler doch bereits selbst auf! Du schreibst die Komponenten sollen die "Basis" kennen. Das ist definitiv keine Ist-Ein- oder Verhält-Sich-Wie-Beziehung. Eine Kennt-Beziehung implmentiert man mit einem Verweis auf das entsprechende Objekt (Zeiger, falls es variabel sein soll; Referenz, wenn eine Komponente während der gesamten Laufzeit mit einer "Basis" verbunden ist.).
Vielleicht möchte ich ja doch ein IST-Ein? Denn ich möchte ja das
ModeLockedLaser::absorber.N
ModeLockedLaser::Nidentische Werte haben (was für alle Werte von LaserdynamicBasics gilt).
Wenn ich dannModeLockedLaser::initSimulation() { setSize(1024*4); // set N }aufrufe, rechnet
ModeLockedLaser::absorber.calc()ebenfalls mit demselben N.
Natürlich könnte ich auch ein Objekt 'Common' in ModeLockedLaser haben und den Zeiger darauf an die Konstruktoren von absorber usw. weiterreichen. Aber dann müsste ich ja überall Common.N schreiben. Das wird gruselig im eigentlichen Alorithmencode, und zeigt eher das die abstrakte Aufsplittung Nachteile gebracht hat. Ich würde aber gerne zeigen das es Vorteile bringt.
-
Aber dann müsste ich ja überall Common.N schreiben. Das wird gruselig im eigentlichen Alorithmencode, und zeigt eher das die abstrakte Aufsplittung Nachteile gebracht hat.
Du setzt "Vorteil" gleich mit "muss ich weniger tippen" bzw. "kann man leichter (schneller) lesen". Das ist manchmal nicht ganz falsch, aber wenn die Struktur bzw. Wartbarkeit des Programms darunter leidet ist es IMO eben doch falsch.
Wenn der Simulations-Code so "gross" ist dass das ersetzen von "N" durch "simulationParameters->N" so schlimm wäre, dann kannst du ja "N" in den entsprechenden Funktionen als lokale Variable definieren:
void blah::foo() { int const N = m_simulationParameters->N; ... }Das geht natürlich nur wenn "m_simulationParameters->N" von foo() nicht verändert wird (direkt oder indirekt). Theoretisch könntest du, falls N doch verändert werden muss, statt "int const N" immer noch "int& N = ..." schreiben, allerdings würde ich das nicht machen. Dann lieber einfach überall "m_simulationParameters->N" schreiben, dann sieht man wenigstens was passiert.
Hier mit Vererbung um sich zu werfen halte ich auf jeden Fall auch für keine gute Idee. Abgesehen davon dass die "EDIT: geht das überhaupt?" Variante eben nicht geht - virtuelle Vererbung greift nur innerhalb der Vererbung-Hierarchie, nicht zwischen Basisklassen und Membern (es wäre für so ziemlich alle Fälle ausser dem den du hier hast auch katastrophal wenn es anders wäre).
Vielleicht möchte ich ja doch ein IST-Ein? Denn ich möchte ja das
ModeLockedLaser::absorber.N
ModeLockedLaser::Nidentische Werte haben (was für alle Werte von LaserdynamicBasics gilt).
Ich denke du verstehst Vererbung und die "ist ein" Beziehung etwas falsch. Aber naja.