A Single Deployment Target is not a Monolith

Since the dawn of software architecture, we mostly knew that ‘Monolithic Architecture’ was more or less a synonym for ball of mud architecture. It mostly referred to code which was so entangled and coupled that it could not be separated out into components (or layers, or modules, or libraries, or equivalent). God classes, lack of information hiding, a change in one place means 20 other changes. That kind of thing. A failure of Modularity.

Recently the term Monolith has been taken to mean having a Single Deployment Target at runtime. This is a quite different meaning.

If you think that Monolith as described in para 1 above is the same as Monolith in para 2 above, then I suggest that you have confused, not separated, your concerns.

This is easy to understand if you are comfortable with architecture views. The para 1 definition is about the logical and (in 4+1 lingo) development views: the structure and relationships of classes, components, packages, and other kinds of modularity. The para 2 definition is only about the runtime deployment view (in 4+1: physical view).

The point is that you are at liberty in pretty much any operating system, runtime or language devised in the last 30 years, to structure your code and components as carefully and modularly as you like, whilst choosing your runtime deployment scenario independently of that modularity: it’s okay for 2 uncoupled components to run on the same machine. Honestly. *nix does it all the time. Ooh, so does Windows. And .Net and Java and Android and iOS and ….

The CTO at intilery.com showed me a couple of years ago how their server codebase can be deployed as either a single .war for a single webserver or split as separate .wars for separate machines by flicking a switch in the build config.

It’s not rocket science, it’s Separation of Concerns: the codebase is not the runtime.

DistributedMethodCallError: The belief that calling across a network is better than calling within a process

Distributed Method Call Error
The belief that methods and functions communicating across a network is somehow better than communicating within a single process on a single machine.

Process this error by politely throwing a verbal exception, inquiring as to what, exactly, is better. And then explain how the answers you’re getting back are the wrong answers.

Here are templates for the three main areas on why a distributed architecture does not make X better:

If X is one of: Response
Separation of Concerns, Coupling, Cohesion or similar But X is not primarily about deployment scenarios, so distributing your deployment does not improve X.
Reliability, Performance, Robustness or similar But as you’ll know from the Fallacies of Distributed Computing, if not from bitter experience, distributed computing makes things harder not better.
Deployability, continuous deployment or integration But deploying to multiple hosts is harder, not easier, than deploying to a single host.

Yes, there are problems for which distributed computing appear to be part of a solution. Redundancy as a reliability tactic appears to push you to distributed computing. So does horizontal scaling as a performance or capacity tactic. But these things are done extremely well at the infrastructure level by a black box: a load balancer. Notice that load balancing does not force a decision on whether each instance of your application-or-service is deployed entirely on a single box or is distributed.

So if you think that microservices or any other form of distributed deployment address issues such as dependency management, coupling, cohesion, continuous deployment, avoiding domino failure, then may I put it to you that you have confused, not separated, your concerns. In 4+1 terms, you may be confounding your physical and process models (i.e. the runtime models) with your logical & development (‘coding-time’) models. As Simon Brown pithily put it, “if you can’t build a structured monolith, what makes you think microservices are the answer?”.

PS

Yesterday I read a blog about ‘Monolithic’ architecture which said – with pictures and everything – that if your problem is how to carry on coding effectively (add new features, fix bugs, resolve technical debt etc) as the size and complexity of the code base increases, then the solution is a distributed deployment architecture with synchronous calls over http using xml or json.

I could weep. You manage your codebase by managing your codebase! Not by making your runtime deployment and threading models 50 times more complicated. This is what I mean by confounding the logical & development models with the process & deployment models.

PPS

If you’re not familiar with the 4+1 architecture views: The

  1. Logical view describes your classes’ behaviour and relationships; the
  2. Development view describes how software is organised and subdivided into e.g. modules, components, layers, and how they are turned into deployable artefacts; the
  3. Process view describes what threading and processes and distributed communications you use and the
  4. Physical view (though I’d rather call it the Deployment view) describes what machines run what code on the running system

The ‘+1’ is the use cases, or user stories.

When I first saw 4+1 I only really ‘got’ the logical view. As years passed, I realised that this reflected a lack of experience on my part. When you first do distributed or asynchronous computing, you begin to see why you’d want a process view and a physical (or deployment) view.

4+1 is quite long in the tooth and has evolved in use. There are other sets of viewpoints. Rozanski & Wood’s seven viewpoints show the benefit of a decade’s more experience. You may think 7 is a lot, but for a small or simple system some of them need only be a sentence or two.

Should a Software Architect Code? is the Wrong Question

It’s a long-running argument in software architecture and I’ve seen some quite emotional comments on it. But it’s the wrong argument. The right question is surely one about ratios:

“What ratio of non-coding architects to coders will work best for us?”

A ballpark answer to this question would follow logically from calculating how many full-time-developers worth of work results in an amount of non-coding-but-still-requires-deep-or-broad-technical-understanding-and-vision work that adds up to one full time job.

I suggest, based mostly on e-commerce & similar SMEs, something like:
(1) 25 developers’ worth of coding results in 1 full-time non-coding-architect’s worth of work.
(2) Every team needs at least one coding-architect-or-architecturally-competent-developer per 5 developers

Which gets me to a ratio of

1:5:25

for

non-coding-architect : coding-architect-or-lead-dev : developer

Architecture features plenty of non-coding work. Dealing with people, plans, business change, technical design, design decisions, frameworks, principles, patterns, catalogues, quality attributes… There’s more than enough of it if you have 25 coders’ worth of development going on.

So in a workplace with 100 developers, you may want a chief architect, 3 or 4 non-coding architects and 20 coding-architects-or-architecturally-competent-developers. But if you are chief architect or even CTO of a company with 15 developers, you probably still code.

There’s no right answer to the question, how much coding does a coding-architects-or-architecturally-competent-developers do. It can vary from nearly-nothing to 95% as projects progress. Perhaps 50% is a good average?

Discussions

There having been not one but two still-live threads on this on LinkedIn software groups since 2012:
LinkedIn – 97 Things Every Software Architect Should Know – Should architects continue coding … ?
LinkedIn – IASA – Should software architects code?
Anthony Langsworth’s 2012 post

Just Enough Design Upfront? How to draw the line between enough and too much

Earlier this year the term Hayim Makabee proposed the term ‘Adaptable Design Up Front’ as a way of pointing the way forwards between the Scylla of BDUF and the Charybdis of degenerating into a Ball of Mud.

Others have used the term ‘Just Enough Design Up Front.’ But what counts as just enough?

That’s the wrong question. Because ‘just enough’ is an insight that misdirects you. Design is not a scalar quantity like length. There is no amount of up-front design that is the right amount. The question is, what are the useful bits of design to do up front?

And this is what ‘Adaptable Design Up Front’ addresses. What you must do up-front is support the change and development to come — usually growth or change in functionality — whilst nailing down the things that ought to be fixed: the invariants which give stability so that developers don’t have to re-learn the system from scratch each day they come into work.

So the basic idea is this: you want just the up-front design that helps you to draw lines between things that will change frequently and things that remain stable over time.

So how to do it?

For the 3 minute kick-start, Hayim has an excellent set of slides to get you going. His ‘architecture vs interior design’ analogy and the idea of applying the open/closed principle at the architecture level hit that ‘brilliantly simple’ spot that make it all seem obvious in hindsight.

ADUF – Adaptable Design Up Front –Hayim Makabee

For more detail on designing for what changes vs. what stays stable, I seriously recommend Jim Coplien & Gertrud Bjørnvig’s under-rated book Lean Architecture: for Agile Software Development which contains decades of hard thought and wisdom. They know the pitfalls on the way first-hand and they can help you navigate them. More important, they show how to prioritise the human factors in your technical architecture. Which, as every architect knows, is what really matters.