Я провел некоторое исследование шаблона декоратора, и есть небольшая путаница с пониманием одной из его проблем. Я продолжаю читать, что «декораторы обычно прозрачны для клиента компонента, то есть, если клиент не полагается на конкретный тип компонента». Я не уверен, что это означает - например, если у нас есть класс Beverage и подкласс Coffee, означает ли это, что клиент полагается на Coffee, и поэтому, если бы он был украшен, были бы некоторые проблемы?
Путаница с шаблоном декоратора?
Ответы (2)
Да, точно. Если вы полагаетесь на реализации, а не на абстракции (абстрактные классы или интерфейсы), это будет серьезной проблемой для кого-то/вас, кто хочет добавить декоратор между ними.
Ознакомьтесь с принципом инверсии зависимостей в Solid Principles.
Это общее правило в своей основе:
следует «зависеть от абстракций. Не полагайтесь на конкреции».
Рассмотрим код:
public class StarbuzzCoffee {
public static void main(String args[]) {
Beverage beverage = new DarkRoast();
beverage = new Mocha(beverage);
beverage = new Coffee (beverage);
beverage = new Whip(beverage);
System.out.println(beverage.getDescription()
+ “ $” + beverage.cost());
...
}
}
Здесь Mocha
, Whip
и Coffee
— конкретные классы, а Beverage
— абстрактный тип. Теперь ваше украшение в порядке, потому что клиент в конечном итоге зависит от Beverage
(абстрактный тип).
Теперь рассмотрим клиент, имеющий такой код:
if (beverage instanceof Mocha) {
<do_something>
}
else if (beverage instanceof Coffee ) {
<do_something>
}
Здесь у вас есть проблема, потому что у клиента есть определенное поведение для разных конкретных типов.
Поскольку мы хотим зависеть от абстракции, а не от конкретного типа, мы используем концепцию внедрения зависимостей (код зависит от абстрактных типов) в популярных фреймворках, таких как Spring. Вы можете узнать больше о IOC
и DI
в этой статье Мартина Фаулера.
Я надеюсь, что это объясняет строку «декораторы обычно прозрачны для клиента компонента, то есть, если клиент не полагается на конкретный тип компонента»
С другой стороны, instanceof
— это плохой дизайн, который не использует ООП в полной мере, и его следует избегать.