Should Enterprise Java Objects Be Mute?

Our legacy Java EE application has value class (VO) classes that usually contain only getters and setters, possibly equals() and hashCode() . These are (usually) objects that need to be stored in persistent storage. (For writing, our application does not have an EJB, although this may change in the future - and we use Hibernate to save our objects.) All business logic for managing data in VO is in separate classes (not EJB, but just POJO). My OO thinking hates this, since I believe that operations on a particular class should be in the same class. Therefore, I have a desire to refactor in order to move the logic to the corresponding VOs.

I just discussed with a colleague who is much more experienced in Java EE than I did, and he confirmed that dumb entities were at least the recommended way. However, he also recently read opinions that cast doubt on the validity of this position.

I understand that there are problems that at least limit what can be placed inside an entity class:

  • it should not be directly dependent on the data level (for example, the request code should go into separate DAOs)
  • if it is directly open to higher levels or to the client (for example, through SOAP), its interface may need to be limited

Are there any more compelling reasons not to move logic into my entities? Or any other issues to consider?

+25
java java-ee oop entity
Feb 25 '10 at 10:40
source share
8 answers

It is assumed that DTO and VO are used to transmit data and do not insert logic. business objects , on the other hand, must embed some logic. I say some because there is always a balance between what you invest in services that coordinate the logic with the participation of several business objects and what you invest in the business objects themselves. Typical business object logic can be validation, field computation, or another operation that affects only one business object at a time.

Note that I still haven't mentioned the term entity . Persistent entities were popularized using ORM, and we are currently trying to use persistent objects of both DTO and business objects at the same time. That is, the object itself flows between levels and levels and contains some logic.

Are there any more compelling reasons rather than moving logic into my entities? Or any other issues that need to be considered?

As you pointed out, it all depends on the dependencies and what you reveal. While the objects are dull (close to DTO), they can be isolated in a dedicated bank easily, which serves as an API level . The more logic you put into entities, the more complicated it becomes. Pay attention to what you are showing and what you are dependent on (loading the class, the client must also have a dependency class). This applies to exceptions, inheritance hierarchies, etc.

To give an example, I had a project in which the objects had the toXml(...) method used in the business layer. As a result, the object client depended on XML.

But if you don't care too much about the layers and the strict separation between the API and the implementation, I think it's useful to move some logic into the entity.

EDIT

This question has been discussed many times and is likely to continue the discussion as there is no final answer. Some interesting links:

+16
Feb 25 '10 at 12:29
source share

I think your point is correct.
See This For More - http://martinfowler.com/bliki/AnemicDomainModel.html
With JPA, Objects are lightweight objects. Therefore, I do not think that she has problems with the logic in them. If used with SOAP / Web Services, I will add a separate facade.

+8
Feb 25 '10 at 10:46
source share

In addition to the Fowler article mentioned earlier, there is a complete treatise on models with rich and anemic domains in Eric Evans' book, Domain Driven Design (2004).

Also check out http://dddcommunity.org/

+4
Feb 25 '10 at 17:40
source share

Right, here is a summary of the feedback received from my Java EE trainer.

From an evaluation perspective, reaching a compromise between anemic and rich domains by moving logic should not be a problem if methods work with Entity attributes. When it comes to a rich domain, the line has to be drawn somewhere, and both Fowler and King seem to have published comments in this direction.

For example, consider the calculateInterestRate () method inside BankAccount, which extracts information from other domain objects, for example, by checking how long someone has been a customer. To avoid dependency, you can divide the method into all objects, but this approach means that the code can end up scattered across several classes. At this point, you can create the InterestCalculator class.

Another thing to consider is thread safety. Singleton DAO and Services handled by Spring must be thread safe, while everything in the domain model will be subject to concurrency issues.

Finally, there is a maintenance problem. Are you sure you will support the application in a couple of years? The choices you make may seem warranted, but are you sure that the next developer will have the experience needed to easily understand your code?

+3
Feb 26 '10 at 12:27
source share

The convention you are talking about is to adopt an anemic domain model, as opposed to a rich domain model, where Entities are simple POJOs annotated as beans (@Entity) with a minimal minimum in terms of getters and seters. Thus, a class with the toXML () method will be considered as a rich domain. I think this helps to keep a clear idea of ​​what is displayed in the relational database, even if the granularity is different.

The advantage is that there is a clear separation between logic and data (the OO philosophy is violated here). The approach is to group them into business logic classes or Services. This corresponds to a tiered architecture with corresponding levels: Domain, Services, DAO and UI.

What a theory.

Edit: just to clarify, when I say there is a clear separation between logic and data, I mean that one object is data oriented, and the other method is oriented in a way that could be considered the end of the procedure.

+1
Feb 25 '10 at 12:25
source share

The main problem with adding logic to these classes is that they will need more attributes to track the state of the object, and these additional attributes usually do not need to be serialized. This means that more work is needed in the serialization mechanism of these classes.

Given that many projects have a mixture of jr. programmers and cf. programmers and most of the work is done by younger ones who don’t understand (or don't care) about optimal serialization, it’s much easier to have these simple old Java objects as “value objects” that pretty much just transmit and receive data and put the logic in another place .

If you manage to create an architecture where logic is placed in a business object (i.e. VO + Logic), I think it would be better. Just keep in mind that the whole team is on the same page and they don’t duplicate code and logic (which is never right?)

Short answer: No, they should not always be stupid, but it is much easier to have them that way.

+1
Feb 25 '10 at 17:00
source share

I did some C programming, and while OOP is good for simplifying problems by creating class hierarchies, I still think that C's simple approach is the simplest and biggest in many cases. In C, we have structures with only public members, and the programmer passes functions to such structures (in Java, such functions will be, for example, static functions in some class) that control the elements. Data and algorithm are separate because functions are not members of structures. I always had the feeling that VO objects are similar to structures in C.

There are many cases where the C language is not the largest, because, for example, there is no hierarchy, there is no polymorphism, things that worthy OOP programmers find useful. However, overall I like this simple C approach and prefer to use it if I don't know that the OOP method will be really useful. For example. when I need to use the class hierarchy to model something or I need to make sure that the members of one or more classes (in the hierarchy) are always compatible with each other, then I cannot use the C struct approach. But in these cases, I would not only have setters and getters.

I would also call this article on C ++, but I like the way this guy explains things like this: http://www.gotw.ca/gotw/084.htm There are 2 rules in this article about when to make a function class member:

(from the quote below I leave some things, read the original if you want to see everything)

  • Always make it a member if it should be one: what operations should be members, because C ++ just says that (for example, constructors) or for functional reasons (for example, they should be virtual)? If they should be, then, well, they just have to be; closed.

  • Prefer to become a member if he needs access to internal elements: for which operations do you need access to internal data that we could provide through friendship? Usually they should be members.

In all other cases, prefer to do this nonmember nonfriend: what operations can work equally well, as nonmember nonfriends? They can and should usually be non-members. This should be the default case you want to strive for.

I have the feeling that if you doubt whether to add functions to these classes, you have no real need. What I wrote here is only part of all the reasons why I would not add methods to such classes, but perhaps this is the father of all my other reasons. But this is all subjective, therefore YMMV. By the way, the approach of static utility functions simplifies unit testing in most cases.

0
Jun 13 '13 at 17:39
source share

Objects are often generated. In languages ​​like Java, there is no partial class, so we cannot extend the entity (without considering patterns like Visitor). Therefore, when you need to restore your entities, you will have to add business logic again, which is not at all practical.

With entities, I would prefer a high level of coupling between objects and their logic.

Other issues to consider are the fact that not all business operations on an entity are the same in all situations. In addition, resolving business logic in entities tends to expose the entity to interactions with integration technologies such as XML, which, in my opinion, should always be kept away from domain logic. In bow architecture, XML will reside in the outer shell and domain objects in the inner part to illustrate how far they really are from each other if you want to create a reusable plug-in system.

0
Apr 03 '17 at 7:19
source share



All Articles