This article is the fifth one in a series that provides practical advice and guidance on how to leverage the Continuous Architecture approach. Today, we’ll discuss a key tool from the Continuous Architecture Toolbox: Architectural Tactics.
Quality Attributes and Architectural Tactics
Functional requirements are usually well documented and carefully reviewed by the business stakeholders, whereas quality attributes may not be so well documented and carefully reviewed. They may be provided as a simple list that fits on a single page and are not usually as carefully scrutinized and tend to be truisms, such as “must be scalable” and “must be highly usable.”
However, our view is that quality attributes drive the architecture design. We need to make architectural decisions to satisfy quality attributes, and those decisions often are compromises, because a decision made to better implement a given quality attribute may have a negative impact on the implementation of other quality attributes. Accurately understanding quality attribute requirements and tradeoffs is one of the most critical prerequisites to adequately architect a system. Architectural decisions are often targeted to find the least-worst option to balance the tradeoffs between competing quality attributes.
Selecting and applying architectural tactics is a proven approach to address quality attributes requirements. Architectural tactics are a very established idea, and came from research at the Software Engineering Institute/Carnegie Mellon (SEI/CMU), originally to address some of the shortcomings of architectural patterns. An architectural tactic is a design decision that affects how the system implements one or more quality attribute requirements. Tactics are often (but unfortunately not always) documented in catalogs in order to promote reuse of this knowledge among architects. We refer to architectural tactics throughout our new “Continuous Architecture in Practice” book, in particular in chapters 5 through 7, which focus on Security, Scalability, Performance and Resilience.
Sample Architectural Tactics for Scalability
Our new book is organized around a trade finance case study. We assume that we are working for a software company that is building a new Trade Finance application called the Trade Finance Exchange (or “TFX”). The purpose of TFX is to allow organizations, engaged in writing and using Letters of Credit in the Trade Finance process, to interact in an efficient, transparent, reliable and safe manner.
TFX is being built as a cloud-native Software-as-a-Service platform. Since TFX will be offered as a white label product to several financial institutions, in addition to our initial client, and since the TFX marketing plans haven’t been finalized yet, scalability requirements are unknown at this time.
In order to meet this challenge, we follow principle 3 – Delay design decisions until they are absolutely necessary and design the initial system to handle the volume requirements for our original client. However, we need to ensure that we will be able to quickly respond to additional scalability requirements if TFX starts to be used by other financial institutions. The following table summarizes some of the architectural tactics that we would use to address potential future TFX scalability challenges:
|Data Distribution||Use data distribution for specific TFX databases that may experience issues when trying to cope with large workloads||Focus on database scalability first, since databases are often the hardest component to scale in a software system.|
|Data Replication||Similarly to data distribution, use data replication as an additional option to deal with TFX databases experiencing scalability issues – see diagram below||Depending on the specific TFX database, data replication may be easier to implement than data distribution|
|Data Partitioning and Sharding||Delay using complex approaches such as data partitioning and sharding until there are no other options.||Using data partitioning and/or sharding would add complexity to the architecture, so we follow principle 3 and delay using these tactics|
|Caching||Leverage caching approaches and tools, including database object caching and proxy caching.||Caching is a powerful technique for solving some scalability (and performance) issues|
|Stateless services||Use stateless services and microservices when possible. Stateful services should only be used when no other option exists.||Stateless services enable scalability. Stateful services can cause scalability issues|
|Microservices and serverless||Using Microservices for TFX provide medium to high scalability. A few serverless functions are used in specific instances||Scalability of severless functions is limited by the cloud provider. Unpredictable cold-start latency could also be an issue.|
|Monitoring TFX Scalability||Design and implement a monitoring architecture which is critical for scalability||A well designed monitoring architecture is a key enabler for scalability|
|Dealing with Failure||Use specific tactics for dealing with failure, such as circuit breakers, governors, timeouts and bulkheads.||Implementing tactics for dealing with failure when workloads increase is very important for scalable architectures|
The Data Replication tactic is depicted in the following diagram:
Using architectural tactics is a very effective way to reuse prior architectural knowledge to address your quality attribute requirements – even if they are not well documented or even accurately known.
The next few articles in this series will continue to describe the practical aspects of using the Continuous Architecture approach, as well as its tools and essential activities (including describing more architectural tactics), so we hope that you find those articles interesting and you will keep on reading them!
For more information on our book, “Continuous Architecture in Practice”, which explains architectural tactics in much more detail, please visit our website at continuousarchitecture.com.
 See for example https://resources.sei.cmu.edu/library/asset-view.cfm?assetID=9087