Software Architecture is a term that is often used, and abused. Frequently it is used as shorthand for all the technical decisions that go into a software project. Other times it is used to refer to diagrams and documentation so disconnected from implementation that its usefulness is completely suspect. But, the reality is that every software system has an architecture, whether intentional or not.
Martin Fowler once described Software Architecture as being “about the important stuff. Whatever that is” (“Who Needs an Architect?” IEEE Software, July/August 2003; pg 3). So, in many contexts a software system’s architecture relates to what and how it does the work that makes it valuable. And, in many respects that means all Software Architecture is intentional. However, in representing how a software system does its work the matter of organization and structure matters.
Respecting organization and structure, this is where the accidents tend to happen in Software Architecture. Nearly all software starts out with a clear organization and structure, often reflecting the framework and tool choices used to bootstrap the project. Yet, as the system grows, organization becomes less deliberate and more sprawling. Structure and organization may be added for new elements of the software’s design, but the macro-organization of the project often remains entirely singular.
A great example of this tendency can be found in numerous Ruby on Rails projects. The division between Models, Views and Controllers starts off clear and sensible. As the application grows often Service Objects, View Models, and other elements of sound Software Design are introduced to keep the system maintainable. Yet, as functionality increases, the macro-organization of Rails applications rarely change to adapt to their increasing complexity. In my experience it is very uncommon to see a single Rails application, no matter how large it grows, organized into modules along functional boundaries. Instead model associations tend to be allowed to form an ever more dense and interdependent web.
This progression is what Accidental Software Architecture looks like. It’s the natural result of macro-organization not evolving over time. The result is a heavily interdependent and tightly coupled system. And, this can happen in any kind of development culture; with good, mediocre, or poor testing practices; and to projects of any age. Most often Accidental Software Architecture is recognized in the Big Ball of Mud anti-pattern. But, there are other signs of Accidental Software Architecture that can go unrecognized, or unaddressed. Some of these include God Objects, Circular Dependencies and difficult to trace callback/lifecycle behaviors.
In the end, the goal is not to label a system as having an Accidental Software Architecture, as if that somehow means we’ve identified a bad system. The goal is to find a path towards more intentional architectural thinking and practices. We want to improve the system, and that means bringing intentionality to what formerly was done without specific intent.
I will be presenting “Beyond Accidental Architecture,” a more thorough talk on this subject and how teams can move beyond it at OpenWest in Utah on July 14th, and at the O’Reilly Software Architecture conference in October. I also recommend Domain-Driven Design Distilled by Vaughn Vernon for those wishing to learn more about working towards more intentional Software Architecture.