Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Classes design with virtual methods

Tags:

c++

oop

How would someone solve such a problem with classes and type as least as possible code? Here is what I have

Base interface for everything

    class IWindow
    {
    public: 
        virtual void Refresh() = 0;
// another 100 virtual methods
// ...
    };

This interface is used inside a library that has no idea about the concrete implementation.

Here is a version of the concrete implementation

    class ConcreteWindow : public IWindow
    {
    public:
        void Refresh() override {}
/// the other 100 overridden methods 
    };

Now we have another interface that adds some additional methods and also used inside that library.

class IDBDetail : public IWindow
{
public:
    virtual void DoDetail() = 0;

};

and here is the main problem, when we create the concrete inmplementation for it

class IGDBDetailWrapper : public IDBDetail, public ConcreteWindow
{
public :
    void DoDetail() {}
};

of course the concrete class IGDBDetailWrapper is abstract as well because it doesn't implement those 100 methods, but I don't wanna do that, I'd like just to reuse the implementation from ConcreteWindow, they are all working with the same window handle but this won't compile of course.

I can copy/paste those 100 methods from ConcreteWindow into IGDBDetailWrapper, but that's an overkill, cause I might have another 10 such new interfaces and concrete implementations.

What other pattern can I use here that would help solve the question and not re-implement those 100 methods again and again?

Thx

like image 810
Eugen Avatar asked Dec 06 '22 18:12

Eugen


2 Answers

Your design is running into diamond problem.

Now we have another interface that adds some additional methods and also used inside that library.

 class IDBDetail : public IWindow { 
  public:
     virtual void DoDetail() = 0;

};

From the description of your IDBDetail interface looks like IDBDetail should not inherit from IWindow. If its just about adding additional functionality then IDBDetail need not be a IWindow. It just needs to understand the IWindow. For example in order to make a monkey do a special things, a trainer need not be a monkey.

Decorator pattern may be what you are looking for.

like image 69
bashrc Avatar answered Jan 07 '23 15:01

bashrc


First, if you are using Visual Studio there are refactoring tools that can help you with that automating what could be otherwise a tedious task, second:

To me is much pointless doing the same:

class IDBDetail : public IWindow
{
public:
    virtual void DoDetail() = 0;

};

I would do that instead

class IDBDetail
{
public:
    virtual void DoDetail() = 0;

};

Interfaces should be used to abstract away responsibilities, so cluttering a Interface with already hundreds of methods with additional methods is a symptom of bad design.

However you could leverage composition one time for all, so you create one time a class that resolve the problem for your, and you can later reuse that

class IDBDetailWithConcreteWindow: public IDBDetail{

    IWindow * concreteWindow;
public:
    IDBDetailWithConcreteWindow(IWindow * window){
        concreteWindow = window;
    }

    void Refresh() override{
        concreteWindow->Refresh();
    }
}

And finally in any derived class you have just to implement methods from IDBDetail

IGDBDetailWrapper: public IDBDetailWithConcreteWindow{
public:

   void DoDetail() override { }
}

The advantage with this solution is that if you have external constraints (like a bad designed pre-existing code base) you can still use it, while the upper solution will not work if you cannot change the IDBDetail interface.

like image 23
CoffeDeveloper Avatar answered Jan 07 '23 15:01

CoffeDeveloper