Вот реальный пример этого принципа (в PHP)
Постановка задачи:
Я хочу, чтобы различные формы контента имели комментарии / обсуждения, связанные сих.Это может быть что угодно: от темы на форуме, до новостной статьи, от профиля пользователя до личного сообщения в стиле разговора.
Архитектура
Нам понадобитсяповторно используемый класс DiscussionManager
, который присоединяет Discussion
к данному объекту содержимого.Тем не менее, приведенные выше четыре примера (и многие другие) концептуально различны.Если мы хотим, чтобы DiscussionManager
использовал их, то у всех четырех + должен быть один общий интерфейс, которым они все пользуются.У DiscussionManager
нет другого способа использовать их, если вы не хотите, чтобы ваши аргументы были обнажены (например, без проверки типов).
Решение: Discussable
взаимодействует с этими методами:
attachDiscussion($topic_id)
detachDiscussion()
getDiscussionID()
Тогда DiscussionManager
может выглядеть так:
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) { ... }
}
Таким образом, DiscussionManager
не заботится ни о каком несвязанном поведении различных типов контента, которые он использует.Он заботится только о поведении, в котором нуждается, независимо от того, с чем связано это поведение.Таким образом, предоставляя каждому типу контента, для которого вы хотите обсудить, интерфейс Discussable
, вы используете принцип разделения интерфейса.
Это также хороший пример ситуации, когда абстрактный базовый класс не являетсяхорошая идея.Тема форума, профиль пользователя и новостная статья не являются даже концептуально отдаленными, поэтому попытка заставить их наследовать поведение при обсуждении приводит к странной связи с неродственным родителем.Используя определенный интерфейс, представляющий обсуждения, вы можете убедиться, что объекты, которые вы хотите обсуждать, совместимы с клиентским кодом, который будет управлять этими обсуждениями.
Этот пример также может быть хорошим кандидатом на использование черт в PHP, хотя и стоит.