Software Architecture: design and documentation
In my previous article I tried to present the role of the application architect on a general level. Today I’d like to focus on his specific aspects of his work, without which the term "architect” wouldn’t make any sense.
Design and documentation
A common image of architect’s work, consisting in drawing and describing blocks, puts two activities of design and documentation in one pot. Meanwhile, these are two independent activities. To explain why I present two definitions of architecture.
Architecture – fundamental concepts or properties of a system in its environment embodied in its elements, relationships, and in the principles of its design and evolution.IEEE 1471 standard.
The software architecture of a system is the set of structures needed to reason about the system, which comprise software elements, relations among them, and properties of both.“Software Architecture in Practice (3-rd edition)”;Len Bass , Paul Clements, Rick Kazman
Architecture isn’t the documentation itself, but a set of principles and properties of the system elements and their dependences. It is something abstract, it is the way of our thinking about created system. Images, diagrams or descriptions are only projections documenting the architecture.
Therefore design is a process of creating and systematizing the architecture, whereas preparing documentation is a process of physical recording. Documentation is supposed to transfer information concerning designed or existing solutions. It enables standardizing the way of thinking of the created system among team members.
Two approaches to create software architecture
There are two well-known approaches to create software and its architecture. We can start from general idea and iteratively decompose system into smaller components, this is called the top-down approach, and is often referred as big up front design. Alternatively, we can start with defining project goals and iteratively add more and more small pieces of functionality to system. Eventually, all those small elements and their relations will compose system with its architecture. This is called the bottom up approach.
Both techniques have good and bad sides, which are compared in the following table.
| Lower Initial Cost|
Packaged software tends to be cheaper, as the costs of development have been spread across thousands of purchasers of the solution.
| Higher cost with many users|
With ‘cost per licence’ payment model in particular, the bill can be quite hefty. Especially if you need your software to be used by a large number of employees at your company. Not to mention, these fees must be paid periodically.
| Ready when you are|
When using an off-the-shelf software, what you need to do is have it set up on your machines and start using it immediately. In case of centrally hosted solutions, there is even no need for installations.
| Need for configuration|
At times, you may find that commercially available products don’t quite meet the specific needs of your company, or are not compatible with your other systems. This may mean you require additional personalisation of the product, which usually leads to unexpected extra costs, and is not always possible.
| Availability of Training|
A packaged solution is likely to have an established base of training materials. They come from the official producer of the software and corporate training companies, but also from its avid users (think YouTube tutorials and community forums).
Too many features can cause confusion among users and unnecessary clutter in the application. You may not be able to hide or remove functionalities or fields your staff neither like, nor need. This makes the system larger and harder to learn.
An out-of-the box software will be continuously developed by its producer who will launch new and upgraded versions. Usually they are available for free or at a reduced cost.
| Dependency on the vendor|
You are not in control of the system, which is developed according to the vendor’s plans, not yours. Lack of the source code limits implementing features you need and increases security risks and a possibility of failure.
| More functionality|
Since it has to meet the requirements of as many users as possible, an off-the-shelf solution is likely to have more functionality. Often you will discover useful features you didn’t realise you needed.
| No competitive advantage|
You are just one of many users of the same system, which can also be bought by your competitors. In this case, it is hard to gain any competitive advantage.
Combining both approaches
Neither one of described methods is perfect as each of them has pros and cons. The general rule is that the top-down approach makes more sense with complex problems, whereas for the minor ones the bottom-up approach is more reasonable. Maybe it would be better to first divide complex problems into smaller ones, and then use evolutionary design? Of course it would be! This is the approach that, intentionally or not, is used by the majority of us.
It is good to make as much up front design, as much stable and well defined requirements we have. However, when requirements are not clear enough, it‘s better to put off decisions until we better understand system and stakeholders’ needs. In such cases, at design stage we should concentrate on defining system components, their interfaces and interactions. Until given components are not developed, all we need is appropriate abstraction and sometimes temporary solution. When we have such abstract plan for the entire system, its parts can be developed evolutionary.
Another important question is, how big those components can be, however before I answer this, I’d like to deliberate important issue of the bottom up approach.
Evolutionary software development is gaining more and more popularity with agile movement. However, it’s often adapted without consideration for its drawbacks. It can’t come only as pleasurable way to develop software, without a long term plan. This leads to crappy, unmaintainable code and project’s catastrophe. It requires the following sophisticated techniques.
Adding each piece of code results in increased entropy of the system, which should be consciously and constantly decreased. Constant refactoring enables that and is often combined with TDD, where refactoring is performed frequently, with every single test. It’s important to do small refactoring but every day, all the time. Even a small distinction of a new function when the old one has grown too much. Creating a new class when the old one starts to do more than one thing. Deleting duplication that you have noticed. Every single day without refactoring results in a small stick of dynamite, which in a few months or years may explode and blow up our entire project. Another question is when refactoring can be safely performed. With unit test! On what kind of code it can be easily performed? Modular one. How to ensure that the code will be modular? Writing unit tests in the first place! When does writing unit test make sense? When we take care they are always ok. How do we know that they are ok? Because we run them, and in case we forget we have Continuous Integration!
The boundary between architect’s and developer’s responsibility
As I have mentioned before it is important to answer where should upfront design be stopped, and how big is the field for evolutionary development? It mostly depends on teamwork and its experience. If we have a team composed of very good engineers, who work well together, it is enough to set the work rules, standards, technologies and create several diagrams presenting architecture on a very high level. However, if we have to deal with a newly formed, unexperienced team, it would be better to invest more time in the joint consideration of solutions and design the systems with more details before development starts.
Another factor influencing this boundary is the stability of requirements. In a project with well-defined requirements, enforced by the contract, which we understand well it is worth planning the system in a more detailed way. On the other hand, if we take part in a research project with changeable requirements there is no point in going deeper than setting general standards and high level system architecture.
Documenting the architecture
As I’ve already mentioned, the design and documentation are not the same. On the other hand, these issues are complementary. Designing the larger part of the application which won’t be documented is pointless. Today, I’ll think about what is, what for and why do we need good documentation.
What is the documentation of architecture?
The first association – a diagram. Certainly, to some extent correct, but only partially.
Firstly, we can’t describe one diagram as documentation. Architecture, even in a simple project, is a complex and multifaceted notion, therefore it can’t be presented on one diagram. Instead, we should create multiple views, presenting architecture from different perspectives and with different accuracy.
Secondly, despite the fact that one picture is worth a thousand words, information such as standards and explanation of taken decisions, is hard to present in a picture. In that case we should use other artefacts e.g., text or code snippets.
Objectives of documentation
Before we eagerly start preparing documentation of architecture, because that is what best practices say, it is worth considering what the point of doing this is.
We can enumerate a few basic objectives of documentation:
- Communication with the client – it can be the basis for presentation of how quality requirements are going to be fulfilled, and how complex and expensive will be the solution.
- Creating a guide for developers – the main purpose will be to create the source of truth, the reference point for programmers, in case they have any doubts regarding solution they would like to use.
- Team education – good documentation will help to promote information about changes in the architecture, and will be a good foundation for discussions concerning the system development.
How much documentation and for whom
There is no right or wrong number of artefacts documenting the architecture. Once again, it depends on the team, its dynamics and the environment. It’s always worth considering the reasonableness of creating another element of documentation regarding its purpose. Not always more documentation is better. While deciding how much and what kind of artefacts we are going to create, it’s better to bear in mind that we won’t be able to solve all the communication problems with the use of documentation:
The primary problem with documentation is the difference between context and content. Documentation can provide content, but understanding the context requires domain expertise.Jim Highsmith“Agile Project Management, Creating Innovative Products”
Existing documentation, even if good and valid, must be understood. To achieve this we need good relations, interactions and cognitive empathy among team members as well as between the team and the client.
Form of documentation
We all know that the value of diagrams presenting relations and behaviours of architectural elements is invaluable. However, diagrams aren’t equal, and I don’t mean differences between class diagrams and sequences diagrams. Some of them are explicit and understandable, however there are also the ones we look at, and don’t understand what the author had in mind.
As we all know the most common standard in the industry is UML. However, for many, not without reason, this standard is too complicated to illustrate the majority of solutions. The problem is so old and common that at the turn of the century Martin Fowler wrote the guide: “UML Distilled: A Brief Guide to the Standard Object Modeling Language”. In his book he describes how to pragmatically use UML. How to use its essence to make our diagrams clear and understandable, without wasting time on tunning them to make compliant with standard.
To summarize the above deliberation, diagrams documenting the application architecture can be divided into:
- Formal – compatible with standard (usually UML), which makes them explicit. They are a good choice if we decide to create a complex documentation with the use of CASE tools. It makes sense, especially if we develop a project of the system with a closed specification.
- Informal – “rectangles and arrows” usually drawn on a piece of paper, whiteboard or flip chart to illustrate the idea we are talking about, or to back up our thinking processes. They are highly unclear and without context of people involved in their creation, they may be more confusing than understood.
- Hybrid – a merger of the two mentioned methods, also known as “Arbitrary Modelling Language” i.e. using 20% of standard to create 80% of uniqueness. Diagrams have a good value for money spent on creating them. Definitely, it is the best way of creating documentation to support the above objectives: communication with the client, creating a guide for developers and education.
The golden thought of software documentation
The above deliberations about documentation may be summed up in two sentences: Documentation has to have its purpose, otherwise it is pointless. What is more, the amount of documents should be barely sufficient, but never insufficient.