Unfortunately it can be a relatively large annoying detail though
In my The Frustrated Architect presentation at GOTO Aarhus in October*, I talked about how there are a number of "classic" software design techniques from the pre-agile era that are being used less and less. For example, things like UML, class-responsibility-collaboration cards and component-based design. This is a shame because some of these techniques can complement an agile way of working and would perhaps prevent some wheels from being reinvented. If people don't know about these techniques though, how will they adopt them? I'll come back to this shortly but, first, I was intrigued by this tweet from Uncle Bob a few weeks back.
I don't necessarily disagree with this statement, although I like to see a software architecture grounded in reality, and that includes technology choices. Another tweet from Uncle Bob...
Again ... maybe, maybe not. Surely if there are some key technology choices that need to be made, then they should be made, right? Finally, another tweet...
Hmmm, if I don't or can't defer decisions, does this mean that I have a bad architecture? Shouldn't deferral be a conscious decision rather than a rule? All of this and the discussion that followed on Twitter intrigued me enough to stump up the cash for Clean Code Episode VII - Architecture, Use Cases, and High Level Design to see what Uncle Bob's perspective on architecture is.
Clean Code Episode VII - Architecture, Use Cases, and High Level Design
Now that I've watched it, what do I think? Well I'm really pleased to see coverage of a couple of things. The first is describing functionality through delivery mechanism independent use cases, where there is no discussion of web pages, screens, buttons, technology, etc. And the second is the follow-up technique where you decompose a use case down into a number of different classes, each of which has a distinct responsibility. These are entities (e.g. business objects), controllers (also known as interactors, which represent the actual flow of control described in the use cases) and boundaries (which represent an interaction with an actor through the "delivery mechanism"). What these techniques basically do is allow you to describe and implement a use case in a way that is completely independent from the way that the use case will be delivered. In effect, you can bolt-on a number of different delivery mechanisms (e.g. a web or console app) without changing the actual core of "the application", which is ultimately the functionality that is being described by the use cases. As I said at the start of this post, these are the sort of techniques that many people don't know about, so I'm really pleased to see them being communicated here.
I'm in agreement then?
Coming back to Uncle Bob's tweets, I can now see his perspective. Adopting this approach does allow you to defer technology decisions and from the perspective of the use cases, this technology stuff is really just an "annoying detail".
I agree that the boundary-controller-entity technique is a great way to design software because the result is a really nice separation of concerns, which ultimately leads to something that can be easily unit tested and extended in the future. This is all about partitioning and isolation. OK, so I'm agreeing with Uncle Bob then? Hmm, not quite.
Throughout the video, Uncle Bob says the following (which I've paraphrased).
The architecture of an accounting app should scream accounting. A web and console version of the same accounting app should have identical architectures. The web delivery mechanism is a detail.
This is repeated a number of times through the video and it's based upon all of the good stuff that I've talked about above. However, I find myself in strong disagreement with the message as a whole. And here's why ... because the word "architecture" is being used. At face value this might sound pedantic but let's consider for a moment what Uncle Bob is actually talking about by redrawing the above diagram. Let's imagine that you're building an accounting app that you want to deliver over the web. Security is important so let's break it into multiple physical tiers. And we need to store all of the accounting data somewhere, so let's use a database. How does that annoying detail look now then...
That's right, the annoying detail is actually a large chunk of the system and, for me, architecture is about more than just what's contained within "the application". Structure is very important, but what about that tricky stuff like non-functional requirements, the actual delivery mechanism (technologies, frameworks, tools, APIs, etc), infrastructure services (e.g. logging, exception handling, configuration, etc), integration services (internal and external), satisfying any environmental constraints (e.g. operations and support), etc. For me, this is what "architecture" is all about and *that's* "the whole enchilada".
If you don't have the video but want to get a feel for Uncle Bob's approach to architecture, take a look at the following links...