【问题标题】:Practical use of Value Objects in Spring MVC applicationSpring MVC 应用中值对象的实际使用
【发布时间】:2016-11-15 17:09:02
【问题描述】:

在我用 Hibernate 和 Spring MVC 编写的应用程序中,我有一些简单的类来表示客户、他的主要办公室地址和其他办公室的位置列表。有一个表单允许添加和编辑客户的数据,然后 Spring MVC 将其映射到 DTO、验证、发送到服务,服务将其转换为(略有不同的)实体并保存。

我考虑过使用值对象来表示和隐式验证某些对象——即电话号码、地址,但我真的不知道如何在这些框架中使用它们——即使我认为我理解值对象的概念和不变性.

如果我将在表示层中使用的 DTO 中使用它们,那么我不能依赖 Spring 将字段从表单映射到对象的机制 - 因为没有设置器。而且我必须在 Controller 或 Service 中手动进行映射。

我应该在实体中使用值对象(嵌入它们)吗?或者也许这太简单了,根本无法使用值对象?

【问题讨论】:

    标签: java spring-mvc domain-driven-design value-objects


    【解决方案1】:

    您的问题主要不是关于值对象,而是您的主要问题(如果我理解正确的话)是如何从 Web 表单发送数据、验证数据并将数据保存在实体中。

    创建一个表单对象,例如MyForm,其中包含用户可以在屏幕中输入的所有字段。表单对象用于将数据传输到服务器,例如:

    class MyForm {
    
        @NotBlank
        private String name;
    
        @NotBlank
        private String phoneNumber;
    
        @NotBlank
        private String address;
    
        // getters and setters
    }
    

    在服务器端控制器验证、转换和存储数据:

    @Controller
    class GuestbookController {
    
        @RequestMapping(value = "/guestbook", method = RequestMethod.GET)
        String myget(Model model, MyForm form) {
            // put data on model
        }
    
        @RequestMapping(value = "/mysubmit", method = RequestMethod.POST)
        String mysubmit(@Valid MyForm form, Errors errors, Model model) {
    
            if (errors.hasErrors()) {
                return myget(model, form);
            }
    
            myrepository.save(new MyEntity(form.getName(), form.getPhoneNumber(), form.getAddress()));
            return "redirect:/myview";
        }
    
    }
    

    您可能需要比单个字符串更详细的地址。那么,是的,使用包含所有地址详细信息的值对象就可以了。

    【讨论】:

      【解决方案2】:

      这是我谦虚的回应。

      • DTO 是没有逻辑的简单数据容器,
      • 而值对象则相反,封装了逻辑。

      只是一个有趣的事情,DTO 过去在 Java 中被称为值对象。

      查看它的一种方法(正如我所读)是让值对象封装实体的所有逻辑,实体只处理身份

      DTO 允许将域模型与 UI(或任何其他端口/适配器)分离。

      值对象应该在域层之外使用吗?我不知道,但我个人不这样做。在我的设置中,它们由应用层和域内部使用,但在应用层之外只有 DTO。

      我有 Spring 可以处理的 DTO 和数据映射器来进行转换(dto 在 UI/应用程序层边界处建模)。 DTO 通常可以有 setter(根据某些人的说法是事件公共财产)。

      现在,如果您想使用框架映射的不可变对象,解决方案取决于您使用的技术。当我使用 JSON(和 Jackson)进行 Web 服务时,我直接使用构造函数上的 @JsonCreator 注释映射不可变命令对象,但我将我的 pojos 耦合到 jackson。为了避免这种情况,您还可以将您的客户序列化程序添加到框架中,让它自动转换控制器方法参数周围的数据结构。

      否则,您始终可以使用数据映射器或工厂方法进行映射。 (我相信你写了一篇关于那个的帖子......)

      【讨论】:

        猜你喜欢
        • 2014-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-29
        • 1970-01-01
        • 1970-01-01
        • 2015-08-28
        • 1970-01-01
        相关资源
        最近更新 更多