В ответ на ваш первый вопрос: « какой подход лучше »?
Я лично предпочел бы использовать шаблон Interface и Proxy (или Decorator) для реализации чего-то подобного.(См. Пункт 16: Композиция Favour по наследованию Effective Java (2nd Edition) )
Если суперкласс (RealSubject
) не находится под вашим контролем, т.е. в том же пакете,и специально разработанные и документированные для Extension любые изменения его реализации от версии к версии могут нарушить вашу реализацию подкласса (EnhancedSubject
).По сути, я говорю следующее: Прямая зависимость от конкретной реализации приводит к хрупкому коду.
В ответ на ваш второй вопрос: " Если EnhancedSubject
удовлетворяет принципу Лискова, Вы все еще рассматриваете Наследование?"
Еще раз безопасно использовать наследование, если RealSubject
и EnhancedSubject
находятся под вашим контролем и выпущены с тем же жизненным циклом, но Непосредственная зависимость от конкретной реализации приводит к хрупкому коду.
Еще один момент, который, как мы надеемся, побуждает вас к использованию реализации интерфейса, - это модульное тестирование.
Например, в том случае, если вы хотитеЕсли вы хотите применить модульное тестирование, было бы намного проще внедрить ложную зависимость RealSubject
в вашу Proxy
реализацию Subject
, чтобы вы могли специально протестировать класс Proxy
, вместо того, чтобы полностью тестироватьвся иерархия объектов, RealSubject
и EnhancedSubject
, просто для подтверждения того, что EnhancedSubject
ведет себя как ожидалось.
Полагаю, это можно сказатьтем не менее, если это очень простой API, и он вряд ли изменится в будущем, конкретные реализации будут просто на проще .And Keep It Simple Stupid (KISS) - одна из лучших политик.
" Можно ли по-прежнему применять шаблон Proxy, если нет интерфейса субъекта? " Вы можете добавить RealSubject
в другойКласс и использовать RealSubject
для внутреннего использования, но если API, использующий RealSubject
, напрямую зависит от конкретного класса, у вас нет другого выбора, кроме как использовать Inheritance.