Путаница с шаблоном декоратора?

Я провел некоторое исследование шаблона декоратора, и есть небольшая путаница с пониманием одной из его проблем. Я продолжаю читать, что «декораторы обычно прозрачны для клиента компонента, то есть, если клиент не полагается на конкретный тип компонента». Я не уверен, что это означает - например, если у нас есть класс Beverage и подкласс Coffee, означает ли это, что клиент полагается на Coffee, и поэтому, если бы он был украшен, были бы некоторые проблемы?


person user3370603    schedule 14.05.2015    source источник


Ответы (2)


Да, точно. Если вы полагаетесь на реализации, а не на абстракции (абстрактные классы или интерфейсы), это будет серьезной проблемой для кого-то/вас, кто хочет добавить декоратор между ними.

Ознакомьтесь с принципом инверсии зависимостей в Solid Principles.
Это общее правило в своей основе:

следует «зависеть от абстракций. Не полагайтесь на конкреции».

person Jahan    schedule 14.05.2015

Рассмотрим код:

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 — это плохой дизайн, который не использует ООП в полной мере, и его следует избегать.

person akhil_mittal    schedule 14.05.2015