6

When applying the interface segregation, should you have separate interfaces for a straightforward setters and interfaces that perform an operation before setting? For example, say you have a class:

class FooClass:
     public GettableFoo,
     public SettableFoo
{
    virtual int getRelevantData();  
    // member of GettableFoo (which is used by roughly 20 clients)

    virtual void setToOtherFooTemplate(GettableFoo *other);
    // member of SettableFoo (which is used by roughly 20 clients, some of which also need GettableFoo interface)

    void setToSum(GettableFoo *a,GettableFoo *b);
    // requires SettableFoo functions to implement, used by 8 clients, some of which also need SettableFoo interface

    void combineSomeOtherWay(GettableFoo *a,GettableFoo *b);
    // requires SettableFoo functions to implement, used by 4 clients (possibly more in the future), some of which also need SettableFoo interface and/or which require the setToSum function

private:
  // complex data
}

The interface segregation principle states that no client should be forced to depend on methods it does not use. Does that mean that setToSum() and combineSomeOtherWay() should each have their own interfaces? The answer seems like it should be yes, but I don't think I've ever come across code with interfaces segregated that much.

If the answer to the above is yes, wouldn't that mean if combineSomeOtherWay() were just setToProduct() (multiply) and I used operator overloading for both to implement this in C++, that technically the operator overloading would be breaking the interface segregation principle given the client needs stated above? And if so, wouldn't most instances where operator overloading is used be breaking ISP, and if not, how is it any different from not segregating any of the interfaces in the above class?

  • If you have a situation, when you have to do segragation like this, it probably means you have too many responsibilities in your class. ISP goes very close with SRP. Don't do the overengineering, keep it simple. By the way, if you have amount of interfaces close to amount of classes, you probably doing something wrong. – Serge Kuharev Jun 21 '15 at 17:28
  • @SergeKuharev "it probably means you have too many responsibilities in your class". Isn't storing settable gettable data only a single responsibility? Some clients need to set the data like x=y, some x=y+z, and some doing something similar to x=y*z, and some of those clients using some combination of these for more complex operations. I think having a separate class who's sole purpose is to perform operations on this class seems even less less simple. Or am I misunderstanding? – knock Jun 21 '15 at 17:59
  • My experience has been that interfaces with only getters tend to be OK but interfaces with only setters are often suspicious; often I'm trying to do something in a very raw way when it should be further abstracted. However, the actual details are not here so at this point it's wild speculation... – J Trana Jun 22 '15 at 4:24
  • Violation of SRP is a valid class-level concern, but following ISP even such class could provide small, functionally-cohesive interfaces to it's clients, thus improving the design of the system at higher-level. – astreltsov Sep 4 '15 at 16:01
2

I'd suggest you come at the ISP from the perspective of client code.

In how many places is your class being used? Is there any client class that only needs one method but not the other? If all client code needs both, there really doesn't seem to be a case for two interfaces.

If you do have two different places where your class is being used, with each requiring one method but not the other, the Interface Segregation Principle says you should have an interface for each use case. Your class would then explicitly implement two interfaces.

Keep in mind that in the often-cited 'Xerox' story of the invention of the ISP, it was a first step in the decomposition of a God Object. Having two interfaces for your class is fine, but it's worth asking yourself if the class can sensibly be broken in half. As others have said, there is a close link between the ISP and SRP (Single Responsibility Principle) here.

2

I find it helpful to think of an interface as a role an object can play. So if a client depends on a single role to do it's job, it will only depend on one interface.

If a bunch of methods belongs to the same role, then it doesn't violate ISP to put them into one interface. For example, a set of mutually-exclusive overloads for doing the same thing in a slightly different way probably belongs to a single role.

Segregating interfaces is a good thing because it gives the clients the ability and encourages them to be designed in more modular way and couple to a narrower contract. And it doesn't really cause significant over-engineering or other overhead, unlike some other techniques/patterns from OOP.

You can always easily merge multiple interfaces back into one if it makes sense. Much harder is to split an interface after you already have a bunch of clients who now have too much responsibility and coupling because they were allowed to depend on a huge interface. This is why it's not always a good idea to rely on clients to tell you how to split an interface.

Summary:

  • model roles that make sense for your application

  • when in doubt, segregate more

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.