may already exist as a pattern under a different name. If so, it is just a case of IndependentDiscovery?
. Feel free to purge this page from the Wiki.
Often, the interface you want to use for a class will depend on the context it is being used in within your system. The idea here is that the class is going to provide different contracts to different parts of the system based on what it is that they need. Some categories where it would be appropriate follow:
- The ImmutableInterface hides methods of a class that could allow it to be modified in situations where you know it shouldn't be modified.
- The APIs required for a class to be effectively unit tested may be more extensive than those you wish to publish to the rest of the system.
- The interface required by a Configurator that configures your object may open up methods that you don't want available in any other context.
- The implementation of an EJB will often have many more public methods than are exposed through the deployment descriptor.
- Web services expose a coarse-grained interface, whereas the interface is much more fine-grained when interacting with other supporting classes.
- You will often wrap general methods of a base class with more semantically-specific and/or parameter-specific methods within a subclass.
An example of the last category is the java.util.Properties class, which is a subclass of java.util.Hashtable. It has getProperty() and setProperty() which work with Strings, but because it is a subclass of Hashtable it exposes get() and put(), which work with objects. To ensure consistency and to keep the public API to a decent size, it makes sense to hide the get() and put() methods by providing the Properties class through an Interface that doesn't provide those methods.
From the point of view of using a class externally, this pattern is the reverse of the DecoratorPattern
. Instead of extending the contract with the outside world by wrapping old functionaility in a class that adds new, you are creating a limited contract for certain clients that hides some of the functionality of a class behind an interface.
A common hack to try to implement the RolePattern
without using a separate interface is to hide selected methods by making them protected or otherwise playing with the scope. In C++, for example, you might declare the Configurator as a friend. In Java, you might make the Unit Test a member of the same package and make the unit-test-specific methods package protected. But this mechanism is extremely limited, and loses the information concerning the different contracts you want to offer to different parts of the system.
Of course, there is nothing new under the sun. I have found a reference to a "principle" which is very similar to this pattern -- The InterfaceSegregationPrinciple