The "code to interfaces" is not an official pattern, but it is an advice that I have seen in many books. I have a specific situation where I wonder if the "code to interface" can still be used.
I have 3 interfaces implemented by 3 classes. These interfaces are very similar, meaning some methods are shared in all interfaces, some methods have a small difference (e.g. in one argument) and some are only in one interface and not in the others.
My question is, what is the best way, if any, to keep the "code to interface" philosophy and reduce the number of interfaces.
If it is not possible, how will you proceed so that there is as less as possible code duplication? For example with asbstract classes?
Following the Interface Segregation Principle I would suggest backing up from the "interface per class" view. An interface is not a front to a class, rather it should represents a set of responsibilities that any class can fulfill by implementing the interface. Re-analysis you interfaces and redesign them to reflect separte responsibilities. You could end of with four or five interfaces with each class implementing one or more of the interfaces. For example, consider that a Corporation class could implement an ICustomer interface, an ICreditor interface, an IEmployer interface, an IStockHolder interface, etc. Reducing the number of interfaces should not be a major concern, focus on having the number of interfaces that is correct for your situation.
Joined: Jan 25, 2011
Thank you very much for the reply.
I think I understand what you mean, even though I am not aware of the Interface Segregation Principle (I will look into it).
Still, I am wondering, what is a good way to get rid of these duplicate methods? Perhaps with a parent interface containing them and children interfaces for the rest of the methods that are not common?
This will mean that will end up with four interfaces. Maybe it is not a major concern to reduce the number of interfaces, but it seems to me very counter-intuitive that I have to add another interface to reduce duplication. Maybe it is the only way, I am just wondering if there is something more elegant.
"Code duplication" indicates that you might be looking to eliminate duplicate code from concrete classes.
You should be able to eliminate "duplicate code" by using inheritance mechanisms with your concrete classes. This should help you eliminate "duplicate" method implementations.
Interface class design is different. You should be able to design an appropriate interface heirarchy using inheritenance mechanisms with your interface classes. This should help you eliminate "duplicate" method signatures when appropriate for the set of requirements.
Keep in mind that the concrete classes are implementing whatever you specify in the interface class. It is not the other way around.
You don't try to "reduce the number of interfaces." The interface class design should be based on the application's requirements. You try to create a design that is appropriate for the requirements.
Keep in mind that your interface class design and concrete class design are strongly related but are different Class design areas.
Joined: Jan 25, 2011
I think that this has become quite generic to understand (for me), so let me try to be a little bit more specific.
Let's say I have 2 different kind of data grids let's call them DefaultEventGrid and DefaultJobGrid. I have 2 separate service classes which implement business methods. These classes each implement a different interface.
For example the EventGrid interface defines a getTotalRecords() method.The JobGrid interface also defines a getTotalRecords() method.
But the business logic is quite different in the implementation, so we are not really talking about code duplication.
Also the EventGrid might have a unique method called getEventSpecificData() (I m improvising here) which is not in the JobGrid interface.
Lastly, there might also be a getNewRecords(arg 1, arg 2) method in the EventGrid, but in the JobGrid interface there is a third argument that must be passed. getNewRecords(arg 1, arg 2, arg 3).
In this situation, would you say that my design is completely wrong? If so, what is the best way to design this?
If my design is not completely off, the only think I thought of( with my little experience) is to create a parent interface e.g. GenericGrid which will define the shared methods. And then the EventGrid and JobGrid will extend this parent interface and define non-shared methods.
Is this the right way to go? If so, my personal opinion is that it is counter-intuitive that the number of interfaces has grown by 1 (3 instead of 2). But if I understand you do not seem to agree with this.