A refactoring transition from an anemic to a rich object model is possible, painful, and—at least for me—necessary.
I'm currently working on an anemic, Struts based J2EE POJO solution that is a few years old. As I understand it, it goes by the book, with class name patterns like OrderLogic, OrderDTO (Data Transfer Object), OrderDAO (Data Access Object) and Hibernate annotated OrderVO (Value Object). They implement an anemic model with logic classes and DAOs containing purely code, and DTOs and VOs containing purely data, close to a Table Module architecture, with VOs acting as data records, which is basically a well structured Transaction Script model: Plain old data based, structured programming.
Oo freak as I am, this frustrates me, especially as there is leakage of responsibility between the classes. On the positive side, there are some good architectural efforts, with OrderLogic managing the high level request for orders, delegating the pure db-access to the DAO. Operations on the resulting OrderVO is mostly also found in OrderLogic, but also elsewhere, for instance in Struts Action classes, as well as in other XxxLogic classes. And there is duplication. And, surprise, surprise, all this is also to be expected, "by the book".
For my brain to function properly, I need to apply the SRP and the IE principles, so as to find my operations close to my data. I also need to support the changes I make with TDD. All this requires a rich, non-anemic domain model. Successively, instead of one big folder (and namespace) common for everything relating to say customer and order management, I create folders for three architectural layer, like Presentation Layer (common.PL), Domain Logic (common.DL) and Data Access (common.DA). To start with, PL contains the DTOs and related stuff, DL contains the new domain objects and other domain layer logic, like class repository objects, mostly refactored out of the Logic classes. Finally, DA contains DAOs and DVs.
At least, that's what I thought.
Actually, after some refactorings, I am heading in a slightly different direction. In my search for how to design my domain objects, I have investigated three different models:
- inherit from the VOs
- delegate to the VOs
- promote the VOs to rich domain objects
When time allows, I will add a figure here to explain this more clairly. For the time being, I am curious to see where this strategy takes me.