Как применить Composition для совместного использования кода между классами Struts2 Action - PullRequest
1 голос
/ 26 сентября 2011

Совместное использование кода между классами Action легко, если вы используете Inheritance и помещаете весь общий код и свойства в базовый класс.В качестве лучшей практики, я думаю, что эмпирическое правило состоит в том, чтобы предпочитать композицию наследованию .Однако мне очень трудно применить эту концепцию к классам действий.Возможно, я делаю это неправильно.

Например, у меня есть 3 разных класса действий.Все они обрабатывают различные способы регистрации пользователя (пользователь может зарегистрироваться из более чем одной формы). Все они в конечном счете вызывают один и тот же метод обслуживания и должны обрабатывать ошибки одинаково.Общему коду нужно что-то вроде:

public class RegisterAction1 {

    public String execute() {

         ...Leaving out code here....

        try {
            registrationService.register(user);
        } catch (BusinessException e) {
            if(e.getErrors().containsKey("someError3)){
                return "Case1";
            }
            else if (e.getErrors().containsKey("someError1")) {
                session.put(Constants.SESSION_REGISTERVO, registerVO);
                return "Case2";
            } else if(e.getErrors().containsKey("someError2")) {
                this.addFieldError("aliasName", this.getText("some.error"));
            } else if(ce.getErrors().containsKey("someError3")) {
                this.someFieldThatMustBeSetForView1 = true;
                this.someFieldThatMustBeSetForView2 = true;
                this.addFieldError("addressLine1", null);
                this.addFieldError("addressLine2", null);
                this.addFieldError("city", null);
            }
        }

        ...Leaving out code here....

        return "Success";
    }
}

Чтобы использовать композицию, я бы подумал, что вы переместили бы этот кусок логики в класс «Помощник» и имели бы ссылку на этот Помощник в классе Action.Если бы вы создали метод "callService" в этом вспомогательном классе, который реализовал этот общий код, как бы вы справились с тем фактом, что большая часть кода фактически изменяет поля в классе ... т.е. передаете ли вы ссылку наДействие для вспомогательного метода вроде следующего?И если да, то как вы справляетесь с тем фактом, что это может быть 1 из трех различных классов действий (т. Е. RegisterAction1, RegisterAction2, RegisterAction3)?

public String callService(RegisterAction1 registerAction) {

1 Ответ

2 голосов
/ 27 сентября 2011

Есть несколько способов сделать это.

Если есть классы без действий, которые должны изменить данные действия, я мог бы выбрать подход ModelDriven и передать модельвокруг, отделив его от архитектуры S2 (при условии, что ваши действия расширяются ActionSupport).

В вашем случае вы также непосредственно модифицируете полевые ошибки (это просто карта).Наивный (и, вероятно, достаточно хороший) подход будет состоять в том, чтобы либо просто передать это вместе, либо передать назад что-то, что можно использовать для изменения ошибок поля, либо в перехватчике, либо в баземетод действия класса.Или, как в приведенном ниже варианте, предположите доступ к ValidationAware impl (а также к модели или ModelDriven impl).

Другой вариант - инкапсуляция соответствующих частей в интерфейсе.единственное, что передается помощнику, это реализация интерфейса.Сюда также может входить ValidationAware, если вам нужен прямой доступ к карте ошибок полей.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...