Home > Uncategorized > Multidimensional Separation of Concerns

Multidimensional Separation of Concerns

Separation of concerns is a popular idea in software. Divide your design up into separate pieces that “know” as little as possible about each other, so you can think about them independently.

The most popular example given in discussions of this topic is a layered or “tiered” architecture:

Some tiers in their natural habitat: a block diagram

Some tiers in their natural habitat: a block diagram

If you ask someone how their design works, or more specifically what problem it is intended to solve, and they show you a picture like that, they’re showing you diddly-squat. There might just as well be boxes labelled Source Code, Compiler and so on. These are things that all applications have. It doesn’t tell you anything about their particular problem domain. A more honest, less pretentious diagram would have boxes like this:

An honest depiction of a problem domain

An honest depiction of a problem domain

These are the actual concerns of a real application – the very things its users talk and think about. The problem is, the users will likely change their minds about stuff like this. This is the foam and froth – I don’t mean to imply that users foam froth at the mouth when they talk; I just mean the nautical metaphor about rough seas. Several weeks into the project, someone will realise that we need to deal with FirstName as well as LastName, and so suddenly your diagram would be out of date. So people tend to draw diagrams of things that don’t change. Unfortunately that pretty much excludes everything specific and interesting about their own project.

They then structure their application according to the diagram. The diagram says that there are separate tiers for presentation, business logic and data access, and so that is what we end up with. The closest thing we can get to a complete diagram would be:

Separate tiers with duplicated domain knowledge

Separate tiers with duplicated domain knowledge

As a real world example, this could mean a presentation tier written in HTML and little bits of jQuery, and a business logic tier written in Java, C#, Ruby or what-have-you, and finally a data access tier consisting of an RDMBS wrapped in a suitable ORM, or something more fashionable like CouchDB.

The vertically stacked tiers look like well-separated cohesive units, which is nice I guess. But it’s not actually that beneficial, because they’re such well understood static concepts that we are unlikely to be that confused by them anyway, and nor are we likely to rip any of them out and totally replace them.

The real pain is what has happened to our specific domain concepts. They’re each fragmented into separate pieces for each tier. They exist only as analogous patterns that crop up encoded in different ways depending on the tier. For example:

<label>First Name <input type="text" name="FirstName"></input></label>
<label>Last Name <input type="text" name="LastName"></input></label>

That’s the presentation tier’s way of encoding domain knowledge. One aspect of the existence of a FirstName concern is that it crops up as a certain pattern with the HTML. But there will be similar manifestations within the business logic layer, encoded in a different language, and then in the data access layer, and so on. There isn’t a single statement anywhere that a FirstName is something we deal with; rather, each tier is structured in a way that (hopefully) matches up with the other tiers, and so they all contribute a different aspect to what FirstName consists of.

So on the day when someone realises we need to concern ourselves with a MiddleInitial as well, we have to visit each tier in turn and make a different kind of update to each one. And if we decide to remove an existing concern from the design, we also have to visit each tier and delete something (or possibly do something more complex).

This situation is sometimes called “cross-cutting concerns”. It’s a pretty poor state of affairs if all of your most specific and relevant concerns are forced to be cross-cutting in nature.

In summary:

The things that are most likely to require changes have been rendered unnecessarily hard to change.

It would be much more convenient if the existence of LastName was stated in one place. And then from that statement the system would automatically generate the necessary incantations in the various tiers. All it needs to know is what type of information LastName is. The type would encapsulate such things as how to represent the information in the user interface as an interactive value, using HTML, scripting, controls and so on, and also it would encapsulate some common operations required by the business logic such as retrieving or applying a value using a common persistent format, and of course the type would also define a way to map itself into the data tier (for example, the RDBMS data type to use).

The same type definition would then be applicable for both FirstName and LastName. Similarly for dates – what is true for one date field is likely to be true for another.

Here’s another diagram:

Domain concerns given priority

Domain concerns given priority

By inventing a system of types, in which each type encapsulates how a piece of information should be presented and stored, we can then describe the rest of our system purely in terms of fields, each of a specific type, along with appropriate business logic to operate on the information. We can then forget about the fine details of presentation and data access. Those aspects are driven entirely by the types.

We’ve now succeeded in achieving a separation of concerns between the tiers, just as originally intended. We can think about the domain concerns and their business logic without having to worry about the details of presentation and data access. That’s the whole point of a tiered design.

But you can only get to that point by considering the two dimensions involved: the technical concerns and the domain concerns. It is essential to prioritise making the domain concerns into independent, solid, several (in the old-fashioned sense) chunks. You need to be able to add, remove, rearrange and separately modify them safely and rapidly, because it is the domain concerns that carry the unique value of your project, and which will need to change continuously to respond to the needs of your users.

Advertisements
  1. Michael Saunders
    February 11, 2010 at 2:15 pm

    Nice article but I’m unsure if you’re simply advocating code gen or something more.

  2. earwicker
    February 11, 2010 at 2:23 pm

    Possibly not advocating code gen at all!

    For example, by reading a high-level description, you could generate HTML for pages. But you could alternatively have JavaScript that builds the UI on the fly, which wouldn’t necessarily involve code gen as such.

  3. jalf
    February 11, 2010 at 9:27 pm

    So what happens when a type’s presentation logic isn’t entirely defined by its type?

    Say we add a ‘gender’ to our object model. In the database, that might be a single char (‘m’ or ‘f’). In the presentation layer it may be one of two images, or it may be CSS class rendering the name pink or blue.

    Which type should our ‘gender’ field use then?

  4. earwicker
    February 11, 2010 at 9:35 pm

    Gender is a perfect example of a type. Note: “inventing a system of types”, which may include some boring generic ones but also some more domain-specific ones, and even ones that are “one-off”. (Though you could imagine a survey asking people about their cross-gender tendencies. Two gender fields: CurrentGender and PreferredGender.) Actually any decent type system would have a quick way of defining enumerated types, which gender is an example of, and could allow you to customise the rendering for them on a per-type basis.

  5. March 28, 2010 at 5:41 pm

    I’m surprised you didn’t make any reference to the data annotations in ASP.NET MVC 2… they were created for exactly this goal – to make the business object primary and presentation secondary. (They don’t (yet?) address data storage.)

  1. March 14, 2015 at 11:52 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: