This is a design pattern question, so I'll illustrate it with a simple example of an address book app.
Firstly a few assumptions. 1. It appears to be acceptable to directly use DB domain objects as the backing store for Spring MVC forms.
Iteration 1 of my app I created a JPA mapped Person object with various attributes attached. Using the DAO pattern I created a persistence object which can getAll, store and delete people from the database. In addition I have a factory method, create, so I can get a person object. Using this DAO object I create a simple web front end. All is good.
In iteration 2 I need to support multiple storage types, so I create an interface for person, which has multiple implementations, and an interface for the DAO persistence, again with multiple implementations. Also, person was extended to be able to have multiple addresses.
interface IPerson {
public String getName();
public List<IAddress> getAddresses();
}
But, when it comes to updating the web interface to be able to deal with these multiple implementations I have an issue. The persistence implementation is injected by Spring. And, because that persistence object has a factory method I am all good for creating the IPerson implementation. But, if I want to do something fancy like allow multiple addresses be submitted as part of the one request then I have an issue. To allow this to work with Spring you seem to need to use an AutoPopulatingList, so spring can just .get(#) the record an copy the attributes in.
So, one solution to making this work is to require all persistence implementations use an autopopulating list, and create the correct implementation for all child classes. Is this appropriate, given that we'd need to apply this @PostLoad with JPA as the base lists get replaced by Hibernate.
The alternative is to not make any assumptions about the implementation passed into the persistence implementation and convert/copy the objects across to the appropriate type. This looks better, as then the Domain object are kept simple, and all the storage complexity is in the DAO. In this case we'd use a Default* implementation of the IPerson and IAddress interfaces.
Even though I like the second option better, I am not necessarily comfortable with this situation. Can anyone offer any insights or advice?
The alternative is to not make any assumptions about the implementation passed into the persistence implementation and convert/copy the objects across to the appropriate type. This looks better, as then the Domain object are kept simple, and all the storage complexity is in the DAO.he alternative is to not make any assumptions about the implementation passed into the persistence implementation and convert/copy the objects across to the appropriate type.
This is the pattern I've followed with Spring MVC
For example, you might have a pretty rich User
object, but when new Users sign up, they only need to supply 2 or 3 fields. I would model this as a UserSignupCommand
and the UserSignupController
uses this as it's command class (not the User
domain object). The controller is then responsible for taking the UserSignupCommand
bean and either converting the data to a User
bean or whatever other type of input your services layer requires.
I would not recommend using domain objects as the form backing objects because in most cases there is not a true matchup between "the object in my domain I am modeling" and "the data supplied by the user in a form".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With