My favourite definition of technical architecture is simply that it’s the software delivery discipline that attempts to ensure the non-functional and strategic requirements are met.
And further, I see the strategic and non-functional requirements as essentially the same thing. Whenever we talk about strategic requirements we’re really talking about future capability - a description of support for future needs, whilst behaving in future-compatible ways, that are generally appropriate for the kind of future we’ve predicted. In line with these thoughts are expectations about the way the system will perform even if it’s not called upon to meld with some future state - support more active users, remain resilient, secure, etc. All architectural thinking starts with some narrative about the future (“if we don’t structure the code this way it will be hard to maintain”, “if we don’t use this technology it will be expensive to scale”, etc).
So the corollary of that should be that non-architectural aspects are largely functional and tactical, and in fact, they are: business analysts, subject matter experts and testers deal mostly with whether the solution does what it’s meant to do at launch, and project delivery people keep an eye on budget and timeliness up until that date. That leaves software developers as the link between the two, trying to deliver the perfect strategic solution under tactical pressures.
I don’t believe all coders can become good architects, but I do think all good architects should code. Not necessarily in their day jobs, but certainly on their own time - seeing architecture in its proper context, and understanding how code scales up to deliver it, is fundamental to making that tactical-to-strategic crossover work. Governance may provide the process and forum to resolve variances, but getting it right beforehand can certainly reduce this overhead and make for a more harmonious relationship between the short and long term perspectives.
This two-part article looks at how small and elegant ideas in code can scale out to become part of the thinking that makes architecture work - a concept called Fractal Amplification. It’s a rather fiddly idea to get across (as I am right this minute discovering) but what I hope to show is that, from hard-core source code to hand-wavy enterprise architecture, better systems can be delivered if you adopt a certain way of thinking. Let’s start at the bottom then, and see what pattern emerges.
Writing software can be loosely categorised into three areas:
- Understanding logic structures and basic flows
- The ‘gotchas’ and patterns of developing useful applications
- And what we’ll call ‘encoding’ for the purposes of this article
Logic structures in most languages can be picked up in a few hours. It’s not hard to write a for-loop, ‘hello world’, or conditional in a previously unknown software dialect. I think we all remember a phase of telling everyone we could code in twenty eight languages, when what we really meant was that we’d written a dozen or so lines in each. An old favourite of mine was this:
for a = 0 to 255 step 1
It’s a BASIC construction that walks through the extended ASCII character set, printing out each value in turn. It worked great on Sinclair and BBC computers, but when I typed it into our school’s Research Machines kit, to show off to my Computer Science teacher, it crashed the VDU. Some of the low numbered characters in the set are non-printable, and whilst some machines happily handle this, the RM box wasn’t happy. One quick reboot later, and we were all friends again, but the story is a neat segue into those odd gotchas and patterns that take much longer to become expert in.
Way back in 2002, Joel Spolsky wrote an article saying basically that 90% of what you need to know about a software language you can pick up in the first week, but the other crucial 10% will take years of practice and experience. I’d change that 90% to something closer to 70%. If you take a richly-jewelled language like Java, it can take months just to learn the practical implications and best-practices of the basic packages. It’s the reason there’s such a wide spread of quality in the field. Even Rails with its convention-over-configuration mantra, designed to make web development quicker, can have you discovering ever more elegant idioms, to make your code more extensible, almost indefinitely.
With the advent of domain-specific languages, I’d suggest that this experience becomes even more important, because there’s not much in the core language except the ability to extend it, according to your own business patterns. In Ruby (and Lisp) a ‘hello world’ can be written:
There is no code to speak of, it just evaluates itself, which rather dramatically allows you to write it in itself. So the patterns and gotchas aren’t so much in the language, and the way it’s applied in certain circumstances (they’ll be unique to your domain), but in the way you encode your designs into the language.
<a href="http://xyzzz.com/destination"><img id="myimage" src="my image"></a>
but you don’t have to. If it fits with your strategic plans, you could encode the destination into the image element in the DOM, and have a neat onclick event handler function:
<img id="myimage" src="/images/myimage.gif">
var imgref = document.getElementById("myimage");
imgref.destination = "http://xyzzz.com/destination";
imgref.onclick = takeMeTo;
location.href = this.destination;
They would have to be some pretty image-centric strategic plans, clearly, but your ‘logic’ and your presentation are structurally more separate and the ‘image’ in the DOM is now an extensible container for all those business plans you don’t yet know about.
Don’t get me wrong. I am not suggesting bespoke extensions to standard elements is always the way to go, what I’m saying is that even in this simple example you can see that how you encode your properties, and where you encode them is critical for future development. If your business domain supports the use of property-rich image-centric objects, you will write less code and have many more elegant options than if you focused on writing something that churns out HTML.
The example isn’t a great one because it’s a bit too simplistic. The essential difference between the two is that the second starts with a business concept (the image) and extends it with business properties (locations) and then acts on those properties with a verb (takeMeTo), whereas the first one just uses the document object model as is, and relies on something behind the scenes to generate it. To make major changes in the first example you’d have to update the generator function, but in the second you can add more properties, new verbs, on so on. Only if the business becomes less image-centric will the second example start to become harder to update, but that’s OK because if the business undergoes major change, it’s more acceptable for the supporting software to, small business changes that can be identified with new nouns and verbs should result in similarly small software changes. But, as I say, the example isn’t so hot, it’s just one that fits into a very small space and is understandable by a wide audience. Let’s look at it a different way and then we should see our theme more clearly.
What’s important is that the line between program logic and data is very blurred, and not just in the conventional OO sense, and the relationship between business entities and the verbs that act on them is fairly loose. By just-a-bit-more-than-conventional-OO I mean everything is an object, and everything is therefore extensible.
my_age = 18
That’s a piece of Ruby. Note how my_age is a variable that holds the object (not the integer) 18, which has a method called ‘times’. And like all other classes, you can add you own properties and methods to it. You can also do this after objects have been instantiated, on the fly. Objects can get, or not get, these new features as you choose. Yes, it’s OO, but not as many know it, if base classes are extended in this way, then they can interact with user classes in many and varied ways, just as spoken language can take verbs and nouns and make new idioms, vernaculars, and constructs - because of its base flexibility.
There’s not even really anything very new here. The Model, View, Controller pattern has been around since 1979 and that’s pretty much all that’s being described.
The view is the representation to the external world. In a web application that’s HTML, but it could be a business document of any kind. The view not only provides information, but a window onto contextual actions that can be performed via provided business services.
The controller handles those action requests, receiving verbs and supporting information (list all orders, delete the user record with an id of 1234, etc).
The model is the gateway to other worlds - an abstraction layer onto the database where user and the order live, or a kind of portal into another layer of controller-views.
But we’re running ahead a little bit. As far as our code journey is concerned, logic flows are important but easy to learn, and patterns of use are where experienced people demonstrate their worth. But, more and more, the latter is being subsumed into a deeper, more lingual, less technical, concept of ‘encoding’ where action verbs and business entities are as loosely related as they are in spoken language, and extended in similar ways. Verbs are orchestrated through controllers that ensure they operate on their targets in the correct contextual manner, and changes to these target entities are abstracted through models, that are relevant and specific to the current domain but act as translators to others.
Now we have a pattern to play with, in the next instalment we’ll look at how it can be reused all over the place in architecture, from simple client-only apps to full service-orientation, and we’ll examine what these idiomatic nouns and verbs look like and how they provide for easier strategic change whilst being tactically quite straightforward to implement.