Software architecture is a lot about different views and aspects of a software as a whole seen by different people involved in it. One view is that software architecture is expensive in the first place and therefore inefficient or useless. This view however leaves out the key factor that every software eventually has a architecture. So the question should be, whether one should take care about it or not. The second case results in software referred to as „historically evolved“. Taking care about software architecture means to care about software quality and supports meeting non-functional requirements for a software in a planned way.
Drawbacks of neglecting software architecture
„Historically evolved“ architectures result when big parts of an software, which was built as a whole, gets extended or changed. Design and design decisions are often undocumented and later changes therefore are made in a different style due to the lack of that knowledge. This effect gets amplified the longer the space of time between changes on a software is and depends upon the developer implementing those changes. If a developer never worked on a software before, he will have a poor knowledge of exisiting code usable to solve his problem. Additionally each developer will bring in his individual style.
Good developers don’t do poor solutions, right? Sure they don’t. But each developer solves only it’s particular problem in the best way possible to him. He actually is not trying to save the world but focuses on one issue to solve. This approach is perfectly fine to solve a single issue but may lead to problems for the system as a whole. Especially if the changes require much refactoring in exisiting code to get working. In the worst case code is even duplicated to avoid changes to existing code.
For each issue there are many ways to write implementations solving them: Very cleanly written ones based on clean code principles (good readable, maintainable) and „quick and dirty“ solutions which are pretty much the opposite. Solutions with higher performance are often less readable and harder to understand then seemingly easy solutions. For instance this happens if a recursive solution is choosen over a iterative one. Though both solve the problem, the iterative one is usually easier to understand but probably less performant and usually rerquires more code. So how can be decided which implementation is more appropriate? The iterative one is cheaper if it comes to changes but performs slower while it’s the other way around with the iterative solution. The answer should be given by the non-functional requirements of the system. May the implementation be more changeable or more performant? How often is the code called? Does it even make a difference?
Looking at each issue at a time leads to well working solutions, though each one maybe writen in a different style. Unit tests prove they work, so functional requirements are most likely to be met. If they are functionally fine, how about the non-functional ones to chose the most suitable strategy for the implementation?
What software architecture is about
Software architecture aims at the non-functional requirements of a software and therefore leads to higher software quality. Non-functional requirements are often put in the second place as they are less tangible and harder to find. While software quality aspects as performance or security are visible from the beginning of software development many apects approaching later in the lifetime of a software are not. For the mid-term and the long-term success of a software system those might be crucial. Doing software architecture asks you to deal with these questions as well, if it’s appropriate. Software quality aspects are described in ISO 9126 which divides the aspects to the following main groups.
For instance if you make a software for one specific use changeabilityand reusability may not be requirements. It’s absolutely okay to leave them out in implementation aspects. Let’s take a software used to manage teams and results for a particular world championship of a particular type of sport as an example. The software is built once and used only one time. As it’s less effort teams may be hardcoded in the classes and only results need to enterable. Four years later the promoter of the event comes back to you and asks you to make another version for the next championship. This time there are more teams and the mode was changed slightly. It should not be expensive, as most of the software already exists, right? Wrong, if you decided to hardcode anything and have a high coupling in your code. Could you sell to the promoter this will even get more expensive as the first project because everything has to be rewritten? Don’t get me wrong. I’m not trying to say you should always write any software most possibly generic and reusable. It might not be a requirement. But it’s up to the developers to ask the customer in what degree it should be reusable for later tournaments or even tournaments of other sport types and find it out. If it should be, it’s a non-functional requirement and belongs to a list of non-functional requirements. It’s up to the software architect to meet that requirement in the software system as a whole later on.
So should software architects address each aspect of a software and try to save the world? No one knows, what changes to a software may be required later on. Customers have plenty of fantastic ideas. However it is the architects job to make conscious decisions about different non-functional aspects of a software which are not obvious in the first place to make the software fulfill the customers quality needs. Especially if decisions have to be made to prefer one quality aspect over another have to be documented. Is perfomance more important or is it changeability?
Documentation of reasons for decisions is crucial as well. Some decisions in implementation may lead to uncommon solutions having multiple drawbacks which are taken because of priorization of quality aspects. They might be refactored to a more common solution if the reason for choosing the uncommon solution is not relevant anymore.
Another point is to make decisions upon recurring solution strategies (microtextures) for similar problems. If a decision was made to use REST services for accessing and interacting with data, no one should implement a service used completely different for a similar purpose if the software is being extended.
Who is addressed by software architecture and who uses it
Looking at functional requirements usually only useres are taken into account. Looking on non-functional requirements will reveal even more people interacting with the system. We’ll call them stakeholders from now on.
A software architecture is less a document but more a media for communication with the different stakeholders involved in that software. It’s always written for the stakeholders.
Despite the obvious users of a software there are people involved in setting it up and configuring it on a the customers infrastructure. Developers are very close to those people and understand their needs more then the ones of other stakeholders. This is probably a key trigger for the DevOps movement starting in the last few years bringing developers to take more care about operations then just throwing another JAR-File over the fence of the operation game reserve.
Other stakeholders are probably the customer who wants solution which can be modified or extended later on as new requirements arrive. Often customers already have a pretty good idea in which a product could be developed in the long run. Though of course the software should be as cheap as possible but delivered as soon as possible. A tradeoff between all those requirements must be found and communicated to the customer. You can’t make an omelette without cracking eggs. Especially the resulting flaws of economies should be documented as well as who made which decision in this context.
As we reached the point of communication. How a software works must be communicated to different stakeholders which require different information of the software. I already mentioned operations probably interessted in a logical view showing the distribution of the software and how the components comunicate with each other. Operations obviously require a different view then for example developers which are more likely interested in getting a quick overview of the components and which are their responsibilities or interfaces. Instead of packing all those information in a single diagram multiple views for each stakeholder are used. Often there are statical views describing how a system is built-up and dynamical views showing specific processes of relevance. Developers themselves are stakeholders aswell, as they are implementing the system.
What shall be documented and how
All documentation is done for specific stakeholders. Only views relevant for the stakeholders involved should be done. Especially parts which might be misunderstood should be documented and explained, aswell as uncommon solutions.
To achieve the goals of software quality for the software as a whole strategies, styles and pattern are applied and policies made. Such decisions should be part of the architecture documentation like any other agreements made considering standards, guidelines, infrastructure usage, law restrictions and so on.
This point probably points out the most significant difference of software architecture and software design: Architecture guides design. Therefore all decisions affecting the design are architecture. For instance: If a Observer-mecchanism must be used it’s part of the architecture, otherwise it’s part of the design.
How a software architecture is documented, is actually up to every architect. Usually a document containing all the necessary views, descriptions and decissions might be enough. The diagrams may be drawn with simple boxes and lines. For the developer views I’d recommend using UML, as it’s pretty common. Consider that the documentation must be accesable by the stakeholders and easily modifiable by the architect. Instead of using word-documents I made good experiences with wikis as they are very modifiable.
A good point to start is the arc42 template as well. It gives structure to the document and results always in the same layout for each project. This allows finding needed information more quickly as they always reside at the same spot. Don’t forget to only make the necessary views, even if you use such an template. You document for the stakeholders and no one else. Don’t make a design document of it.
Who does the software architecture and how is it maintained
Though I used the term „software architect“ several times in this post i’d like to clarify this is not a single person. Most teams are to small to have a fulltime architect and it’s more like a role taken by one or more of the developers from time to time. The job is to keep an eye on the development and to ensure the agreements made in the architecture documentation are met. Ideally a minimal framework to meet the agreements should be implemented first. From time to time small prototypes must be developed to verify ideas and test their influence on other involved components and services. Interfaces and unit tests against them may be helpful here aswell as test driven development.
Despite the project goals looking at the end of the softwares development there are architectural goals focusing at the whole lifecycle of the software maintained and monitored by the software architect. This means especially that as the software gets older the requirements may change and refactorings might be necessary. In this case the whole architecture may require refactoring to solve the new requirements. This sounds like a lot of work, but shouldn’t be if the software consists of well encapsulated components designed following the separation of concerns concept. The documentation should be in sync with the code from day to day. However it is worth the work as it keeps software maintainable and forces developers as well as architects to tackle the reality of the customers world changing from day to day a bit. What else can be more satisfying then a satisfied customer who feels himself understood?
How can software architecture be applied
There are multiple methods of applying software architecture. All of them require a close look at the non-functional requirements. Existing software can be analyzed aswell to check how close they meet existing requirements. Methods like the Architecture Tradeoff Analysis Method (ATAM) may be useful for thatP.
For new software there are approaches using architectural styles and tactics to support given requirements. Attribute-Driven Design (ADD), Domain-Specific Software Architecture (PuLSE-DSSA), Quality-Software architecture (Quasar) or Architecture-Based Design (ABD) may be useful approaches, just like Model Driven Development (MDD).
I’ll probably write an article about some of the methods for building, writing or evaluating software architectures later on.