Мне приходится работать с кодом, который на самом деле не является 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, который будет хранить данные из запроса, а затем передавать их в службу. Это приемлемый способ ведения дел?
Ответ 1 · рейтинг 2 · Péter Török
Да, это известный способ устранения этой зависимости. Я не могу вспомнить точные источники навскидку, но несколько книг включают эту технику.
Вариантом этого было бы сделать AddressData оболочкой, которая вместо того, чтобы копировать и хранить все необходимые данные запроса в себе, просто хранит приватную ссылку на них и перенаправляет все вызовы на них. Это может быть более гибким и чистым, особенно если параметров запроса много и/или параметры часто меняются/вводятся новые.
Ответ 3 · рейтинг 1 · Bert F
Используйте интерфейсы для разделения:
Модель:
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);