Split backup storage with Spring Web MVC

This is a template template, so I will illustrate it with a simple example of an address book application.

Firstly, a few assumptions. 1. It seems acceptable to directly use database domain objects as backup storage for Spring MVC forms.

Iteration 1 of my application I created a JPA object object mapped to various attributes. Using the DAO pattern, I created a persistence object that can getAll to store and delete people from the database. Also, I have a factory method, create so that I can get the person object. Using this DAO object, I am creating a simple web interface. All is well.

In iteration 2, I need to support several types of repositories, so I am creating an interface for a person who has several implementations, and an interface for saving DAO, again with several implementations. In addition, the person has been expanded 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 a problem. The persistence implementation is introduced by Spring. And since this persistence object has a factory method, I am well versed in the implementation of IPerson. But, if I want to do something unusual, for example, to allow the transfer of multiple addresses as part of a single request, then I have a problem. To let this work with Spring, you seem to need to use an AutoPopulatingList, so Spring can just .get (#) write a copy of the attributes.

Thus, one of the solutions to this work is the requirement that all persistence implementations use an autopopulation list and create the correct implementation for all child classes. This is appropriate given that we will need to apply this @PostLoad with JPA, as the base lists will be replaced with Hibernate.

An alternative is the absence of any implementation assumptions passed into the persistence implementation, and the conversion / copying of objects to the appropriate type. This looks better, because then the Domain object remains simple, and all the storage complexity is in the DAO. In this case, we will use the default implementation * of the IPerson and IAddress interfaces.

Despite the fact that I like the second option better, I'm not necessarily comfortable with this situation. Can anyone offer any ideas or tips?

+4
source share
3 answers

An alternative is the absence of any implementation assumptions passed into the persistence implementation, and the conversion / copying of objects to the appropriate type. It looks better, because then the domain object remains simple, and all the storage complexity is in the DAO. An alternative is the absence of any implementation assumptions passed into the persistence implementation, and the conversion / copying of objects to the appropriate type.

This is the pattern I came across with Spring MVC

  • A package of domain objects that do not have links to DAO services / code (think of it as your model)
  • Controller level, service level and DAO level work with domain objects
  • To process form controllers, use a separate layer of “team” or “form” objects, which model the data that the user fills in the form, rather than domain objects. Users pass it to the controller, which associates the request with the command / form object, and your controller displays or converts these beans to your beans domain.

For example, you may have a rather rich User object, but when new users register, they need to provide only 2 or 3 fields. I would like to simulate this as a UserSignupCommand , and UserSignupController uses this as its command class (and not a User domain object). The controller is then responsible for receiving the UserSignupCommand bean and converting the data to a User bean or any other type of input that is required for your service level.

I would not recommend using domain objects as form support objects, because in most cases there is no true correspondence between "the object in my domain that I am modeling" and "the data provided by the user in the form."

+4
source

It’s very unpleasant to have several sets of classes that embody the same business data with only different settings. It is really disgusting, as if I had to choose between something like one of your persistence paths, like JAXB, and with multiple dodges, I would rather give up technology and find a better way to do it, because having all this meaningless code is a major pain.

Alan Perlis said: "It is better to have 100 functions running on one data structure than 10 functions on 10 data structures." You especially want to avoid data structures that basically duplicate each other. Maintaining a backup code base is not fun.

I suggest you check out domain driven design. The idea is that you have domain objects that do not know how they are stored (this is called Persistence Notorance). Thus, your domain objects can be POJOs, you usually do not need to install interfaces on them, because they have no dependencies on anything in your application, other than other domain objects. (There may be extreme cases where this becomes useful, but this will not be a normal case.) You can put your business logic (information about how the domain object relates to other domain objects) into the domain object without worrying about how to check it because there is no database binding. In addition, domain objects can be freely transferred throughout the application, since they do not have any dependencies at a certain level. From the point of view of dependencies, the domain level is responsible for all other parts of the application, but does not depend on them.

The result of all this is that the domain logic and technical data on how objects are stored become separate problems, so each can be tested separately. You also have a central data structure that contains all the business data in only one place, so you do not have a few changes that can happen when something changes.

There is a free web book available on the basis of a domain managed http://www.infoq.com .

+4
source

Usually I do not have interfaces for model objects such as Person and Address. I wonder why you decided to go this route?

I can’t think of several implementations for each. If your IPerson has implementations such as Mother, Sister, Friend, etc., I would recommend using a role design instead. Just because the phrase "Genie is mother" comes off the tongue so beautifully does not mean that you are reasonable to base your design on IS-A and inheritance.

The address may be variable, as you move between countries, so it may be more reasonable, but it will be very difficult for you to come up with one interface that is suitable for both the United States and Japan.

In iteration 2, I need to support several types of storage,

Can you clarify this? What does "several types of storage" mean? DAOs that use relational databases, file systems, object databases, etc.?

so I create an interface for a person who has several implementations,

I do not see how this is necessary for the previous requirement.

and an interface for saving DAO, again with several implementations.

This is the usual Spring idiom.

I would say that the network and personal levels do not need to worry about the complexity of perseverance. This is what the persistence interface should be hiding. Everything that makes him seep into other layers makes his customers bad. I think I would prefer your second option.

But my real recommendation would be to eliminate the IPerson interface if you cannot provide an air reason for storing it.

+1
source

All Articles