Wednesday, 4 October 2017

Concerning Seperation


The majority of good engineering and architectural practices in software development can be traced back to the principle of separation of concerns.

A concern may be deemed a reason to change, a functional unit or a set of connected pieces of information but whatever the definition it should be possible to demonstrate clear and distinct separation when it comes to the implementation of particular tasks and actions in a code base.

When this isn't the case we instead see the emergence of spaghetti code, instead of well formed modules of code we are left with interwoven and potentially unintelligible software that is very difficult to pick apart.

It should be possible when explaining the construction of a code base to identify a certain layering along the lines of the concerns that will broadly fulfil common objectives.

Business Logic

Software generally exists to represent a particular business domain, these domains will always have particular rules of operation and practices that define what it is the business does for its users.

This logic when implemented in a code base should be distinct from the implementation of integrations, such as REST APIs, that provide input and also to the mechanism that is used to present the output to the user.

The business logic should be unconcerned with how the data it is using to make decisions is being provided and also to what will be done with the outcomes it is producing, it is purely about logic.

Model

Alongside logic a business domain will also likely have a representation of the data it deals with and how it models its world.

These model classes should be only concerned with representing these entities and be entirely dumb.

It should be very rare to see logical programming constructs in these model classes as the place for logic and model manipulation is in the business logic that represents the rules that govern the management of the model.

A simple example might be that a class representing a bank loan shouldn't contain code to calculate repayment values or fines for late payment, it should simply represent the amount owed by the customer.

Services

No piece of software is self contained, it generally relies on the flow of information in and out of its own sphere of operation.

These flows might be API calls to servers, to functionality within the underlying OS or to other pieces of software deployed alongside it.

All of these interactions should be encapsulated within a service layer, the responsibility of which is to understand the mechanism for the interaction and how to either retrieve or send the relevant information.

A service layer interacts with outside entities so you don't have to, abstracting the detail so other parts of the code base can concentrate on what can be achieved with the information being provided.

These services should also be small enough to make possible the opportunity they can be composed to perform more than the sum of the parts. 

Presentation

Most software at some point must open up a window into its world, both showing the user the current state of its domain whilst also accepting input from the user to change that state.

Any logic in this layer should be solely concerned with choices related to the presentation of data, at no time should it be deciding what data should be displayed only how it should be rendered.

Being the only area of code the user can interact with means it is necessary the presentation layer be the first to be informed of a users input, the code in this area should be the minimum to provide a linkage between this input and the business logic that will decide the outcome, not filtered, second guessed or pre-empted.

Most reasonably complicated software will have more distinct layers than have been presented here.

These might cover hardware abstraction, platform abstraction or any other distinct functional units that can be identified.

Whatever they may be it should be possible to draw a ring around them on an architecture diagram rather than a many sided polygon.

A single concern is a single reason to change and a single reason to cause a bug.

The impact this will have on the maintainability and extensibility of a code base is immeasurable and is pretty much the only way to achieve a clean architecture.

The challenges are firstly to clearly identify these concerns and secondly to have the discipline to resist the temptation to mix them.

As with many good software development practices a healthy dose of pedantry and an obsession with order can go a long way to providing good outcomes.       

No comments:

Post a Comment