Question

I took a JavaEE course today and I was presented to the "default" JavaEE architecture, which consists mainly of Entities, Services and DTOs. The guy presenting the course explained that it was indeed a case of anemic models, but however this was the "in facto standard JavaEE architecture".

I am new to JavaEE, but I've head some experience with other languages. The first time I read about beans as components, I thought they would be great to create a DDD-like architecture.

It sounds strange to me that a "standard architecture" has a anemic domain (I, until now, thought it was a "bad smell").

Is there any technical reason or big advantage of using this architecture? Why an architecture that defines its models to be anemic is the current standard?

I asked him and he talked about transaction context, but I have to admit I didn't understood exactly what he meant.

Was it helpful?

Solution

I see this in the .NET world as well and I have so far identified a handful of reasons as to why this happens (I also do not prefer anemic data models).

  1. Old code. People didn't know better and it's too expensive to rewrite.
  2. Misinterpretation of the DRY principle. People want to use their objects as contracts and send them over the wire as XML/JSON and then prefer to make them into simple DTO's - and instead of using these as contracts and then translating them to real domain objects at the boundaries people go to the anemic domain model antipattern instead in order to not have two objects representing the "same" object.
  3. The application is actually not complex enough to warrant a domain model.

Now, in 1 and 3 an anemic domain model might actually be the right choice. Having a rich domain model can be a lot of work which may not actually provide enough value given your application. Many applications, even in the JavaEE world, are just glorified CRUD-layers on top of a database. If there aren't enough domain logic, anemic domain models can actually be the correct choice.

In 2 however I'd say that it's just bad practices. If you have an application with a domain that is rich enough to warrant a domain model then you should have one. According to SRP each object should have a single responsibility, DTO's by design already have one responsibility - represent the data transfer format between your system and an external system. You should not use them for anything else. There should be a mapping layer (which in these days are much faster to write than they've ever been before since there are plenty of frameworks/libraries that can remove a lot of the busywork in writing these) that maps from the DTO to your domain objects and vice versa - and then your application should only use these domain objects to perform its intended purpose. This also gives you the chance to refactor and change your implementation independently of changing your external contract - and this is a huge gain once you're in production.

But yes. It can be a lot of extra work, and the really hard part about this is looking at your domain and asking the question "Does this domain motivate going full on DDD?". And you really shouldn't underestimate that question, it's actually a really hard one.

OTHER TIPS

Typically you domain objects would cross layers and also process boundaries. So your Domain objects which are typically POJOs are essentially the contract between layers and processes. Contracts should define the expected structure of inputs, outputs (and exceptions) not the business logic. This is true weather you are writing enterprise code or otherwise.

Keeping the domains light weight and bare-bones ensures that the conversion (serializations in various forms) takes place easily. Here is an example - your domain gets spitted out by Jersy Clients as a JSON object - now if you object has a lot of BL and dependencies - the conversion or serialization to JSON will be complicated and unwanted knowledge will be passed on to the client which only cares for the data.

That is not to say your objects have to be dumb! If you can reduce redundancy in the object by providing one field with some additional getter methods for convenience by all means go ahead and do it - example if you have unit cost and quantity fields in your POJO but for display you typically need the total price go ahead and add it as a getter without introducing a new fields (redundant) - make sure you provide no setter method for it only getter. this kind of border lines with BL but it isn't if the role of your services is a lot more involved than computing price.

This does not mean J2EE applications are based on skimpy models it just that you can implement any more complex model using only entities, attributes and relationships.

In the same way you can implement any control structure (for each, while, do until) using only if and goto.

There is no need for the more sophisticated concepts to be part of the implementation.

The real problem is that while DDD may look pretty on a diagram no-one has come up with an elegant way to translate these concepts to code.

I used to be a big fan of generating code from models, but, now I have many doubts. The model is now source code, which needs to be under the control of the implementer/programmer if you want the system to work and perform well, however, the designers and modelers are used to hacking the model and traditionally have no concerns about any implementation issues. In effect the model which used to be a communication tool and the interface between designers and developers has become a battleground between the designers who want an elegant and accurate description of the requirements and the developers who need a precise and often quite ugly model to generate efficient code.

Licensed under: CC-BY-SA with attribution
scroll top