Reputation: 2990
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
Upvotes: 4
Views: 136
Reputation: 394
@bashrc is right, but it should be possible to solve the problem with virtual inheritance:
class ConcreteWindow : public virtual IWindow {...}
class IDBDetail : public virtual IWindow {...}
This Wikipedia article on virtual inheritance states the solution as well.
Upvotes: 3
Reputation: 2982
You can use virtual inheritance. If we ignore fact should IDBDetail
inherit from IWindow
or not, we could use virtual inheritance to solve problem with current architecture:
class IWindow
{
public:
virtual void Refresh() = 0;
// another 100 virtual methods
// ...
};
class ConcreteWindow : virtual public IWindow
{
public:
void Refresh() override {}
/// the other 100 overridden methods
};
class IDBDetail : virtual public IWindow
{
public:
virtual void DoDetail() = 0;
};
class IGDBDetailWrapper : public IDBDetail, public ConcreteWindow
{
public :
void DoDetail() {}
};
Now compiler will use implementation for your 101 abstract method from ConcreteWindow
Upvotes: 2
Reputation: 1357
It will not solve your problem, but at least you can redirect execution yourself:
class IGDBDetailWrapper : public IDBDetail, public ConcreteWindow
{
public:
virtual void DoDetail() override { /*work here*/ }
virtual void Refresh() override { ConcreteWindow::Refresh(); }
//another 100 methods
};
You can make the block of such redirections as a compiler #DEFINE
and repeat it as many times as you want.
Upvotes: 2
Reputation: 8315
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.
Upvotes: 3
Reputation: 241
You have to override all the methods in abstract class, there is no other way. Actually you shouldn't create an abstract class of 100 methods here and that's it. Perhaps You can divide it in some smaller abstract classes? However, in this case IDBDetail should not inherit after IWindow and IGBDDetailWrapper also shouldn't inherit after IWindow - and we are here.
Upvotes: 2
Reputation: 4835
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.
Upvotes: 3