Sinclair Schuller April 20, 2020
The role of “software architect” is often poorly understood. There’s usually little objective clarity in the job description. Lack of definitional clarity hurts not the architect, but the actual software architecture that the architect designs. Not operating under the guidance of precise definition, many architects wander in their efforts. The result is ineffective architectures and, ultimately, a shaky technical foundation for the products that these architectures intend to power.
Getting the architecture wrong for an app is one thing, but getting the architecture of a digital platform wrong is an order of magnitude more costly a mistake. Why? Digital platforms are abstractions (usually built around a core product) that distill domain functionality into reusable “building blocks.” 3rd parties use those building blocks to develop an infinite number of dependent applications. Poor architecture imparts the cost of that failure into every one of those apps, amplifying the damage in a significant way. Imagine the ecosystem cost of say, Apple getting the iOS architecture wrong. It would be enormous. A platform architect really needs to know what they’re doing. Great platform architects focus on the following principles:
Shaping an evolutionary path for an architecture:
There are three essential truths in architecture: (1) the architecture won’t be exactly right the first time around, (2) an architecture is never “done,” and (3) old needs may disappear while new ones may arise. An architect creates an initial architecture with built-in “guard rails” to shape evolution over time, being able to absorb these three truths without too much pain.
Managing the tension at the boundary between the best solution and domain constraints:
Designing ideal, unbounded solutions (sans constraints) is easy. It’s physics without friction or entropy. Software architects must design the best solutions within boundaries. Given a set of constraints, architects must create an optimized architecture. Cost, timeframe, technology availability, and skillset constraints are all very real. Ignoring a constraint to “optimize” an architecture is akin to designing a ship while neglecting buoyancy to optimize math calculations; the ship will sink.
Determining what complexity is acceptable:
The least complex code is no code. As soon as one writes a line of code, complexity is introduced, making idealistic minimization of complexity impossible. An architect should contain complexity to the minimum necessary to get the job done. Minimization should be in terms of implementation complexity and complexity of understanding. An architecture that is hard to understand is impossible to follow at scale. The complexity maximum needs to be enforced through the architecture, acting as a bit of a bounding box. A wide-open architecture that is loosely defined, along with bad abstractions – see (4) – invites high complexity. A well-defined architecture bounds complexity.
Establishing the right abstractions:
Choosing the wrong abstractions can be the death of an architecture, negatively impacting the other four principles listed in this post. Abstractions need to encapsulate expectations, behaviors, and boundaries in a clean, sane way. Architects need to choose abstractions with the express intent of improving outcomes in the other four principles.
Thinking through the next 15 years:
Architectures are built to provide a foundation for something “here and now.” But architectures typically survive much longer than “here and now.” The (fat) client/server model held a strong position for almost 20 years. Web apps hit the scene in the late 1990s. Despite early criticisms of web-based apps as being just a “shiny thing” and not able to replace fat-client functionality, web-apps took over. Those that embraced HTTP had architectures that could absorb change over a more extended period of time. While no one can know with certainty that a new paradigm will supplant an older one, signs do emerge that what seems to be existing, stable architecture paradigms are on a downward curve. The new “shiny thing” is more practical and appropriate for a future state.
Per principle (1), architects need to absorb continual change, and an architect shouldn’t create something that’s “legacy” in its approach two years after going live. Architects often face deciding between the current, seemingly stable paradigm, and anchoring their architecture around what might be the kick-off of a new paradigm. If they choose incorrectly in either direction, developers and standards will no longer support additional change. To the extent possible, the architecture must be decomposable to the point that it withstands complete paradigm shifts. The architect should defer as many unnecessary decisions as possible that don’t carry a “deferral cost.”
There are many concerns an architect takes on, but these five tend to define the foundation for success. Are there principles that you’d consider more important than these, or that should be added to the list?