代码之家  ›  专栏  ›  技术社区  ›  Vivin Paliath

MVC实现/最佳实践问题

  •  2
  • Vivin Paliath  · 技术社区  · 16 年前

    这是我的问题。我收到了一个到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 回复  |  直到 16 年前
        1
  •  2
  •   Péter Török    16 年前

    是的,这是消除这种依赖性的一种已知方法。我想不起确切的来源,但有几本书包含了这种技术。

    另一种方法是 AddressData 包装器不是复制和保存所有需要的请求数据,而是保留对它的私有引用并将所有调用转发给它。这可能更灵活、更干净,特别是当有许多请求参数和/或参数经常更改/引入新参数时。

        2
  •  2
  •   Finglas    16 年前

    是的,这是一个有效的解决方案,称为 Parameter Object

        3
  •  1
  •   Bert F    16 年前

    使用接口解耦:

    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);
    }
    

    现在控制器具有选项,并且模型受到保护,不受控制器实现的影响:

    // 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);
    
    推荐文章