Смотреть фото Фасад и Строитель

Я сделал упражнение с Фасадом и Строителем. 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

Надеюсь это поможет

Другие вопросы по тегам