The subject is a bit broad… so, let me explain what is this about. I’m trying to show a sample implementation of a system, modeling it using the Object Oriented Paradigm. The system is an online book store. The source code can be found here and the implemented requirements(1) here. I developed this using the Java programming language, Hibernate for persistence, Spring and Spring MVC.
The main purpose of this is to come up with a good object oriented model, trying to avoid any impact on it with implementation stuff like persistence. The persistence is a cross-cutting concern that should not affect our design. I did not spend time on hibernate optimization, or Spring best practices, you will find a lot of places out there about these. Creating a good object oriented model is not an easy exercise and there, is where I spent most of the time while develop this. The implemented model is based on a mini-market metaphor.
With this, I tried to avoid a very common mistake where model objects are full of getters and setters, but not behaviour. The business logic is spread across methods outside the model, and the model objects are used as data structures (i.e.: struct in C or record in Pascal). This is clearly procedural programming. And this is more evident when you have to provide persistence to your system. This symptom is called anemic model. OOP is domain driven by definition, and the responsibilities are more important to identify objects (or the only way others may say) than data.
The implementation consist of the following modules:
tntbooks.model: Here are the objects that do the stuff, modeling the mini-market. All the business logic is here. This module does not depend on any other module within the system (any number of front ends can consume this module and any persistence mechanism can be plugged for this model, without changing any line of code). The model is tested using just JUnit (it was not needed to use any mock framework).
tntbooks.api: Here are the objects that belongs to the interface. that deals with the non object oriented world. Deals with URLs, requests and response.
tntbooks.persistence: Here are the objects that deals with persistence and hibernate (in this case). It implements two interfaces from the model module.
core: This is a module that can be reused in other domain. It was created after some refactor to make the Cart object more reusable for other domains, and not only for the tnt book store application.
Another interesting thing to highlight here is the implementation of an Hibernate interceptor that I had to do (you will find it on the tntbooks.persistence package). This was needed to inject transient object to persistent object. The persistent object Customer talks with the Cashier transient object. When I retrieve a Customer object from the database, this interceptor inject the Cashier collaborator transparently. This makes client code cleaner, due to I don’t have to duplicate code to inject the Cashier every time I get a Customer from the database.
I also tried to hide as much as possible all the methods that were only required by Hibernate: getters, setters and default constructors. That is why I used the private keyword for those, in order to just expose the business responsibilities of the objects that belongs to the tntbooks.model package.
If you want to give it a try, I develop this using Eclipse, Tomcat 6.0, Ivy for dependency management (with IvyDE for Eclipse), you will find all the dependencies in the ivy.xml file and Apache Derby.
I’m happy to hear other thoughts around how to model these requirements or any suggestion that you may have.
(1). The requirements are taken from (with some modifications I made) a TDD course I took in 10pines.