How to identify and fix an anemic domain model

CRUD applications tend to involve classes with many accessor methods and very little business logic, the behaviour being implemented at a higher level in manager (or god) classes. This usually signals that the domain model is anaemic. Many developers know the symptoms, but few know how to actually resolve the problem.

I have been suffering the same frustrations myself as I write classes that seem to have no responsibility other than to write and read attributes. OOP is not only rendered futile in such cases, but the amount of code that needs to be written also increases as I have to write classes that are effectively nothing more than data transfer objects and manager classes to act on those.

Through unit testing and refactoring, I have finally managed to develop a few simple rules to identify when a domain model is anemic. Without these two practices, it would have been just as difficult as many others are finding it.

Unit testing helped by forcing me into writing the “usage code” before implementing the classes. By first writing tests, I get an idea how the interfaces of my domain model will be used and can quickly flag up anything that seems out of place or redundant. For example, consider a simple Account that has the following responsibilities:

  • Represent a user account
  • Hold information about a user (ie. username, password, email address, status)
  • Used for authentication

This class seems very dumb at first, and one is tempted to implement only getter and setter methods as the interface.

Now, say we write a unit test for user authentication. What most people will probably do is this:

This, in the unit test, should immediately signal that the model is anemic. Here, the responsibility for checking that the input password is valid is handled by the calling code. However, the Account class is supposed to take care of this.

The fix is to refactor the unit test as follows.

Now, the behaviour is encapsulated within the Account class, making the implementation of the “authenticate user” use-case more robust.

There are many such small refactorings that can be performed on one’s code in order to make classes richer and reduce the symptoms of anemic domain models. One has only to write good unit tests and refactor whenever one thinks that things can be written in a better way.

I follow these principles:

  • If calling code reads an attribute from an object to then act on that piece of information, the behaviour should be moved to the object.
  • Getters and setters should not be systematically implemented; instead, write setters and setters only when unit tests indicate that they will be needed.
  • If there are chain method calls on an object, this indicates that the object is lacking some behaviour.

I am sure other programmers have their own personal ways of resolving anemic domain models. I would be very interested in reading what techniques others use.

Developing web applications with RIFE

I am using a little-known, yet very powerful, framework called RIFE. I discovered it when I came across a heated discussion between Geert Bevin, the author of the framework, and the Ruby on Rails camp.

What I like most about RIFE is the separation between presentation and logic, and the ease with which raw HTML code can be manipulated using Java code. This provides the foundation for creating visual components with little difficulty.

Templates are simple HTML files interspersed with RIFE tags. There are only four tags: the placeholder (or value) tag V marks a location on a page where content can be inserted; the block tag B marks a region of contents that can be manipulated as a unit; the directive tag I allows inclusion of templates; and, the default block tag BV identifies a block of content as the default one to be rendered at a placeholder location. Any HTML code enclosed within any of these tags can be manipulated by code, which allows for interesting effects. For example, a block of text can be marked as an error message and displayed at a specific location whenever that error occurs; similarly, one of several blocks of text in different languages can be displayed according to the user’s chosen locale. As would be expected, the RIFE framework already provides such pre-built components.

The ease of developing components in this way puts RIFE ahead of most other frameworks. In JSF, for example, visual elements are rendered by Java code, which is a rather un-natural way of developing web pages; in RIFE, visual elements are created with raw HTML code, and are interspersed with the template tags so that they can be manipulated by a backing Java class.

However, RIFE has much more to offer: a persistence subsystem, a CRUD rapid application development module, automatic validation, etc. But, perhaps even more important, RIFE has a dedicated community that is constantly growing as new users realise the productivity gains to be derived from the framewok. Geert Bevin is very active in the community, always taking time to listen to his users’ suggestions and help them. With so many web frameworks available nowadays, all following the same principles, RIFE comes as a breath of fresh air.