我必须使用一些不是真正的MVC的代码(即,它不使用显式框架等)。现在我们处理将数据传递给服务的servlet。
这是我的问题。我收到一个servlet的帖子,其中包含一大堆我必须保存到数据库的地址数据。数据(显然)在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
的中间对象,它将保存请求中的数据,然后将其传递给服务。这是一种可接受的做事方式吗?
答案 0 :(得分:2)
是的,这是消除这种依赖性的一种已知方法。我无法回想起我的头脑中的确切来源,但有几本书包括这种技术。
这种方法的一个变体是使AddressData
成为一个包装器,它不是复制并保存所有需要的请求数据,而是保留对它的私有引用并转发对它的所有调用。这可能更灵活,更清洁,特别是如果有许多请求参数和/或参数被更改/新的参数被频繁引入。
答案 1 :(得分:2)
是的,这是一个有效的解决方案,称为Parameter Object。
答案 2 :(得分:1)
使用接口去耦:
型号:
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);