user888270
user888270

Reputation: 631

how to achieve interface segregation with polymorphic behavior c++

Suppose you have two functions fun1 and fun2. there are two classes der1 and der2. Both der1 and der2 implement fun1, but only der2 implements fun2. But i need to have polymorphic behavior with a base pointer to both der1 and der2. Does it make sense to have both these function in a base class (Abstract) even though only der2 will use both?

der1 and der2 are related and I think der2 should contain der1. But even then the base class will need to declare both fun1 and fun2. How do I achieve ISP? Does below code looks fine or is there a way to restructure it in a better way?

class base // Abstract
{
public:
virtual void fun1() {//default implementation}    
void fun2(){ // used by only der2}
};

class der1 : public base
{
//this also have fun2 as its defined in base.
}

class der2 : public base
{
// should implement fun1 and fun2 both 
public:
void fun2() { //implements fun2.}
}

Upvotes: 3

Views: 411

Answers (2)

Oktalist
Oktalist

Reputation: 14714

No, it doesn't make sense to have both functions in one base class, if there is a derived class which doesn't implement both functions. That would fail the Liskov Substitution Principle.

I suggest a hierarchy of interfaces:

struct base1
{
    virtual void fun1();
};

struct base2 : public base1
{
    virtual void fun2();
};

class der1 : public base1
{
public:
    virtual void fun1() override;
};

class der2 : public base2
{
public:
    virtual void fun1() override;
    virtual void fun2() override;
};

A base1* can point to either a der1 or a der2, and therefore only has fun1.

A base2* has both fun1 and fun2, and therefore can only point to a der2.

Upvotes: 1

Яois
Яois

Reputation: 3858

The Interface Segregation Principle addresses the problem of client functions or classes using only a subset of all the methods in an interface they depend on. For example, imagine the following case:

enter image description here

In this case, both "Client" classes depend on the whole "BigInterface" API while they only really need a subset of methods. The simplest solution in a case like this is to "split" the big interface and create cohesive ones, e.g. :

enter image description here

In your particular case, it depends on who uses der1, der2 and base. It is hard to know if your code looks fine without more context information, but assuming that your client classes depend on base even though they only need either fun1 or fun2, you should apply a similar recipe as in the example and split your interface in two.

Hope that it helps :)

Upvotes: 1

Related Questions