Wednesday, October 15, 2014

Architectural Drivers: Building Blocks for Decision Making

Architectural drivers are formally defined as the set of requirements that have significant influence over your architecture.  In other words, there are some requirements that will help you decide which structures to pick for your system design and others that are less consequential in the context of software architecture.  This implies that it is extremely important to get the architectural drivers right early in a project, as architecture structures will become more difficult to change as the developed software becomes more realized.

Thinking about early requirements as "drivers" can also help you to create traceability from stakeholder concerns to specific architectural decisions made.  Having this traceability is great because it helps to promote important qualities in your team, such as agility.  With traceability you can make changes on purpose and with confidence as you understand the genesis for structural decisions.

What are Architectural Drivers?

Architectural drivers have significant influence over the design of a system and are the determining factor over whether one design is “better” or “worse” than another that produces the same features. Architectural drivers are nearly always divided into four categories.  Some people might go with only three categories (talking generally about constraints), and others might include other things as drivers, but if this is your first time working with architectural drivers you should start with these four categories before tailoring.

Architectural drivers can be one of the following.
  1. Technical Constraints
  2. Business Constraints
  3. Quality Attributes
  4. High-Level Functional Requirements
Let's go into more detail for each of these categories.

Technical constraints are technical design decisions which absolutely must be satisfied in the architecture. These are generally fixed from the beginning of a project and may be expensive to change as the project progresses. Constraints, as the the name suggests, cannot be changed.

Business constraints are decisions imposed by business considerations that must be satisfied in the architecture.  Like technical constraints, business constraints are generally fixed from the beginning and have a significant influence on decision making for the design.  Likewise once in place these are considered unchangeable.  An example might be a specific delivery date, budget, or 

Quality attributes, sometimes called quality requirements, are specific criteria by which a system’s operations can be judged – that is, how well a system performs specific functions. Quality attributes greatly influence the design of the system.  In many cases, the same functionality can be achieved in a number of ways and so it is the quality attributes that ultimately determines when one design is better or worse than another.  Quality attributes receive a significant and thorough treatment in Software Architecture in Practice and you can read a sample chapter introducing quality attributes online.  Quality attributes are recorded as scenarios that describes a qualitative response within the context of specific system functionality.  For example, performance is a common quality attribute, but performance when the system is doing what?

High-level functional requirements provide an overview for what the system will do, the functions and features of the system. These might take shape in any number of formats from epics to stories to use cases to ye olde "shall" statements.  While quality attributes might determine specific structures you choose, the ultimate goal of the software you are building is to build achieve some bit of functionality.  From an architecture perspective, you won't go to exhaustive detail, and indeed it's best not to go into too much detail as diving deep too early can seriously delay the project.

What about Non-Functional Requirements?

If you've read any of the software engineering literature, you'll see the term "non-functional" requirements used fairly often.  The basic thinking was that there are these things that are functional requirements, and then there's things that are not functional requirements, non-functional requirements.  Setting aside the fact that calling requirements "non-functional" is kind of silly and certainly not precise, this term comes up enough that it's important to understand it in the context of architectural drivers.

Most of the time people are referring to constraints and quality attributes when they talk about non-functional requirements.  Unfortunately, most of the time teams will lump all "non-functionals" into a single list. This is unfortunate because knowing specifically what kinds of drivers you are dealing with gives you a lot of decision making power.

Functional requirements are negotiable and must be shown to be correct.

Constraints cannot be changed once fixed.

Quality attributes imply trade-offs and often can't be directly tested until very late in the system's lifecycle. As a result you will need to find proxies, run experiments, and reason about the structures you've selected to determine whether or not you've promoted the right quality attributes.