Entwurfsmuster gesucht



  • Hallo

    Suche ein Entwurfsmuster für meine Aufgabenstellung. Habe eigentlich eine einfache Klassenhierarchie. Zwei Basisklassen und davon mehrere abgeleitete Klassen.

    Nun haben diese abgeleitet Klassen eine Menge von Variablen. Diese Variablen können zu Gruppen zusammengefasst werden. Es gibt nun 2 Gruppen.

    hier mal ein beispiel in C++

    class CBase1{...};
    class CBase2{...};
    
    class CDerived1 : public CBase1{...};
    class CDerived2 : public CBase1{...};
    
    class CDerived3 : public CBase2{...};
    class CDerived4 : public CBase2{...};
    
    // ...und die Daten
    
    class CDataSet1
    {
        int m_var1;
        double m_var2;
        string m_var3;
    };
    
    class CDataSet2
    {
       int m_test[];
       bool  m_tested;
    };
    

    Nun kann eine abgeleitete Klasse (egal ob von CBase1 oder CBase2) ein CDataSet1 oder ein CDataSet2 besitzen.

    Nun wäre es ja möglich z.B. von CBase1 und CDataSet1 abzuleiten. Die Mehrfachvererbung wollte ich aber gerne verhindern.

    Gibt es ein Entwurfsmuster das hier passen könnte?


  • Mod

    Trifft die Aussage "Ein CDerivedX ist ein CDataSetX" zu?

    Falls ja, dann ist Mehrfachvererbung das richtige (nur keine Angst, geht genauso wie sonst auch).

    Falls aber die Aussage "Ein CDerivedX hat/besitzt/enthält ein CDataSetX" zutrifft, dann ist Vererbung das falsche. Dann benötigt CDerivedX ein CDataSetX als Klassenvariable.



  • y-vonne schrieb:

    Nun kann eine abgeleitete Klasse (egal ob von CBase1 oder CBase2) ein CDataSet1 oder ein CDataSet2 besitzen.

    Dann tu doch genau das: Verpass den Klassen ein Member vom Typ CDataSet1/2. Hier brauchst du keine Vererbung.



  • Ok. Ich glaube ich habe was wichtiges vergessen.

    Die Klasse CDataSet1 und CDataSet2 haben jeweils eine Methode Read() um die Variablenwerte einzulesen. Nun würde ich diese Methode einmal zentral aufrufen.
    Und das aus CBase1 oder CBase2.

    Dafür benötige ich eigentlich ein Entwurfsmuster.



  • Dann rufs doch einfach zentral auf 😕

    Ich versteh dein Problem ehrlich gesagt nicht. Entwurfsmuster sind nicht dafür da, sie auf Biegen und Brechen irgendwo anzuwenden.



  • Dann rufs doch einfach zentral auf

    Super Antwort. Wo rufe ich sie auf? In CBase. Die kennt ja die Member der abgeleiteten Klassen nicht.



  • class CBase1
    {
    public:
    	virtual void readMember() = 0;
    
    	void irgendneAufrufendeFunktion()
    	{
    		...
    		readMember();
    		...
    	}
    };
    
    class CDerived1 : public CBase1
    {
    public:
    	virtual void readMember()
    	{
    		foo.Read();
    	}
    
    private:
    	CDataSet1 foo;
    };
    


  • Hm. Ok.
    Dann muss ich aber in jeder abgeleiteten Klasse

    virtual void readMember()
    {
          foo.Read();
    }
    

    implementieren. Und genau das dachte ich kann ich durch ein Entwurfsmuster umgehen.

    Entwurfsmuster sind nicht dafür da, sie auf Biegen und Brechen irgendwo anzuwenden.

    Wenns auch ohne Entwurfsmuster geht auch recht.



  • Wenns denn in C++ ist könntest du mit Templates arbeiten:

    template <class DataSet>
    class Base1
    {
    protected: 
      DataSet dset; //Erben haben Zugriff
    public:
      void Read() { dset.Read(); }   
    };
    
    class Derived1 : public Base1<DataSet2>
    {
      /* ... */
    };
    

    Oder eine Ebene dazwischen einführen:

    class Base1
    {
    public: 
      virtual void Read() = 0;
    };
    
    template <class Dataset>
    class DataSetHolder1 : public Base1
    {
    protected: 
      DataSet dset; //Erben haben Zugriff
    public:
      virtual void Read() { dset.Read(); }   
    };
    
    class Derived1 : public DataSetHolder1<DataSet2>
    {
      /* ... */
    };
    


  • Das mit dem Template ist ein interessanter Ansatz. Vielen Dank.



  • Eine andere Möglichkeit wäre ja auch eine Basisklasse für die beiden Dataset Klassen.

    Und dann in Base1 und Base2 einen Zeiger auf diese Basisklasse und mit diesem Read aufrufen.

    In den Derived Klassen dann diesen Zeiger auf einen der Beiden bestimmten DataSet Klassen setzen.

    Oder?



  • Alter Schwede, mann kanns auch übertreiben.
    Schreib halt in jede abgeleitete Klasse die 3 Zeilen rein.
    Sich dafür extra zusätzliche Komplexität einhandeln zahlt sich genau gar nicht aus.



  • Alter Schwede, mann kanns auch übertreiben

    😃 Immer bestrebt das beste raus zu holen.
    Ok. Das sehe ich nun als Expertenrat und mache es genau so. Danke!


Log in to reply