Friday, September 28, 2007

Never Start With the Data Model

My bias is for object oriented design and domain modeling. I am convinced that you don't build great software by starting design with a data model. I think starting with the data model is just about the worst idea and pretty much guarantees mediocre software. The best systems start with a domain model and work through the various layers of the system down to the database, not the other way around.

The database should be left until as late in development as possible. Experience shows this is not the case because creating the database is usually one of the first things on a project task list. Instead we should be asking how soon do we really need a database? The unit tests will be better and faster when they don't need a database. You know that data access should be encapsulated behind an interface. Why not leave the database until we know what the data requirements of an at least partially working system are?

Honestly, I can't think of a harder way to try to conceptualize a system than through a data model. Do your users understand a database schema? Is a database schema the model of your system you want to carry around in your head? Great software requires a model that can be used to communicate with users, developers, product owners, and domain experts. I don't think a data model is how any business person conceptualizes their business processes. What you need is a consistent coherent domain model that can can be used to make sense of a system at any level. You must be able to "peel the onion" to discover details as needed. Design by data model immediately forces all the nasty gnarly implementation details front and center. It is a well understood user interface design principle that bad designs expose details of the data model via data entry screens. The worst designs percolate the data model from top to bottom.

The best software solutions model a problem in the problem domain. A data model is a solution in the database domain not the problem domain. So why is the database schema where design so often starts? Maybe it's the mainframe mentality in big corporations, or naive developers who don't really understand object orientation, or just a general ignorance of object oriented design and domain modeling. Eric Evans wrote great book on domain driven design that is not as widely read as it deserves to be. In that book he talks about the "ubiquitous language" of a software project -
"A domain model can be the core of a common language for a software project. The model is a set of concepts built up in the heads of people on the project, with terms and relationships that reflect domain insight. These terms and interrelationships provide the semantics of a language that is tailored to the domain ..."
I don't see such a language ever coming from a data model.

What prompted me to write this was a post touting the new release of an "active record" object relational mapping framework for Java and some controversy it generated in this post. As you can probably guess, I'm not really a fan of the active record design pattern. But reading the posts and the comments, and knowing how popular Ruby on Rails is, it's clear that lot's of developers are very big fans.

I don't get it. Maybe it's because active record is so easy to understand. I suppose active record might work for small systems. But I would never want to use it on any even moderately sized enterprise software project. I see enough ugly code, highly coupled, tangled classes, and mangled hierarchies without database access code mixed into my business classes and immediately coupling my design to the database. I shudder to imagine the maintenance headaches it would cause. At least I'm in good company -
"Another argument against Active Record is the fact that it couples the object design to the database design. This makes it more difficult to refactor either design as a project goes forward."

Martin Fowler, Patterns of Enterprise Application Integration
"In an object oriented program, UI, database, and other support code often gets written directly into the business objects. Additional business logic is embedded in the behavior of the UI widgets and database scripts. This happens because it is the easiest way to make things work, in the short run.

When the domain-related code is diffused through such a large amount of code, it becomes extremely difficult to see and to reason about. Superficial changes to the UI can actually change business logic. To change a business rule may require require meticulous tracing of UI code, database code, or other program elements."


Eric Evans, Domain Driven Design

I hope the fans of active record know what they could be getting themselves into, but as usual I doubt that is the case.

Wednesday, September 19, 2007

There Aren't Any Rules

I know a lot of programmers won't agree but there are few, if any, "rules" for writing good code. It doesn't matter what platform or language or type of software you are writing. If you think someone can hand you a set of rules that you can follow to write good code you are mistaken. I try not to call anything a rule anymore. Now I call them guidelines or principles. The difference is that a guideline needs to be interpreted and judged to know when it should be applied. A guideline might also apply to more than one case.

Sorry, but I reserve the right to change my mind tomorrow about what I told you today was the right thing. This profession is too young, changes too fast, and is too much of a craft for rules written in stone. I've been doing this long enough to know that many things we consider best practices today are likely to change tomorrow. Remember hungarian notation? At one point you would have flunked a code review if you didn't use it, now you'd be more likely to flunk if you did. How about object oriented design? I remember when inheritance and polymorphism were going to save the world. Now too much inheritance is a sure sign of bad design. How about unit testing? We're still discovering the best techniques for things like mock objects.

Much of what makes good code depends on situation and context. Michaels Feathers says it very clearly -
"Good programming is contextual. Practice is contextual. We can articulate rules about how to use language constructs correctly, but they're just guidelines. Context is king."

When Good Code Looks Bad, Michael Feathers
I'd like to add that it is also about having the knowledge and judgment to know which guideline to apply when. There aren't any shortcuts, it takes judgment, practice, and study to write good code. Becoming a good programmer is hard work and you won't be one by following a set of rules. But you might become one if you practice and study the art of programming.


Wednesday, September 5, 2007

Metrics To Improve Unit Testing

At Test Often Joe Ponczak lists seven metrics that you can use to make your methods more testable, "Seven Metrics to Improve Your Unit Testing". Experienced unit testers will probably be familiar with the metrics but it never hurts to review. I mainly mention this because it is the blog for CODIGN Software which makes some nice reasonably priced Eclipse plug-ins for writing JUnit tests and analyzing code coverage.

p.s. I sure don't like the white on black color scheme on the blog though.

Tuesday, September 4, 2007

What makes software so hard?

Great article in the August issue of The Rational Edge, "What makes software so hard?". I have been convinced for some time that software is a design and not a manufacturing process. The article clearly describes the difference in explaining where in each type of process lie -
"On the other hand, for software projects, the relationship between
architecture and design versus production is not only inverted, but in
fact approaches infinity: since the production or manufacturing costs
for software are almost nil, almost all cost for a software
project comes from the workflows dealing with the creative parts --
that is, the invention and design of software."
Another great quote is the author's comparison of software to writing a novel. The metaphor fits so well -
"In a sense, creating software is far more closely related to writing a novel than to any traditional engineering effort -- an author is free to construct whatever type of story, limited only by his imagination and whatever facts may be necessary to the narrative. Furthermore, the author must construct the architecture of the story in his head, and to make sure the design and implementation of the story is consistent with the overall architecture. The quality of the author's product is to a high degree based on whether he succeeds in keeping the details of the story consistent with the architecture."
It is the notion that software is like manufacuring that has really turned me against big process improvement efforts like CMMi that are pushed from the top down. Anyone in a corporate environment has likely lived through at least one such effort. They usually seem so to be attempts to create predictability that does not exist in software and turn developers into interchangeable pieces that can be shuffled around a Gantt chart.