MVC实施/最佳实践问题

时间:2010-04-15 21:15:16

标签: model-view-controller design-patterns

我必须使用一些不是真正的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的中间对象,它将保存请求中的数据,然后将其传递给服务。这是一种可接受的做事方式吗?

3 个答案:

答案 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);