DbWrapper Design Problem



  • Hallo,

    ich bastel gerade an einem kleinen Framework zur Datenbankkonvertierung. Jetzt habe ich ein Problem. Es giebt folgende triviale Klassen:

    ]class DbReader//reading from DB
    {//some pure virtual funcs};
    
    class DbWriter//Writing To Db
    {//some pure virtual funcs};
    
    struct IDbObserver
    {
       DbReader* GotNewEntry(void) = 0;
    };
    
    //Wrapper araound a Reader, to wrap specific Readers
    template<class TDbReadWrapper>
    class DbObserver : public DbReadWrapper, public IDbObserver
    {
    	public:
    		DbObserver( const char* pstrObserverName )
    		{
    		   m_pDbWrapper = new TDbReadWrapper();
    		}
    		virtual ~DbObserver()
    		{
    			delete m_pDbWrapper;
    		};
                       //These funcs are inherited from the Reader and overridden
    		virtual int OpenDb( char* pstrFileName, int* piDataSets = NULL ){ return m_pDbWrapper->OpenDb( pstrFileName, piDataSets  ); }
    		virtual void CloseDb(void){ m_pDbWrapper->CloseDb(); }
    		virtual int GetNextSession( PatData& theData ){ return m_pDbWrapper->GetNextSession( theData ); }
    		virtual int CopyImage( const char* pstrSrcImage, const char* pstrDestImage ){ return m_pDbWrapper->CopyImage( pstrSrcImage, pstrDestImage ); }//copies a specified Src Image to the specfified Dest - Image	protected:
    		void WriteRecentEntry(void);//write the recent entry to a file
    		void LoadRecentEntry(void);//read the recent entry from a file
    		std::string m_strRecentEntry;
    		TDbReadWrapper* m_pDbWrapper;
    };
    

    Hoffe ich schaffe jetzt das vernünftig zu erkären: Da ich ja spezielle DbReader habe (abgeleitet vonDbReader), und ich von denen dann die entsprechenden Observer bilden will, habe ich keine andere Möglichkeit gefunden als diesen Wrapper zu schreiben, da ein Observer ja Die Schnittstellen eines Readers haben soll und die eines IDbObserver. Ich könnte natürlich auch einfach dem Reader die Funktion GotNewEntry(void) verpassen und die giebt halt immer NULL zurück, aber solchen unschönene Balast wollte ich gerne vermeiden.

    Falls mir da nichts besseres einfält, führt das geradewegs zum nächsten Problem: Die einzelnen Observer werden dann in Kontainern verwaltet:

    class DbReadContainer : public DbWrapperContainer<DbObserver<DbReadWrapper>*>, public IDbObserver
    {
    public:
    	virtual DbReadWrapper* GotNewEntry(void);
    	virtual void push_back( DbObserver<DbReadWrapper>* pWrapper )
    	{
    		m_vDbWrappers.push_back( pWrapper );
    	}
    };
    

    leider funktioniert dann folgendes nicht:

    class VisupacDbWrapper : public DbReadWrapper{....}//The wrapper
    class VisupacDbObserver : public DbObserver<VisupacDbWrapper>{....}//And its observer
    DbReadContainer aReader;
    aReader.push_back( new VisupacDbObserver() );
    

    es kommt nur, das er 'VisupacDbObserver ' nicht in 'DbObserver<TDbReadWrapper>' konvertieren kann, obwohl doch VisupacDbObserver ein DbObserver<DbReadWrapper> ist. Ich hoffe, ich habe den Code nicht zu sehr zusammengekürzt, so das das Chaos noch nachzuvollziehen ist.

    Zugegeben : Der Aufwand, nur um eine Memberfunktion, die man nicht implementiert zu sparen ist wohl kaum gerechtfertigt, aber ab und zukommt eben doch der Spieltrieb durch :).

    Danke an alle, die meinen wirren Gedanken noch folgen 😃



  • mhh, es hilft odt schon das problem beim Schreiben einer Frage mal auf den Punkt zu bringen.
    Fazit: es ist nicht verkehrt, einfach eine Abstraktionsebene einzuschieben, um eine Schnittstelle noch mal seperat zu spezifizieren:

    class IDbReadObserver : public DbReadWrapper, public IDbObserver
    {};//nothing to implement,just a plain interface
    

    damit wird:

    template<class TDbReadWrapper>
    class DbObserver : public DbReadWrapper, public IDbObserver
    {....}
    

    zu

    template<class TDbReadWrapper>
    class DbObserver : public IDbReadObserver{}
    

    und

    class DbReadContainer : public DbWrapperContainer<DbObserver<DbReadWrapper>*>, public IDbObserver{}
    

    zu

    class DbReadContainer : public DbWrapperContainer<IDbReadObserver*>, public IDbObserver{}
    

    auch wenn ich nich verstehe, warum die alte Variante so nicht funktioniert hat. Oder giebt es prinzipielle Probleme, wenn mann templates so verschachtelt instanziiert und als Parameter übergiebt?


Anmelden zum Antworten