2014-02-10 3 views
1

Я читаю рисунок дизайна Decorator от Gof. Я имею неурядицы в следующих точкахConfusion in Decorator Pattern

  1. Это говорит важный аспект паттерна это позволяет декораторы появляться в любом месте, где используется компонент. Клиент не может вообще сказать разницу между украшенным компонентом или не украшенным компонентом? Например, если я думаю, что я клиент, а базовый компонент связан с электронной почтой, но я также хочу, чтобы он был защищен. Кто-то предоставляет мне функциональность.

    Email email = new SecuredEmail(new TextEmail()); 
    

    В: Это просто довольно гипотетически. Разве я не знаю, как клиент знает , что этот текст-адрес украшен? Я просто смущен, может кто-то прояснить это сомнение?

  2. Декоратор и его компонент не идентичны. Декоратор действует как прозрачный корпус . Но с точки зрения идентичности объекта декорированный компонент не идентичен самому компоненту. Следовательно, вы не должны полагаться на идентификатор объекта при использовании декораторов. Что это значит?

Может кто-нибудь объяснить эти две части.

Бен

+0

Вы собрали создание и использование. Это две совершенно разные вещи в шаблонах. Во время творения вы должны все знать. Во время использования вам не нужны эти знания. – nikita

ответ

2

Допустим, что Email является интерфейсом Java. Любой класс, реализующий Email, может быть использован для инициализации переменной email, включая любой декоратор, поскольку декораторы реализуют интерфейс или расширяют абстрактный класс (реализующий интерфейс). Конечно, клиенты могут знать, что такое экземпляр класса, но обычно им это не нужно. Просто используйте email.getClass().

С другой стороны, декоратор не является тем же объектом, что и украшенный. Он обертывает украшенный предмет. Поэтому TextEmail и SecuredEmail - это не одни и те же объекты. Если код выглядел так:

TextEmail txtEmail = new TextEmail(); 
SecuredEmail securedEmail = new SecuredEmail(txtEmail); 

затем проверяя их идентичность даст следующий результат:

System.out.println("identical: " + (txtEmail == securedEmail)); 

т.е.

identical: false 

equals(Object) мог быть написан так, что может дать другой результат , например

System.out.println("equal: " + txtEmail.equals(securedEmail)); 

выход:

equal: true 
+0

IMHO вы нарушили второе заявление. Я не вижу причин, по которым текстовые сообщения должны быть равны. –

+0

Спасибо @Vash - нет причин, чтобы эти два объекта были равны в этом случае. В общем, это может быть случай. –

+0

Спасибо @Vash и Борис. Короче говоря, в основном декоратор расширяет абстрактный класс, который inturn реализует или расширяет интерфейс компонента, поэтому они не могут быть идентичными, как в случае идентичности? – benz

1

Вы не клиент. Код с использованием электронной почты является клиентом, и он знает только, что объект является электронной почтой. Он не будет знать, что это TextEmail, украшенный SecuredEmail.

Что касается использования идентификатора объекта, это означает, что кусок кода должен работать одинаково, передается ли ему TextEmail или TextEmail, завернутый в SecuredEmail.В техническом смысле вы не должны полагаться на email1 == email2, так как email2 может быть электронной почтой1, украшенной SecureEmail.

1

Ad.1 В качестве клиента, пользователя декорированного класса вы не можете определить, какую реализацию вы используете.

Мы должны предположить, что Email, является интерфейсом и не создавать два метода.

Метод 1

public Email getMail() { 
    reutrn TextEmai(); 
} 

Метод 2

public Email getMail() { 
    reutrn SecureEmail(); 
} 

Как пользователь с API, вы будете знать, что существует класс, который есть метод Email getMail(), вы не можете определить по его описание какого класса будет решаться. Это может быть метод 1 или метод 2. Но в качестве используемого вы не можете быть уверены.

Второй момент, см. Равенство объекта. В этом примере объект TextEmail не равен SecureEmail. Как пояснил Борис в своем ответе и комментариях. Декоратор может, но не должен реализовывать метод equals таким же образом. Поэтому никогда не следует доверять или полагаться на равенство при использовании шаблона декоратора.

+0

Итак, это вкратце означает, что в основном декоратор расширяет абстрактный класс, который, в свою очередь, реализует или расширяет интерфейс компонента, поэтому они не могут быть идентичными, как в случае идентичности? Да, как объяснил Борис, если мы реализуем равные в некотором смысле, это может вернуть истину, но это полностью зависит от реализации. Правильно ли я понимаю? – benz

+0

Больше o меньше да. Декоратор может распространять любые нечетные классы или объекты и интерфейсы и принимать в качестве аргумента экземпляр. Но, наконец, дело в том, что пользователь (разработчик), вы не можете предположить, какой декоратор использовался или доверять тому, что метод равен, будет работать одинаково для украшенного объекта. –