Inversion of the problem of constructing object management objects

As I understand it, an IoC container is useful when creating application-level objects, such as services and factories. But domain level objects must be created manually. The Spring manual says: "Normally, fine-grained domain objects are not defined in a container, because DAO and business logic are usually required to create / load domain objects."

Well. But what if my domain is a “fine-grained” object depending on some application-level object. For example, I have a UserViewer (user user, UserConstants). There, the user is a domain object that cannot be entered, but UserViewer also needs UserConstants, which is a high-level object injected by the IoC container.

I want to add UserConstants from an IoC container, but I also need a User runtime temporary parameter.

What is wrong with the design?

Thanks in advance!

UPDATE

It seems I was not accurate enough with my question. I really need an example of how to do this:

create an instance of the UserViewer class (User user, UserService service), where the user is passed as a parameter and the service is entered from IoC.

If I add a UserViewer viewer, then how do I pass it to the user?

If I create the UserViewer viewer manually, then how do I pass it?

+4
source share
3 answers

There is nothing wrong with this design. you use Factories for this, which has one foot in the domain, one foot in the infrastructure.

You can either write them manually or make a container for you with things like the TypedFactoryFacility in Windsor.

Also, when your domain objects come from a persistence level, you can connect it to a container to implement the services they require (NHibernate can do this).

+4
source

But what if my “fine-grained” domain depends on some application-level object?

That is what is considered bad practice. I would say that problems can be:

  • There are many such objects, so performance and memory problems may occur.
  • The style of POJO is that they can be used in all environments (stored in a database, processed by business algorithms and rules, technologies are read and installed, serialized and transmitted over the network). Deploying objects at the application level can lead to the following problems:

    • In your architecture, you probably have a rule that some (most) application-level objects can be used in some layers and not in others. Since all layers have access to pojos, this rule will be violated transitively.
    • When serialized and rebuilt in another JVM, that will mean your application-level objects. They are useless, they need to be changed for local equivalents ...

Typically, the pojos that make up your domain are self-contained. They can have access to other pojos (and many enumerations), that's all.

In addition to data, they have methods that implement the details of business rules or algorithms (remember the idea of ​​OO grouping data and code that work on it ;-)):

  • This is especially good when they have inheritance, because it allows you to set up a business rule for some pojo, providing a different implementation (different case without if or switch: remember OO? ;-)).
  • Any code that requires access to objects of the application level (for example, access to the database) is taken out, for example, in the Service or Manager. But this code remains at a high level, thus readable and simple, because pojos themselves take care of low-level details (and special cases).

    After this, you will often find out that pojo methods are reused and compiled in various ways by services or managers. This is a big win in reducing duplication, method names provide much-needed “value” and provide easier access to developers who are new to the module.

+1
source

For your update:

create an instance of the UserViewer class (User user, UserService service), where the user is passed as a parameter and the service is entered from IoC.

If I add a UserViewer viewer, then how do I pass it to the user?

If I create the UserViewer viewer manually, then how do I pass it?

In this case, you will need the factory method (possibly a factory or your locator). He could look further, dividing two parts:

 public UserViewer createUserViewer(User user) { UserViewer viewer = instantiateBean(UserViewer.class); viewer.setUser(user); return viewer; } private <E> E instantiateBean(Class<E> clazz) { // call the IoC container to create and inject a bean } 
0
source

All Articles