Software Architecture Patterns — Which one to choose ?
Priyal Walpita
CTO at ZorroSign Inc. | Expert in AI/ML, Blockchain, Quantum Computing, Cybersecurity & Secure Coding | Digital Security Innovator | Mentor & Trainer in Advanced Tech
Planning on starting a greenfield software project? Then selecting the right architectural pattern will play a crucial role to the outcome of the project. Selecting the most popular or the latest technology in the market won’t always mean that it would bring the best results. However, selecting the most appropriate will provide proven solutions to prevailing and recurring issues.
There is a famous saying in the field of software engineering that says “take decisions to your resume”. What does this mean? IT professionals like to decorate their resumes with the latest and greatest technologies which would help in their next interview, but would not actually be beneficial for a project. For example, if your project is to build a regular data capturing form (with no more than 10 fields) for a survey which will be used only once by less than 100 users, using highly complex architecture patterns like Microservices would be an utter disaster. It would be like building a fighter jet just to visit the grocery store at the end of your street.
Thorough planning must be done when selecting an architecture pattern and the following features must be taken into account.
- Cost
- Time to Market
- Number of users (current and future)
- Level of isolation (ie: integration with other systems/platforms)
What happens if we develop a system without any architecture pattern? It will eventually end up a ‘big ball of mud’ where every class connects to all other classes.
So whenever you change the behaviour or structure of one class, a ripple effect would follow where multiple other classes would break. Is your software like this? The best way to find out is by using a software design reverse engineering tool like hex-ray that analyzes your component/class structures. If you end up with something like the above picture, then its time to rethink and do some alterations to your software design.
To help you, we will skim through the fundamentals of main software architectural patterns along with the pros and cons of each pattern. Then we will elaborate what architecture pattern would be the best fit for a given scenario. But we need to keep one thing in mind. When it comes to software architecture, there is no black and white answer; no correct or wrong architectures exist. It is very subjective and depends on a multitude of factors as mentioned before.
This blog goes as a series and we will be covering the following topics as the main chapters of the series.
- What is a Software Architecture Pattern (this post)
- Layered Architecture Pattern
- Microkernel Architecture Pattern
- Event Driven Architecture Pattern
What is a Software Architecture Pattern ?
The discipline of creating the fundamental structures of a software system is referred to as software architecture. Software structures are made up of software elements and their relations which function as a blueprint, laying out the pattern of tasks to be executed. Software design teams greatly depend on these software architectural patterns. It should be noted that software architecture must be chosen wisely because once implemented it is not easy to change.
Software architectural patterns are important as they are examples of the best solutions that have been built and tested successfully in architecture design. Experienced developers use their knowledge and familiarity to include these patterns rather than creating patterns artificially or randomly when designing. Furthermore, by using these patterns and highlighting them, they can share their knowledge and teach new developers key design strategies as well.
Benefits of Software Architectural Patterns
Patterns help in the identification and specification of abstractions which are found above the level of single objects, classes, and components. It is difficult for a single application to address a complex problem by itself. Patterns introduce different roles which have multiple application components thus helping in providing solutions. They define the constituent components along with their responsibilities and relationships on how they collaborate.
Additionally, these solutions portray the relationship between the roles which are introduced. For example, the Observer pattern comprises of two leading roles which are the subject and observer. The two roles cooperate via a push-based change propagation mechanism which ensures that the components can hold their state consistent with each other.
Patterns offer a common language and a shared understanding of design concepts. This helps ease the re-use of architectural knowledge and artefacts even though the reuse of certain algorithms, interfaces, implementations, and detailed designs may not always be possible. For instance, when developers have an understanding of the Observer pattern, discussions on how to manage two cooperating components consistent in their system is not required.
Patterns help in documenting software architectures. Through an in-depth evaluation of the consequences and implementation trade-offs, patterns make it possible to trace the reasons why specific design choices are selected over others. The software development path, practice, and maintenance can be smoothed by keeping a record of the intent, behaviour, and structure of the software in terms of the patterns which are found within it. Product-line architectures use patterns that are beneficial thus developers should be aware of it. If not, they would struggle to use it correctly without any understanding of the fundamental structure, mechanisms and control flow. Pattern based documentation of architecture helps in resolving conflict by helping developers focus on main design decisions.
Patterns are useful in the construction of software which have well-defined processes. Some patterns make a sketch of particular behaviour. This paves the way to meet certain functional requirements for the applications in a certain domain. For instance, patterns have been recorded for accounting systems and corporate finance and in improving the capacity of reactive systems.
Patterns also help in capturing experience in a form that can be independent of specific project details and constraints, implementation paradigm and often even programming language. When understanding coding principles and addressing design challenges in new projects, it is possible for developers to implement solutions that are error-prone, inefficient or unable to be maintained. Patterns help developers select suitable software architectures without falling into potential pitfalls in a domain.
Patterns help software developers coming from different programming language cultures share design insights that are of mutual interest while also preventing ‘language wars’. The transfer of knowledge among different generations of developers who are familiar with it helps balance and enable members of various communities to communicate and refocus on the concerns of a particular language community. While the coding could be dissimilar, similar patterns could be present which underpin the old and the new.
Architectural Patterns are not Coding Guidelines
It must be noted that patterns cannot be deemed as coding guidelines. Coding guidelines can be put together either partly or from patterns that are focused on code style. However, the converse is not true. Though there are many coding guidelines that are idiomatic, this does not automatically make them design patterns. For instance, the specification for Sun Microsystem’s JavaBeans had consistently used get and set prefixes for property accessors as ‘design patterns’. However, though most of these prefixes are patterns, they do not help solve design issues for general designs even within Java code.
Application of Architectural Patterns
It is always important to understand the pattern vocabulary clearly as applying the wrong pattern can lead to a lot of problems. An experienced developer would have a sound judgement which would help him understand when a pattern is not appropriate in a particular situation. When there is misapplication, it can yield inappropriate designs and implementations.
Having superficial knowledge of a pattern can give developers the impression that they are well versed in it even though there may be a better solution for it. A good example is when knowing the structure and participants in complex patterns like Proactor and Reflection. This knowledge is only a single aspect thus is not enough. For effective pattern application, it is important that the essence of the pattern is reflected in its context and not just the structure.
Stay tuned to this blog series as we will be discussing how to apply most common software architecture patterns. The next post of this series will discuss the Layered Architecture pattern.
If you have any queries/concerns, then you can drop me an email or send me a message on LinkedIn or Twitter. I’m just a message away :)
Thanks for reading!