Fractal Amplification (1)

Coding, most of it anyway, is encoding

9 minute read

Tags: ,

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
	print chr$(a);
next

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:

"hello world"

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.

Sure, for-loops and conditional statements will be around for the foreseeable future, but it’s what they are looping through, and being conditional on, that’s changing. In traditional OO languages, you design class hierarchies and instantiate examples of those classes, which then interact with one another and the outside world. But in looser so-called duck-typed languages, like Ruby and Javascript, everything is an object and everything is extensible for your own ends. In Javascript, if you want a mouse click on an image to initiate a navigation to a preset page, you could create an anchor tag, with an image inside it:

<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">
<script>
	var imgref = document.getElementById("myimage");

	imgref.destination = "http://xyzzz.com/destination";
	imgref.onclick = takeMeTo;

	function takeMeTo()
	{
		location.href = this.destination;
	}
</script>

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.

The Javascript package Prototype, extends not just elements, but strings and arrays with a wealth of useful and elegant functionality. Prototype and the related Scriptaculous are domain specific languages for client-side development. They use Javascript’s ability to adapt and extend itself, and evaluate itself, to make a richer collection of document object model elements (nouns) specific to that domain (form tags, paragraphs, css classes, tables, etc). The verbs to these nouns can be applied to any item that has the requisite property, they are not methods on the classes per se. For example, hide, which makes an element disappear, can be applied to anything that supports the display css property.

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

my_age.times do
	"happy birthday"
end

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.

It’s worth pointing out here that there’s nothing to say you have to use Ruby, or Javascript, or Lisp to build in this way. Features like weak typing, introspection, reflection, closures, etc all help, but with effort most major languages can do it.

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.

Created: