繁体   English   中英

Spring MVC 3 - 将“不可变”对象绑定到表单

[英]Spring MVC 3 - Binding an 'immutable' object to a form

我有几个完全经过单元测试和精心制作的富DDD模型类,具有最终的不可变不变量和完整性检查。 对象的实例化通过适当的构造函数,静态工厂方法甚至通过构建器来实现。

现在,我必须提供一个Spring MVC表单来创建一些类的新实例。

在我看来(我不是专家)我必须为我要绑定的所有表单的支持类提供空构造函数和属性的setter。

所以我该怎么做 ?

创建专门用于形成支持的贫血对象,并将信息传递给我的域模型(对DRY原则来说太多了......)调用适当的方法/构建器?

或者是否有一些我错过的机会可以挽救我的一天? :)

提前感谢您的智慧!

用于与表示层绑定的对象通常称为视图模型,它们是DTO,用于显示从域对象映射的数据,然后将用户输入映射回域对象。 视图模型通常看起来与它们所代表的域对象非常相似,但是存在一些重要的差异:

  1. 来自域对象的数据可以被展平或以其他方式变换以适合给定视图的要求。 使映射在普通对象中比在演示框架中的映射(例如MVC)更容易管理。 调试和检测错误更容易。

  2. 给定视图可能需要来自多个域对象的数据 - 可能没有单个域对象适合视图的要求。 视图模型可以由多个域对象填充。

  3. 视图模型通常在设计时考虑了特定的表示框架,因此可以利用框架特定的属性进行绑定和客户端验证。 正如您所说,典型的要求是无参数构造函数,这对于视图模型来说很好。 同样,测试和管理视图模型要比某种复杂的映射机制容易得多。

视图模型似乎违反了DRY原则,但仔细观察后,视图模型的责任是不同的,因此在考虑单一责任原则的情况下,有两个类是合适的。 另外,请看一下这篇文章,讨论通常由DRY原则引导的重用谬误。

此外,视图模型确实是贫血的,尽管它们可能具有接受域对象作为参数的构造函数以及使用视图模型中的值作为输入来创建和更新域对象的方法。 根据经验,我发现为每个将由表示层呈现的域实体创建视图模型类是一种很好的做法。 管理域对象和视图模型的双层层次结构比管理复杂的映射机制更容易。

另请注意,有些库试图简化视图模型和域对象之间的映射,例如.NET Framework的AutoMapper

我通过创建DTO接口解决了这个问题:

public interface DTO<T> {
    T getDomainObject();

    void loadFromDomainObject(T domainObject);
}

public class PersonDTO implements DTO<Person> {
    private String firstName;
    private String lastName;

    public PersonDTO() {
        super();
    }

    // setters, getters ...

    @Override
    public Person getDomainObject() {
        return new Person(firstName, lastName);
    }

    @Override
    public void loadFromDomainObject(Person person) {
        this.firstName = person.getFirstName();
        this.lastName = person.getLastName();
    }

    // validation methods, view formatting methods, etc
}

这也会阻止视图验证和格式化内容泄漏到域模型中。 我真的不喜欢在我的域对象中使用Spring特定(或其他特定于框架)的注释(@Value等)和javax.validation注释。

是的,您需要为表单创建对象以获取所有输入,并在一次操作中使用此对象更新模型。

但是我不会把这个对象称为贫血(特别是如果你做DDD)。 这个对象代表一个工作单元。 所以这也是Domain Concepts!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM