Tag Archives: software architecture

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

Why OO Business Applications Always Wind Up Splitting Methods from Data And Not Encapsulating Either

One of the main—perhaps the main—selling point of OO is Encapsulation. Which is actually two selling points. Firstly Information Hiding, that is, hiding the innards of a class so you can use it without needing to know how it works. Secondly Modularity, holding related data and methods together in one place. It’s the use of objects & classes to achieve these two effects that gives OO a large part of its flavour, distinct from procedural or functional programming.

The power this gives is the ability to model the domain naturally. This is power of OO. Given a business having customers with addresses, orders, invoices, products etc, we can model the domain – the entities and their relationships – very naturally in code by creating classes to represent them.

So as OO developers coming to line-of-business applications we expect to apply these techniques. We think about what should be private or public to each class, and we think about what responsibilities belong with classes, and what methods & data are needed to fulfil that responsibility.

The problem is, businesses don’t do modularity and information hiding. (Well they do of course, by being split up into business functions – sales, accounting, warehouse, customer services etc. Information private to one department is not usually available or even of interest to staff in another. But that’s not the level we’re interested in in a domain model).

Look again at our OO classes: customers, addresses, invoices, orderlines, products etc. These things are not encapsulated in business use at all. Firstly, there is no hidden information; when a business user goes to their information system to get information about a customer they expect just that: Information. No hiding. Secondly, information is all they expect. They do not expect the information system to model the customer’s ability to Walk() and Talk(). No methods – and so little modularity – are needed.

This is true of almost everything in a business’s domain model. From a business users point of view, it’s all just screens of information. Documents. And this – the humble document – is the heart of what we missed in our sketch of a domain model. The real thing we are modelling is not the flesh and blood Customer, or the physical Product they want to buy. What we’re really modelling in line-of-business apps is paper documents in a filing cabinet.

A piece of paper in a filing cabinet has no methods to model. It’s just a data-holder. An accurate domain model for a piece-of-paper-for-a-customer is just a list of fields or properties. You can wrap get() & set() methods round them if you like, but all you’re doing is adding boilerplate. (As an aside, a big advantage of computers over paper is much better performance in modelling relationships between those pieces of paper. A database can look up a customer’s order history much faster than a human with a set of filing cabinets).

So where are the methods in a business? They are largely in the business processes. (The phrase ‘business process’ is one that your business people use, which tells you that business processes should be part of your domain too).

To the business, a process is usually a sequence of actions done by a chain of people. In a typical business process, a piece of paper (actual or virtual) is passed around; information is updated on it, or on other pieces of paper; and very occasionally something is actually done, such as finding an item in a warehouse and putting in a box.

Which class in your domain is responsible for these actions? Probably none of them. You could create a WarehouseWorker class responsible for Pick()ing and Ship()ing the product, but you’ll quickly realise (unless your warehouse is staffed by robots for whom you are writing the control programs) that you can’t write any code that actually belongs in those methods. You can write code for UpdateStockCount(), to record the fact that stock is decremented; and you could write an UpdateCustomerOrderStatus() so that the customer services department can tell the customer how their order is getting on. Indeed, that’s probably exactly what’s being required of your system. But which class in your domain responsible for these actions?

If you think that the Customer class, or the Order class, is responsible for UpdateCustomerOrderStatus(), then you would appear to be imagining a piece of paper updating itself, which is not a normal responsibility for a piece of paper. (Either that, or you’re imagining the ghost of the customer coming on-site to keep track of their order. The real customer has no such responsibility. Their only responsibility at this point is to sit at home waiting for their package to arrive). In the world before computers it was probably the responsibility of the Stock Controller or Inventory Controller (yes, those are real job titles still held by real people) to do this book-keeping. So your domain model could/should include a StockController class with that responsibility.

Now ask yourself, what data do I need to encapsulate in the fields of a StockController class? The answer is almost certainly none whatsoever. You are not usually asked to model the real stock controllers’ working hours or height or physical strength in a line-of-business application. All you need to model is their ability to UpdateStockCount() & UpdateCustomerOrderStatus(). You need model no internal state.

This is typical of business process modelling. Business processes are nearly always stateless – all the information they need is given to them each time they are invoked. This is true for so-called ‘long-running’ processes too: the classes responsible for performing each step of the process are not responsible for holding state. Rather, they expect to have data (or ids/keys to look up the data) passed to it.

In short: ninety percent of the domain of a line-of-business application is usually correctly modelled as:

  • Documents holding data
  • Stateless public processes which receive these documents as their inputs

Because most of what you are modelling is paper documents (which do nothing, except record data) being worked on by employees (about whom you know nothing, except their ability to update the documents).

And that’s why data is not encapsulated in business applications, nor are methods and data held together in the same class.

Objections

But wait – surely we still have encapsulation and information hiding between for instance the UI layer vs data access layer vs domain model?

Yes, that’s right. The StockController exposes the fact that it can UpdateStockCount() but hides the fact (in fact, doesn’t even know itself) that this is achieved by writing to a copy of SQL Server installed on machine XYZ. A clear sign of concerns that should be separated at quite a high level is that they are semantically unrelated, that is, they speak a different language. The UI layer and the domain model know nothing of this ‘Sql Server’ of which you speak.

The point is rather that you should not be disappointed if it turns out that your domain model feels more anaemic than rich. That models the reality of typical business domains.

What about business rules & logic? They aren’t stateless business processes?

Also true. And the above line of thought need not be applied to them. (Does an abstract concept such as ‘business rule’ have state? Yes if it’s the-rule-as-applied-to-a-specific-case; no if it’s ‘The Rule’ in abstract).