#java #ооп #solid
Пример с дополнением интерфейса: class Playback { private Media current; public void play(Media media) { current.stop(); current = media; current.play(); } public void next() { Media media // получение следующей по какому либо алгоритму play(media); } public void prev() { Media media // получение предыдущей по какому либо алгоритму play(media); } } Пример с добавлением классов операций: class Playback { private Media current; public Media current() { return current; } public void play(Media media) { current.stop(); current = media; current.play(); } } abstract class PlayOperation { private Playback playback; public void execute() { Media media = provide(); playback.play(media); } protected abstract Media provide(); } class NextOperation extends PlayOperation { public Media provide() { Media media // получение следующей по какому либо алгоритму return media; } } class PrevOperation extends PlayOperation { public Media provide() { Media media // получение предыдущей по какому либо алгоритму return media; } } class RandomOperation extends PlayOperation { private Random random; public Media provide() { Media media // получение рандомной return media; } } Пример с новыми классами выглядит привлекательнее, а стоит ли оно того?
Ответы
Ответ 1
Пример с добавлением классов операций То что вы описали в примере, это почти шаблон проектирования "Посетитель" . NextOperation , PrevOperation , RandomOperation - посетители класса Playback . В данном случае этот шаблон вряд ли обоснован, так как он призван добавлять поведение иерархии классов, и он действительно при работе с иерархией играет на OCP (т.к. необходимость добавления поведения в дерево наследников с помощью добавления метода в базовый класс как-раз нарушит OCP). У вас же класс один Playback - OCP не будет нарушено в первом случае - Playback открыт для расширения наследованием (если конечно поменять private на protected), и закрыт для изменения (это значит, что переписывать его вам не требуется для доработки поведения в наследниках). Нельзя не увидеть минус второго подхода - вы серьёзно усложняете систему, размазывая простую логику на множество классов ( это Anti-SRP ). Поэтому я бы посоветовал оставить первый вариант, как минимум, когда система простая - так усложнять её нельзя, YAGNI против. Но если Playback становится базовым классом иерархии - использование посетителей будет уже обосновано, и следует добавить метод visit(PlayOperation operation), при чём возможность посещения Playback - не значит что метод next(), например, обязательно должен быть вынесен в класс-посетитель: в посетителей лучше выносить дополнительные операции, а основные - оставлять внутри класса.
Комментариев нет:
Отправить комментарий