Смотреть фото Фасад и Строитель
Я сделал упражнение с Фасадом и Строителем. Root - это простой LoginService-интерфейс
public interface LoginService {
void addUser(int id, String username, String password, String mail);
boolean login(String username, String password);
void logout();
}
Другие классы - это LoginServiceDecorator и некоторые конкретные декораторы. Наконец Строитель, который проверен таким образом:
service = new LoginServiceBuilder().withValidation().withEncoding().withLogging().toService();
с некоторыми тестами.
Все было хорошо, до реализации toService()
-метод, где я не очень хорошо представлял, как реализовать. Я показываю, где я застрял:
LoginServiceBuilder
public class LoginServiceBuilder {
/*
* Note that the decorators must be connected in reverse order of the
* builder method invocations. So we use a stack to hold all decorator
* instances and at the end of the building process, we connect the
* decorators in the right order.
*/
private Stack<LoginServiceDecorator> stack = new Stack<LoginServiceDecorator>();
public LoginServiceBuilder() {
}
public LoginServiceBuilder withValidation() {
stack.push(new ValidationDecorator(new LoginServiceImpl()));
return this;
}
public LoginServiceBuilder withEncoding() {
stack.push(new EncodingDecorator(new LoginServiceImpl()));
return this;
}
public LoginServiceBuilder withLogging() {
stack.push(new LoggingDecorator(new LoginServiceImpl()));
return this;
}
public LoginService toService() {
// Here I stucked
}
Ну, наконец, я сдался и посмотрел на решение:
public LoginService toService() {
LoginService service = new LoginServiceImpl();
while (!stack.isEmpty()) {
LoginServiceDecorator decorator = stack.pop();
decorator.setService(service); // just to set the private member there (Type of the Interface as shown at beginning)
service = decorator;
}
return service;
}
Вот почему я до сих пор чищу свою шею так: для меня это выглядит так, что когда стек пуст, служба проста последней, которую он поймал. Может быть, кто-то мог бы объяснить мне мягкими словами, почему у меня должны быть все декораторы сейчас.
Большое спасибо заранее
1 ответ
Роль декоратора состоит в том, чтобы динамически добавлять поведение объекта. Вот почему они реализуют один и тот же интерфейс.
У вас должен быть один декоратор для одного добавленного поведения. Вот почему вы создаете стек декораторов
decorator.anOperation()
должен выполнить decoratedObject.anOperation()
Используя наследование, вы можете заменить оформленный объект вместо украшенного объекта. Вот почему у вас есть service = decorator
, В вашем примере вы заменяете свой сервис (decorObject) на связанный декоратор, а затем применяете следующий декоратор к DecoOredObject.
В конце стека у вас есть "fullDecoratedObject".
Для более подробного объяснения, я считаю этот сайт полезным http://www.dofactory.com/. Реализация в C#, но она легко конвертируется в Java. смотрите эту страницу: http://www.dofactory.com/net/decorator-design-pattern
Надеюсь это поможет