Here is a real world example of this principle (in PHP)
Problem:
I want various forms of content to have comments / discussions related to them. This content can be anything from a forum topic, from a news article to a user profile to a private conversation-style message.
Architecture
We will need a reusable DiscussionManager class that binds the Discussion to this content object. However, the four examples above (and many others) are conceptually different from each other. If we want the DiscussionManager use them, then all four + should have one common interface that they all share. There is no other way to use them to use the DiscussionManager if you do not want your arguments to be bare (for example, type checking is not).
Solution: A Discussable interface with these methods:
attachDiscussion($topic_id)detachDiscussion()getDiscussionID()
Then the DiscussionManager might look like this:
class DiscussionManager { public function addDiscussionToContent(Discussable $Content) { $Discussion = $this->DiscussionFactory->make( ...some data...); $Discussion->save() // Or $this->DiscussionRepository->save($Discussion); $Content->attachDiscussion($Discussion->getID()); // Maybe saves itself, or you can save through a repository } public function deleteDiscussion(Discussable $Content) { $id = $Content->getDiscussionID(); $Content->detatchDiscussion(); $this->DiscussionRepository->delete($id); } public function closeDiscussion($discussion_id) { ... } }
Thus, the DiscussionManager does not care about any unrelated behavior of the various types of content that it uses. He ONLY takes care of the behavior he needs, regardless of what these behaviors are associated with. Thus, by providing each type of content that you want to discuss with the Discussable interface, you are using the principle of interface segregation.
This is also a good example of a situation where an abstract base class is not a good idea. The forum topic, user profile, and news article are not even conceptually the same thing, so trying to force them to inherit the behavior associated with the discussion leads to a strange connection with the unrelated parent. Using the specific interface that represents the discussions, you can verify that the objects you want to discuss are compatible with the client code that will manage these discussions.
This example can also be a good candidate for using Traits in PHP, for what it's worth.
AgmLauncher Mar 18 '14 at 16:43 2014-03-18 16:43
source share