Реализация MVC/вопрос о передовой практике

Мне приходится работать с кодом, который на самом деле не является MVC (т. е., среди прочего, он не использует явную структуру). Сейчас мы обходимся сервлетами, передающими данные службам.

Вот моя проблема. Я получаю сообщение на сервлет, который содержит целую кучу адресных данных, которые я должен сохранить в базе данных. Данные (очевидно) находятся в объекте HttpServletRequest. Мой вопрос: как мне передать эти данные в службу? Я неохотно делаю это так:

AddressService.saveAddress(request);

Потому что я не думаю, что служба должна иметь зависимость от запроса. Мой другой вариант - сделать что-то вроде этого:

String addressLine = request.getParameter("addressLine");
..
.. about 7 other parameters
..
String zip = request.getParameter("zip");

AddressService.saveAddress(addressLine, ... 7 other parameters ..., zip);

Но мне тоже не нравится иметь функцию с огромным количеством параметров. Я думал о создании промежуточного объекта с именем AddressData, который будет хранить данные из запроса, а затем передавать их в службу. Это приемлемый способ ведения дел?


person Vivin Paliath    schedule 15.04.2010    source источник


Ответы (3)


Да, это известный способ устранения этой зависимости. Я не могу вспомнить точные источники навскидку, но несколько книг включают эту технику.

Вариантом этого было бы сделать AddressData оболочкой, которая вместо того, чтобы копировать и хранить все необходимые данные запроса в себе, просто хранит приватную ссылку на них и перенаправляет все вызовы на них. Это может быть более гибким и чистым, особенно если параметров запроса много и/или параметры часто меняются/вводятся новые.

person Péter Török    schedule 15.04.2010

Да, это допустимое решение, и оно называется объектом параметров.

person Finglas    schedule 15.04.2010

Используйте интерфейсы для разделения:

Модель:

public interface Address {
    String getLine1();
    String getLine2();
    ...
    String getZip();
}
public class AddressBase implements Address {
    public AddressBase(String line1, String line2, ..., String zip) {
       ...
    }
    ...
}
public class AddressService {
    void saveAddress(Address address);
}

Теперь у контроллера(ов) есть опции и модель защищена от реализации контроллера:

Вариант контроллера 1:

// wrap - lazy interrogator
class AddressRequestWrapper implements Address {
    ...
    AddressRequestWrapper(HttpRequest request) {
        this.request = request;
    }
    String getLine1() {   return request.get(LINE_1_FIELD_ID); }
    ...
}

Вариант контроллера 2:

// "wrap" - eager interrogator
class AddressRequestWrapper extends AddressBase {
    AddressRequestWrapper(HttpRequest request) {
        super(
            request.get(LINE_1_FIELD_ID),
            request.get(LINE_2_FIELD_ID),
            ...
            request.get(ZIP_FIELD_ID)
        );
  }
  ...
}

Вариант контроллера 3:

// Just use AddressBase directly
Address address =
    new AddressBase(
            request.get(LINE_1_FIELD_ID),
            request.get(LINE_2_FIELD_ID),
            ...
            request.get(ZIP_FIELD_ID)
    );
AddressService.saveAddress(address);
person Bert F    schedule 15.04.2010