Wednesday 1 January 2014

Clean Code. "I do not think that word means what you think it means."

From my copy of Clean Code: A Handbook of Agile Software Craftsmanship (the paper copy of which (barely) predates my work in Rails. The highlighted paragraph is what I'd highlighted in the paper copy:

Active Record

Active Records are special forms of DTOs. They are data structures with public (or bean- accessed) variables; but they typically have navigational methods like save and find. Typically these Active Records are direct translations from database tables, or other data sources.

Unfortunately we often find that developers try to treat these data structures as though they were objects by putting business rule methods in them. This is awkward because it creates a hybrid between a data structure and an object.

The solution, of course, is to treat the Active Record as a data structure and to create separate objects that contain the business rules and that hide their internal data (which are probably just instances of the Active Record).

I've been increasingly uncomfortable with the way Rails encourages people to conflate the domain model objects with persistence in Rails' core component, ActiveRecord. Running across this bit again makes me think of Inigo Montoya from The Princess Bride: You keep using that word. I do not think it means what you think it means. Judging from my own projects and those I've participated in and observed on Github, the fact that ActiveRecord does not properly implement or encourage the Active Record pattern is a primary root cause of many bugs and much confusion and heartburn.

Happy New Year.


Tim Case said...

Giles Bowkett specifically talks about the difference between the name ActiveRecord and the pattern ActiveRecord in his book "Rails as She is Spoke". The gist of it is that Rails breaks a lot of principles of object oriented design and the overall net benefit is better than if it adhered strictly to OO principles and patterns. I agree with him. However, work in the Rails world is being done to separate behavior from data and you would probably be interested in seeing implementations of Rails using Robert Martin's Clean Architecture, DCI, or Hexagonal architecture. All of it is still pretty new but in all three you'll see separation of behaviors from data.

breen said...

There's an interesting discussion going on hackpad about alternate architecture patterns.

Ruurd said...

Having seen the concern subdirectories in a contemporary RAILS project and my understanding that persistence really is a concern when dealing with model state persistence isn't it possible to move away from direct inheritance (which is at least suspicious from the OO point of view) towards mixing behavior?

Other than that, there is enough leeway nowadays to do decoration when dealing with model objects. The draper gem comes to mind.

Ruurd said...

Nah. Not 'mixing behavior' but 'mix-in behavior'.

Unknown said...

@Ruurd — Modules are inheritance in Ruby. They look and work (to the not-overly-inquisitive developer) to be "mix-ins" that leave the single-inheritance hierarchy pristine, but that is an illusion. There are several excellent write-ups on this scattered about the web; James Coglan has an excellent one here.