Monday, June 28, 2010
Simplicity vs. Adaptability
When dealing with code, and code architecture and design, there are lots of factors which have to be weighed to determine what the best way to go is. The popularity of Ruby on Rails in the blogosphere and the conference circuit has begun to shift the conversation about these factors a bit. When we were focused on Java and .NET we spent lots of time talking about The Gang of Four, Fowler, SOLID, and SOA. These days we seem to be talking more about BDD, "simplicity", terseness, and productivity.
I think this is a good thing, but I also think it's because we have finally realized that we are writing a whole new class of applications now. Back in the day, people were focused on BIG and COMPLICATED applications for banking and shipping and other complicated industries. We are still doing that kind of work today of course, but we've added a whole new class of application that didn't exist before: small and simple web applications. These websites are actual applications, not just brochure sites, so they have logic and models and all the rest. But their domain tends to be small, and the rules tend to be much simpler.
It seems like what we've learned as an industry is that all the patterns and practices that have been developed for dealing with large and complicated systems aren't necessarily needed for smaller web applications. But many of these things have become so ingrained in the way that we think and the way we approach problems that it can be a rather jarring shift to throw them out.
Ultimately this comes down to a question of Simplicity vs. Adaptability.
Simplicity: straight forward, few layers
Adaptability: Guards against change, includes more abstraction
Are These Really Opposing Characteristics?
The best possible design would be one that is both simple and adaptable, but usually simplicity and adaptability are opposing characteristics. This is because to make something adaptable, you tend to have to build in more layers and more abstraction, and that necessarily makes it more complicated.
For example, the Active Record pattern is simpler than the Data Mapper pattern. But the Data Mapper pattern isolates your models from changes in the database and vice versa, as well as removing all persistence knowledge from the models themselves.
There is a fun catch-22 here though. If your abstractions can serve as effective methaphors, you can begin to ignore the complexity the abstraction hides from you. This allows you to think about the system in a much simpler way, even though the details of it are very complex. But its debatable whether we would call a system like this "simple." For example, websites written with Ruby on Rails tend to be simple, but I would not describe Rails itself as simple.
Simplicity is exemplified by DHH, creator of Ruby on Rails
Adaptability is exemplified by Jeremy D Miller, creator of FubuMVC
Just look at the difference in their tag lines:
"Ruby on Rails is an open-source web framework that's optimized for programmer happiness and sustainable productivity."
FubuMVC: "Compositional, compile safe, convention-based configuration for complex web applications."
The focus of these two projects is clearly different, and its hard to argue with either one. Both can be used to create "simple" web applications. But Rails is very focused on a certain subset of simple web apps, where Fubu is more interested in being adaptable in order to allow you to tailor it to your needs.
There is a trade-off here. And which trade is right for your project is one of the most important decisions you have to make. As I wrote recently, the factors you have to consider in this trade-off frequently aren't even technical! So we really need to understand how diverse our industry has become, and we need to understand the context in which these things are being discussed.