How much business logic should Value objects contain?

The idea of putting data and business logic together is to promote encapsulation, and to expose as little internal state as possible to other objects. That way, clients can rely on an interface rather than on an implementation. See the "Tell, Don't Ask" principle and the Law of Demeter. Encapsulation makes it easier to understand the states data can be in, easier to read code, easier to decouple classes and generally easier to unit test.

Externalising business logic (generally into "Service" or "Manager" classes) makes questions like "where is this data used?" and "What states can it be in?" a lot more difficult to answer. It's also a procedural way of thinking, wrapped up in an object. This can lead to an anemic domain model.

Externalising behaviour isn't always bad. For example, a service layer might orchestrate domain objects, but without taking over their state-manipulating responsibilities. Or, when you are mostly doing reads/writes to a DB that map nicely to input forms, maybe you don't need a domain model - or the painful object/relational mapping overhead it entails - at all.

Transfer Objects often serve to decouple architectural layers from each other (or from an external system) by providing the minimum state information the calling layer needs, without exposing any business logic.

This can be useful, for example when preparing information for the view: just give the view the information it needs, and nothing else, so that it can concentrate on how to display the information, rather than what information to display. For example, the TO might be an aggregation of several sources of data.

One advantage is that your views and your domain objects are decoupled. Using your domain objects in JSPs can make your domain harder to refactor and promotes the indiscriminate use of getters and setters (hence breaking encapsulation).

However, there's also an overhead associated with having a lot of Transfer Objects and often a lot of duplication, too. Some projects I've been on end up with TO's that basically mirror other domain objects (which I consider an anti-pattern).


You should better call them Transfer Objects or Data transfer objects (DTO).

Earlier this same j2ee pattern was called 'Value object' but they changed the name because it was confused with this

http://dddcommunity.org/discussion/messageboardarchive/ValueObjects.html

To answer your question, I would only put minimal logic to my DTOs, logic that is required for display reasons.

Even better, if we are talking about a database based web application, I would go beyond the core j2ee patterns and use Hibernate or the Java Persistence API to create a domain model that supports lazy loading of relations and use this in the view.

See the Open session in view.

In this way, you don't have to program a set of DTOs and you have all the business logic available to use in your views/controllers etc.


It depends.

oops, did I just blurt out a cliche?

The basic question to ask for designing an object is: will the logic governing the object's data be different or the same when used/consumed by other objects?

If different areas of usage call for different logic, externalise it. If it is the same no matter where the object travels to, place it together with the class.