Many of the constraints I have in my day-to-day job as a developer come from this mysterious world of the software architect. After listening to Martin Fowler on the Ruby Rogues podcast talk about his book Patterns of Enterprise Application Architecture (PoEAA), I decided to pick up a copy (i.e. I ordered it from Amazon) and read a bit more into architecture. Not understanding the domain very well, I also watched a few talks and read a few different articles trying to get a feeling for the important aspects.
This post goes over a bit of Fowler's book, goes over some of the different opinions on software architecture, and tries to answer the questions "what is software architecture?" and "when should you be an architect?"
Architecture is Important
architecture boils down to the important stuff - whatever that is. -- PoEAA
Fowler describes architecture as the important decisions in a project. The kind of decision that would require massive effort to change down the line. It is comprised of decisions that
developers wish they could get right early on because they're perceived as hard to change. -- PoEAA
If you can imagine a request to change something in an application and your answer is "it will require a major change to the system", that difficulty was probably caused by an architectural decision in the past.
Decisions like which persistency patterns should be used, how objects will interact with remote systems, how domain logic is separated in the system will significantly impact the way the system is developed. They will also have ripple effects into other areas like performance, maintenance and design.
It is important to understand what an architectural decision is, and what it looks like. Spending a lot of effort making good decisions for unimportant aspects of the application is time wasted. However, making important decisions lightly and without an appreciation for how hard it will be to change later, may cause years of pain.
Conveying the importance of architectural decisions can be difficult because some people dislike software architecture as it seems Waterfall-ish. Uncle Bob Martin put it like this:
there has been a feeling in the Agile community since about '99, that "architecture is irrelevant, we don't need to do architecture, all we need to do is write lots of tests, and do lots of stories, and do quick iterations and the code will assemble itself magically". This has always been horse shit!
Just because you are planning ahead, does not mean that you are somehow violating agile development principles, just don't go overboard.
When to make Architecture Decisions?
Fowler states that architectural decisions should be made towards the beginning of the project. Others, like Kent Beck and Uncle Bob Martin, say you should defer making architectural decisions until they are absolutely needed.
In Fowler's article Is Design Dead? he compares his "cowardly" approach of making decisions early to the "aggressive" approach to defer decisions until necessary. Fowler argues that you may have a broad understanding of the domain from experience, and you can make architectural decisions early in a project, with the understanding that it might be necessary to change them later.
In Uncle Bob's talk Architecture the Lost Years from Ruby Midwest 2011, he asserts that decisions like which framework or database to use are merely details of an application and should not dictate the way in which it is designed. He then gives an example where by deferring the decision of which database to use, he was able to create a fully functioning application without any database. Finally, when a database was eventually needed, they were able to quickly add it because of this deferred decision. Uncle Bob's advice is:
A good architecture allows major decisions to be deferred
This battle between deferring and upfront architecture is something that I deal with day-to-day. For example, the first major decision in most of my projects is what framework to use (Ruby with Rails or Sinatra, Node.js with Hapi or Express), which:
- according to Uncle Bob, the decision should be deferred until it is necessary to be made, with the understanding that a price may need to be payed for adapting the existing project to a framework
- according to Fowler, existing experience should be used to make the decision now, with the understanding that at some point a price may need to be paid for changing the framework
Jim Coplien in a discussion with Uncle Bob (video here) gave a nice middle ground where you should:
capitalize on what you know [and] take some hard decisions up front, because that will make the rest of the decisions easier later.
That is, make the decisions you can now, and instead of guessing defer the other decisions until later, when more information is available.
How I break down these views is:
- If the domain is not well understood or I have little experience with it, I will take Uncle Bob's advice and wait to make any architectural decisions
- If I have experience with a domain, then I will take Fowler's advice and make architectural decisions with the understanding they may need to be revised later
Software architecture is a complex topic, and I still have much more to read and learn. In this post I looked at the kinds of decisions, and when to make them. I did not cover the hardest topic, how to make the best architectural decisions with the available information. I think that topic would fill many books.