ActiveRecord pattern, so what?
The Active Record pattern has a lot of publicity recently thanks to the Ruby On Rails and Grails wave. A definition could be: an object that encapsulates both data and behavior (ie a database row and it's data access logic).
A bit of history
I was asked recently my thoughts about this pattern. First of all, if someone still remembers EJB 1.0 and 2.x Entity Beans, this was a perfect example of the Active Record Pattern... and a successful failure. Some of the reasons for this failure was the tight link between the data and it's access logic: Serialization issue, data tight to a persistent technology etc etc.
Statically typed languages
To me the ActiveRecord pattern is not well suited for statically typed languages like Java, hence the raise of another pattern : DAO (aka DAL in the .net world). It prevents the hard link between the persistence technology and the actual data representation.
Dynamic languages
Dynamic languages (and to a certain extend AOP) have the nice ability to decorate an object with additional features on the fly, without linking it "the hard way": you can then easily reuse your domain classes out of the persistence context.
Grails uses such a behavior to add CRUD operations transparently to your domain model (with quite complex Querying capabilities).
One still face a problem, what if the application developer needs to add a more complex persistence operation (esp a query), he will end up "hard-coding" the function to the domain object and we're back to the issue faced by statically typed languages... unless you create a DAO object. But then, your persistence operations will be split between your implicit domain model methods and your DAO: another code smell.
Dynamic DAO
As you can see, I'm not keen on the ActiveRecord pattern (out of simple applications), but I really love the simplicity of GORM (the Grails way). The solution is a dynamic DAO. JBoss Seam already generates very simple yet powerful DAOs benefiting from Java Generics. If you combine that with a dynamic language, you can have the best of both worlds.
class UserProcess {
@In UserDao userDao;
void create(String firstname, String lastname) {
if (userDao.countByFirstnameAndLastname(firstname, lastname) == 0) {
def user = new User( "Emmanuel", "Bernard" )
userDao.save user
}
else {
throw new UserAlreadyExistException()
}
}
}
Note that countByFirstnameAndLastname and save can be dynamic methods à la GORM.
Conclusion
I'm not a big fan of the ActiveRecord. For static languages, I would use the DAO approach. For dynamic languages, I did not make up my mind but a DAO on steroids seems very promising.
Comments