簡體   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