Skip to content

Instantly share code, notes, and snippets.

@thiagoarrais
Last active January 12, 2016 17:13
Show Gist options
  • Save thiagoarrais/87d92ab68313c1d9fb1f to your computer and use it in GitHub Desktop.
Save thiagoarrais/87d92ab68313c1d9fb1f to your computer and use it in GitHub Desktop.

Software Architecture: It is (not) what you think

Original at http://www.ruthmalan.com/Journal/2014/2014JournalOctober.htm#Software_Architecture

In what follows, the caps are only meant to highlight the play on words. :-) It's just one of those ruff riffs, you know. The play is meant to highlight different understandings, not to suggest how the actual you reading here conceives of and delimits architecture. It is merely a thinking tool and rhetorical device. (Aside: "architect" may be a hat developers on the team all wear, or a role; we're setting that discussion aside here.)

“Software Architecture: It IS what you think” -- you already have a working knowledge of what software architecture is. Things like

  • Organizing structure of the system – components and relationships
  • Blueprint – architecture specification, component contracts, etc.
  • Decisions: “"All architecture is design but not all design is architecture. Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change.". -- Grady Booch

But. Which decisions?

“Software Architecture: It is NOT what you think”

The architect decides which decisions are architecturally significant, but decisions would generally fall within the bailiwick of architecture for these kinds of reasons:

  • Scope – we architect across. We use the umbrella diagram to illustrate architecting across scopes; across the internal boundaries within the system (components, microservices, services, subsystems, etc. depending on the chunking paradigms for the system in question), architecting across the system, architecting across the system boundary and its relationship with other systems. Architecture decisions are those that need to be made from the system perspective, taking into account their impact on system outcomes and the interacting web of other design decisions. For example, if a decision from the perspective of one feature or microservice or (sub)system would make it really hard for another, that's an indicator of architectural significance.

  • Timing – ground under the feet. The architect can’t just say “YAGNI”; the architect has to apply technical and organizational wisdom and think through what needs to be put in place early to allow the team to move forward, or because it will incur high cost to change later. Uncertainty is highest on the first day, yet we need to get started, and then we need to make progress – the architect has to be able to live with ambiguity and paradox! And resolve ambiguity and uncertainty by deciding, where that is critical; and exploring, or deferring. Deferring what we can, for then we know more. It is also not all "feed forward" -- we need to iterate, taking what we learn as we design (including the design we do in the process of coding) into account and potentially reworking at "higher" (that is, more broadly scoped) levels. As fits the extraordinary moment. For each unfolding moment. Over time. Not just early. Not just later. As the system evolves -- so throughout its lifespan. Judgment calls about what is architecturally significant, and when to tackle it.

  • Strategically significant, not just structurally significant – make or break decisions. Many characterizations of architecture focus exclusively on structurally significant decisions -- the emphasis on cost of change is cost of change to the system itself (so a code focus). Of course, addressing the structurally significant technical challenges of the system design is fundamental! But we also try to wedge open the space of architectural concern, because the system impacts value creation. The architect shifts her center of gravity, so to speak, from a technical emphasis addressing technically-framed technical concerns programmatically, to technical decisions in service of value creation and differentiation, or business intent and strategy – figuring out what the strategy means, and needs, and expressing this shaping intent in technical terms. Identifying and addressing structural challenges, and collaborating on shaping solutions that take the various forces, demands on, and desires for the system into account. This means outlining (technical) strategies sometimes, and designing mechanisms, at others. Again, judgment calls.

  • Design is fractal -- “turtles all the way down.” The system offers capabilities to its context, and these mean it, in turn, has internal responsibilities which get assigned to parts (subsystems, (micro)services, components, …); those parts offer capabilities to their contexts, and have internal responsibilities… so “requirements” and contextual constraints and challenges at one level, get translated through design to parts with responsibilities at the next level. This is not necessarily or strictly hierarchical; for example, a part may play a role in multiple mechanisms. But you get the idea. So what we tend to call “Requirements” for a system, is system design at a higher level (that is, broader scope). We need to architect across those boundaries, so the architect needs to be involved in crafting the system concept and architecturally significant capabilities. This informs the shaping of desired capabilities, with innovative ideas coming from what we can build with technology, along with ideas for addressing its limitations. And this provides contextual understanding, so the system (internals) architecting work can get started early (from the start) making the process more agile (responsive, adaptive, exploratory, iterative and incremental, etc.). It also provides a fulcrum for active feedback across the design boundaries (iterating not just on "solution" design at various scopes, but on strategy and system capability design). That way, learning is fed into more broadly scoped strategic design, as well as more narrowly scoped local design. (Re)Factoring of responsibilities, for example, becomes something that happens at many levels and over time. Again. Judgment factors. And factors and refactors.

  • Structure and dynamics – the structure needs to enable the dynamic behavior of the system and its intended properties (or qualities). Further, the system capabilites and properties, and our understanding of what is desired and what the tradeoffs are, emerge from the interactions within the system and between the system and its contexts of operation, use, and development; they take shape and evolve. (I recommend reading Decisions, Concerns ...(re-)Defining Software Architecture -- the section of Designing The Defining Structure makes points pertinent to this bullet.) The structure is a composition of mechanisms designed to deliver capabilities and properties of the system -- that is, the structure should not/cannot be designed without deep consideration of dynamic behavior, and resultant forces, that the structure must sustain and enable. And these mechanisms (and underlying structures) intermesh and interact.

“Software Architecture: It is not what YOU think”

  • Not what you think alone – thinking “out loud” in small groups, with an emphasis on collaboration and participation, bringing more minds to bear; this is important when the system is complex, requires different expertise, etc. It is important to draw out, to sketch and model literally, but also to get ideas into a shared thoughtspace by talking, writing, modeling (in various media), exploring, understanding, resolving, elaborating, improving, sharing, .... collaborating, partnering, peer-ing!

  • The broader team (of teams) also needs to buy in to and understand decisions and be able to move forward. At some points and contexts, the architect may have to be that benevolent dictator with “a baseball bat” (more realistically, feather), but generally it is more about shaping, guiding, coaching, peer problem-solving. Regardless, software architecture is the outcome – if the design intent isn’t communicated and understood and feasible, etc., it won’t be what is built; the actual built architecture will diverge from the intention. Architecture is not a one person island thing, unless the project is a one-person thing. We need to strike a dynamic balance between participation and keeping things moving -- too many involved in thinking something through, and that snarls up just as surely as not including others.

  • Minimalist -- focus on essential architecturally significant decisions and defer the rest (in time and to others)

“Software Architecture: It is not what you THINK”

It's also not just about thinking (important as that is), but about building -- paper prototypes or sketch mockups, code prototypes, pretendotypes, role play, slices of the system, the system! But using the cheapest medium to explore critical design routes, alteratives (I wrote lateratives and that is a nice malamanteau from, and evoking, lateral alternatives!), options.

The most pernicious couplings are to assumptions -- including those we don't even know we're making.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment