In terms of ensuring quality, the role of architecture, architectural best practices, and architectural process is foundational. Code that does not adhere to a rational and understandable architecture cannot reasonably be considered as ‘quality’ code. Such code is often (correctly) ridiculed as ‘spaghetti’ code — it is difficult to read, hard to modify without unintended consequences and its maintenance often involves ‘key personnel’ dependencies on developers who have invested hours poring over the obtuse code to try to ‘figure it out’.
You can continuously test, measure and deploy the mess all you want, but you can’t derive quality from unstructured code.
If a codebase has no regular, definable architecture, then efforts aimed at delivering quality code will likely fail. Related to this, a frequent criticism of Agile methodology is that it de-emphasizes architecture and, in particular, architectural planning upfront. The general gist of this criticism is that developers ‘just start coding’, and do not adhere to any sort of consistent architecture. Where structure does emerge, the criticism goes, it emerges in isolation and not as some sort of general ground plan. Hence, in as much as architecture provides a foundation for software quality, agile projects will be severely challenged due to this lack of architectural foundation (or, at least that’s how the criticism goes).
“Code that does not adhere to a rational and understandable architecture cannot reasonably be considered as ‘quality’ code.”
As an indictment of Agile software development, this criticism fails. Agile itself does not de-emphasize architecture, nor does it encourage developers to produce code that lacks organization and structure. Rather, poorly executed and poorly managed software projects that do not follow agile architectural practices produce results that are consistent with this criticism. This series of articles will establish best practices, standards and guidance for the successful application of architecture within agile software projects.
Architecture in the agile context must not be viewed as schematics or blueprints designed up-front to dictate development, but as living documents that guide and support emergent design. Consistent with the agile manifesto, the purpose of agile architectural documentation is to serve as a vehicle for interactive communication between scrum team stakeholders, advance communication and understanding with client stakeholders, support and enable change and help ensure quality delivery of functioning software. In a nutshell — Agile architecture only exists as an aid to communication and as a support to the iterative development and delivery of quality software. Agile architects are chief communicators, facilitators and guides embedded in the agile process.
When deployed in the context of an iterative agile project, architectures should conform to one of these four schemas: Initial, Working, Target or Transfer.
The first class of agile architecture is the result of light-weight iterative design up-front, as part of a sprint-zero (S0) or ‘discovery’ sprint. These architectures are considered to be initial architectures. Initial architectures may be produced to document the findings of discovery, sketching out an initial structure of new and existing software components that will support the development of the discovered user stories. Initial architectures can also be created to provide an understanding of the large work items that respective teams must tackle, and provide coordination around technical dependencies (e.g. component A needs to be produced before component B can be started, and B and C must consume services provided by component C, etc). As such, initial architectures are invaluable for helping to ‘size-out’ development teams and understand what skills and skill levels the implementing teams will need to build the software in question.
Architecture provides the tools to discover a path through the unknown, and document your discoveries for those who come after.
Initial architectures are also a good way to rapidly iterate through possible solutions before any code is laid down — solutions can be diagrammed to enough detail so that they can be compared and evaluated. Better solutions can be selected, and the decisions can be documented. Initial architectures may also be prepared to establish and document integration and communication properties prior to implementation, thereby reducing the potential for rework. Last but not least, initial architectures can encode ‘invariants’ of the problem space — aspects of the software build that are not subject to change and around which the team must synchronize. Some examples of invariants include authentication and authorization schemas, key systems of record or existing legacy systems that must be leveraged.
The second schema of agile architecture is produced during the course of a sprint and typically used for more short-term sprint-related aims. These architectures are considered to be working architectures. Working architectures are often produced to provide direction to developers building features in current or upcoming sprints. In this case, they may be as simple as a paper sketch or whiteboard diagram. Working architectures also sometimes provide explanatory documentation to various stakeholders about the state of the code or serve as a way to discuss options and tradeoffs to client stakeholders. In this case, they may be more robustly documented with write-ups and legends. Working architectures are also frequently updates to either initial architectures or updates to previous working architectures which in turn are updates of initial architectures. As such, working architectures provide living documentation for a software project and reflect the ongoing evolution of an agile codebase.
Working architectures are best built and executed in the field, as living documents that reflect the decisions made at every level.
The third major schema of agile architectures are aspirational architectures. These architectures serve as a way to guide the continued iterative development of a growing codebase by envisioning future-states that constitute a transformational improvement over the current state. These architectures are referred to as target architectures. Target architectures can diverge significantly from the actual reality of the code, as they are meant to define a future state to which the code should come into conformance with, iteratively and step-by-step. Target architectures are often prepared when a project has grown in complexity and has outgrown their initial architectural designs. Target architectures may constitute a significant undertaking for architects and leads, and migration to such architectures may even be entire stories for ingestion into one or more sprints.
When complex systems exhibit surprisingly simple organizing principles, it can be a thing of beauty. Conformance to a perfect design can be a great thing to strive for, as long as we allow for ‘prickly’ realities.
The fourth and final schema for agile architecture are transfer architectures. Transfer architects are typically drawn up as a final architectural snapshot of a software project. This may happen when the software project enters a state of inactivity, or it may happen when a software project is transferred between teams, where the new team may not have living knowledge of the software. Transfer architectures often act as bookend architectures, conveying solid documentation of the state of the code and providing an initial architecture when the project is taken out of stasis — thus enabling rapid re-start of development by future teams.
A good transfer architecture is like a cutaway diagram — it shows how the ‘finished’ system parts fit together in a simplified view, so that when the next team needs to fix or modify the system, they know how to get started.
In an Agile context, Architecture’s role is to help the scrum team solve problems and communicate that solution to the various stakeholders. It takes as its primary concern and responsibility code quality by providing a rational, thorough structure for code and a structured approach to the solution of problems. Architects themselves must not view themselves as external to (and certainly not above) the agile process, rather they should view their role as an extended part of the scrum team.
Architectural documentation is not monolithic. Some Architectures reflect early solutioning and discovery, others may reflect ‘just in time’ support to help structure work in progress, and still others may reflect end-state documentation or aspirational states that the software can move incrementally towards. The Architect must be cognizant of the context in which they seek to deploy their trade, and match their work to the needs at hand.
Now that we’ve provided the foundation for Architecture in the Agile context, we will move towards an analysis framework for ‘good’ architecture and show a worked example of ‘good’ architectural documentation. Check it out!