Spring MVC 3 - Binding an "Immutable" Object to a Form

I have several carefully thought-out and finely crafted rich DDD model classes with final invariant invariants and integrity checks. An instance of an object is created through the corresponding constructors, static factory methods, and even through Builders.

Now I have to provide a Spring MVC form to create new instances of some classes.

It seems to me (I'm not an expert) that I should provide empty constructors and attributes for all the form support classes that I want to bind.

So what should I do?

Create anemic objects designed to support the form and transmit the information of my domain model (so much for the DRY principle ...) calling the appropriate methods / builder?

Or are there mecanisms that I missed that could save my day? :)

Thank you in advance for your wisdom!

+7
source share
3 answers

Objects that are used to associate with presentation levels are usually called view models, and they are DTOs designed to display data displayed from domain objects and then map user input back to domain objects. View models usually look very similar to the domain objects that they represent, but there are some important differences:

  • The data of domain objects can be flattened or otherwise transformed in accordance with the requirements of this type. Having mappings in simple objects is easier to manage than mappings in a view structure such as MVC. Easier to debug and detect errors.

  • For this view, data from several domain objects may be required - there cannot be an object with one domain that meets the requirements of the view. A view model can be populated with several domain objects.

  • A presentation model is usually developed taking into account the specific structure of the presentation and, as such, can use infrastructure-specific attributes for binding and validation on the client side. As you said, a typical requirement is a parameterless constructor, which works great for a view model. Again, it’s much easier to test and manage the view model than some kind of complex rendering engine.

The presented models, apparently, violate the DRY principle, however, after closer attention, the responsibility of the viewing model differs, therefore, with the principle of single responsibility, this article discusses the error of reuse, often cited according to the DRY principle.

In addition, view models are truly anemic, although they can have a constructor that takes a domain object as a parameter and a way to create and update a domain object using the values ​​in the view model as input. From experience, I believe that it is good practice to create a presentation model class for each domain object that will be displayed by the presentation level. It’s easier to manage a hierarchy of double classes of domain objects and a view model than to manage complex display mechanisms.

In addition, there are libraries that try to simplify the mapping between view models and domain objects, such as AutoMapper for the .NET Framework.

+10
source

Yes, you will need to create Objects for the form to take all the input data, and update your model using these objects in one operation.

But I will not call these objects anemic (especially if you do DDD). These objects represent one unit of work. So these are Domain Concepts!

0
source

I solved this by creating a DTO interface:

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 } 

It also stops checking and formatting checks for leakage into the domain model. I really dislike Spring specific (or other structure specific) annotations (@Value, etc.) and javax.validation annotations in my domain objects.

0
source

All Articles