Interface Segregation Principle- Program to an interface

前端 未结 6 665
无人及你
无人及你 2020-12-01 01:05

I was reading about SOLID and other design principles. I thought ISP was the same as \"Program to an interface, not an implementation\". But it looks like these are differen

6条回答
  •  一整个雨季
    2020-12-01 01:39

    Here's a real-world example of this principle (in PHP)

    Problem Statement:

    I want various forms of content to have comments/discussion associated with them. That content might be anything from a forum topic, to a news article, to a user's profile, to a conversation-style private message.

    Architecture

    We will want a re-usable DiscussionManager class which attaches a Discussion to a given content entity. However, the above four examples (and many more) are all conceptually different. If we want the DiscussionManager to use them, then all four+ need to have one common interface that they all share. There is no other way for DiscussionManager to use them unless you want to your arguments to go naked (e.g. no type checking).

    Solution: Discussable interface with these methods:

    • attachDiscussion($topic_id)
    • detachDiscussion()
    • getDiscussionID()

    Then 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) { ... }
    }
    

    This way, DiscussionManager does not care about any of the unrelated behaviors of the various content types that it uses. It ONLY cares about the behaviors it needs, regardless of what those behaviors are associated with. So by giving each content type that you want to have discussions for, a Discussable interface, you are using the interface segregation principle.

    This is also a good example of a situation where an abstract base class is not a good idea. A forum topic, user profile, and news article aren't even remotely conceptually the same thing, thus trying to get them to inherit the discussion behaviors leads to strange coupling to an unrelated parent. Using a specific interface that represents discussions, you can makes sure that the entities you want to have discussions, are compatible with the client code that will be managing those discussions.

    This example might also be a good candidate for usage of Traits in PHP, for what it's worth.

提交回复
热议问题