Design for Life

Soundview, Bronx, NY

 

The underlying theme of my last post, “Babies, Bathwater, and Software Architects”, was that it’s necessary to understand the role of a software architect in order to understand the need for that role. If our understanding of the role is flawed, not just missing aspects of what the role should be focusing on, but also largely consisting of things the role should not be concerned with, then we can’t really effectively determine whether the role is needed or not. If a person drowning is told that an anvil is a life-preserver, that doesn’t mean that they don’t need a life-preserver. It does mean they need a better definition of “life-preserver”.

Ruth Malan, answering the question “Do we still need architects?”, captures the essence of what is unique about the concerns of the software architect role:

There’s paying attention to the structural integrity of the code when that competes with the urge to deliver value and all we’ve been able to accomplish in terms of the responsiveness of continuous integration and deployment. We don’t intend to let the code devolve as we respond to unfolding demands, but we have to intend not to, and that takes time — possibly time away from the next increment of user-perceived value. There’s watching for architecturally impactful, structurally and strategically significant decisions, and making sure they get the attention, reflection, expertise they require. Even when the team periodically takes stock, and spends time reflecting learning back into the design/code, the architect’s role is to facilitate, to nurture, the design integrity of the system as a system – as something coherent. Where coherence is about not just fit and function, but system properties. Non-trivial, mutually interacting properties that entail tradeoffs. Moreover, this coherence must be achieved across (microservice, or whatever, focused) teams. This takes technical know-how and know-when, and know-who to work with, to bring needed expertise to bear.

These system properties are crucial, because without a cohesive set of system properties (aka quality of service requirements), the quality of the system suffers:

Even if the parts are perfectly implemented and fly in perfect formation, the quality is still lacking.

A tweet from Charles T. Betz points out the missing ingredient:

Now, even though Frederick Brooks was writing about the architecture of hardware, and the nature of users has drastically evolved over the last fifty-four years, his point remains: “Architecture must include engineering considerations, so that the design will be economica1 and feasible; but the emphasis in architecture is upon the needs of the user, whereas in engineering the emphasis is upon the needs of the fabricator.”

In other words, habitability, the quality of being “livable”, is a critical condition for an architecture. Two systems providing the exact same functionality may not be equivalent. The system providing the “better” (from the user’s perspective) quality of service will most likely be seen as the superior system. In some cases, quality of service concerns can even outweigh functional concerns.

Who, if not the software architect, is looking out for the livability of your system as a whole?

Form Follows Function on SPaMCast 331

SPaMCAST logo

I’m back for another appearance on Tom Cagley’s Software Process and Measurement (SPaMCast) podcast.

SPaMCast 331 features Tom on Agile Coaching, a discussion of my “Microservices vs SOA – Is there any real difference?” post and an installment of Jo Ann Sweeny’s column, “Explaining Communication”, dealing with communication channels.

Microservices vs SOA – Is there any real difference?

Microservice architecture has been the hot topic for 2014, so I suppose it’s appropriate that it be the subject for what I intend to be my last post until 2015. Last week, Kelly Sommers kicked off an active discussion of the nature of microservices vis-a-vis SOA:

This isn’t really a new observation. Before Lewis and Fowler published their final installment of the post that started the everyone talking, Steve Jones had already published “Microservices is SOA, for those who know what SOA is”. Even Adrian Cockcroft, in response to Sommers, noted:

And yet, they’re different. In a post written for Iasa, “Microservices – The Return of SOA?”, I quoted Anne Thomas Manes’ “SOA is Dead; Long Live Services”:

Successful SOA (i.e., application re-architecture) requires disruption to the status quo. SOA is not simply a matter of deploying new technology and building service interfaces to existing applications; it requires redesign of the application portfolio. And it requires a massive shift in the way IT operates. The small select group of organizations that has seen spectacular gains from SOA did so by treating it as an agent of transformation. In each of these success stories, SOA was just one aspect of the transformation effort. And here’s the secret to success: SOA needs to be part of something bigger. If it isn’t, then you need to ask yourself why you’ve been doing it.

As I stated in that post

Part of the problem may be that both SOA and microservices have aspects that transcend boundaries. Manes quote above makes it clear that SOA is concerned with enterprise IT architecture. Microservices are primarily an application architecture pattern.

Microservices can be reused by multiple applications, but need not be. SOA’s emphasis was at a higher level of abstraction. While the two share a great many principles, they apply them at different scales (application and solution architecture versus enterprise IT architecture).

Last weeks Twitter stream did produce some examples of principles that are, if not unique, then at least more heavily emphasized in the microservice style. From Marco Vermeulen:

Eugene Kalenkovich‘s post, “Can I Haz Name?”, captures the essence (in my opinion) of this style: “Independent Scalability, Independent Lifecycle and Independent Data”. It’s not about the lines of code, but about the separation of concerns within the context of the application. These same “independences” are important to SOA, but define a microservice architecture.

Accidental Architecture

Hillside Slum

I’m not sure if it’s ironic or fitting that my very first post on Form Follows Function, “Like it or not, you have an architecture (in fact, you may have several)”, dealt with the concept of accidental architecture. A blog dedicated to software and solution architecture starts off by discussing the fact that architecture exists even in the absence of intentional design? It is, however, a theme that seems to recur.

The latest recurrence was a Twitter exchange with Ruth Malan, in which she stated:

Design is the act and the outcome. We design a system. The system has a design.

This prompted Arnon Rotem-Gal-Oz to observe that architecture need not be intentional and “…even areas you neglect well [sic] have design and then you’d have to deal with its implications”. To this I added “accidental architecture is still architecture – whether it’s good architecture or not is another thing”.

Ruth closed with a reference to a passage by Grady Booch:

Every software-intensive system has an architecture. In some cases that architecture is intentional, while in others it is accidental. Most of the time it is both, born of the consequences of a myriad of design decisions made by its architects and its developers over the lifetime of a system, from its inception through its evolution.

The idea that an architecture can “emerge” out of skillful construction rather than as a result of purposeful design, is trivially true. The “Big Ball of Mud”, an ad hoc arrangement of code that grows organically, remains a popular design pattern (yes, it’s a pattern rather than an anti-pattern – see the Introduction of “Big Ball of Mud” for an explanation of why). What remains in question is how effective is an architecture that largely or even entirely “emerges”.

Even the current architectural style of the day, microservices, can fall prey to the Big Ball of Mud syndrome. A plethora of small service applications developed without a unifying vision of how they will make up a coherent whole can easily turn muddy (if not already born muddy). The tagline of Simon Brown’s “Distributed big balls of mud” sums it up: “If you can’t build a monolith, what makes you think microservices are the answer?”.

Someone building a house using this theory might purchase the finest of building materials and fixtures. They might construct and finish each room with the greatest of care. If, however, the bathroom is built opening into the dining room and kitchen, some might question the design. Software, solution, and even enterprise IT architectures exist as systems of systems. The execution of a system’s components is extremely important, but you cannot ignore the context of the larger ecosystem in which those components will exist.

Too much design up front, architects attempting to make decisions below the level of granularity for which they have sufficient information, is obviously wrong. It’s like attempting to drive while blindfolded using only a GPS. By the same token, jumping in the car and driving without any idea of a destination beyond what’s at the end of your hood is unlikely to be successful either. Finding a workable balance between the two seems to be the optimal solution.

[Shanty Town Image by Otsogey via Wikimedia Commons.]

What do we mean by “architecture”?

Some things last longer than others

Every systematic development of any subject ought to begin with a definition, so that everyone may understand what the discussion is about.

Marcus Tullius Cicero (196BC ‒ 16BC), De Officiis, Book 1, Moral Goodness (h/t to Glen Alleman, October 8, 2013 Quote of the Day)

One of the joys of the English language is the overloading of words with multiple meanings. While it’s not hard to start an argument over technical issues under normal circumstances, having multiple definitions to conflate makes it that much easier. Take, for example, the word “architecture”. While different dictionaries give slightly different definitions (e.g. Merriam-Webster Dictionary.com and Wiktionary), the common set of definitions boil down to:

While there is a relationship between these concepts, a person practicing architecture might create an architectural design using one or more architectural styles, there is enough differentiation to cause trouble if we don’t clarify our terms. Far from being an academic exercise, paying attention to semantics can actually save time and frustration when there is ambiguity present.

Architecture versus Design

There was interesting debate on what is an architect, the difference between design and architecture (no one really knows…
(Ilan Kirschenbaum, discussing a meeting of the Software Craftsmanship in Israel group)

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, as quoted by nearly everyone)

In the inaugural post of Form Follows Function, I noted the definition of architecture that I felt best applied across the realms of Application, Solution, and Enterprise Architecture. While researching the post “What’s driving your architecture?”, I found considerable discussion of the difference between architecture and design (in the sense of design decisions that are architecturally significant versus those that are not). Although the distinction might seem to be academic at first glance, it cuts to the heart of questions around the value of architecture and architects, particularly under Agile processes. This makes the confusion alluded to above by Ilan Kirschenbaum doubly worrisome.

Simon Brown, building on Booch’s comment above, provides important insights on the concept of design in “Disambiguating architecture”. Design “…exists to resolve a force on the system”, where force represents “…cost, scope, resources, timescales, requirements – anything you wish to take into consideration as part of your design selection”. He also notes that “…a design is one of a number of possible choices for resolving a particular force on the system”. Thus design, architectural or not, can be defined as making the optimal choice to satisfy the various forces impacting the matter at hand.

Rick Kazmon and Amnon Eden, writing for the Carnegie Mellon Software Engineering Institute, identified locality as the defining characteristic of architectural design in their article “Defining the Terms Architecture, Design, and Implementation”. Non-local specifications, applying to the system as a whole, constitute architecture in their opinion. According to Kazmon and Eden, “More generally, for each specification we should be able to determine whether it is a design statement, describing a purely local phenomenon (and hence of secondary interest in architectural documentation, discussion, or analysis), or whether it is an instance of an underlying, more general rule”.

Eden and Kazman, joined by Yoram Hirshfeld, further expanded on this definition in “Abstraction Classes In Software Design”, published in IEE Software Vol. 153, No. 4 (Aug. 2006). The authors identify global design decisions as strategic and local design decisions as tactical:

Strategic design statements [11] articulate design decisions that determine the primary behavioural and structural properties of a program (software system). Strategic decisions address global, system-wide concerns and carry the most consequential implications. Strategic decisions include the choice of programming paradigm [36] (‘object-oriented programming’), architectural style [17] (‘pipes and filters’), application framework [24] (‘Microsoft Foundation Classes’), component-based software engineering standards [40] (‘Enterprise JavaBeans’), and design principles (‘universal base class’), as well as assumptions that may lead to architectural mismatch [18] (‘The Softbench Broadcast Message Server expected all of the components to have a graphical user interface’) and law governed regularities [28] (‘every class in the system inherits from class C’). Because of the consequences they carry, Strategic decisions must be made early in the software development process and should be established explicitly before any detailed design is carried out.

In contrast, Tactical design [11] statements articulate design decisions that are concerned with a specific module. Tactical decisions often describe a pattern of correlations between one collection of modules (objects, procedures, classes etc.) and another. Intuitively speaking, Tactical statements are ‘local’ in the sense that their scope is limited to some part of the program and not outside it. Tactical decisions include the choice of design patterns [16] (‘Factory Method’), refactorings [15] (‘Replace Conditional With Polymorphism’), and programming idioms [5] (‘counted pointer’), and usually are taken much later than strategic design decisions in the software development process.

Although I broadly agree with the general rule of global = strategic and local = tactical, it should not be considered an absolute. It is possible for one segment of a system to have aspects that strongly influence the overall architecture (justifying Booch’s criteria for significance). This is the reason that I do not hold the opinion that functional requirements are design and non-functional are architecture.

Arnon Rotem-Gal-Oz, architecture manager at Nice Systems, identifies several aspects of architecture in his presentation “Software Architecture”. Architecture comprises the major components of a system; their relationships and interactions. Data and behavior of these major components is only relevant to architecture from the point of view of the interactions between these components. Like Booch, Rotem-Gal-Oz characterizes the architecture as being the most difficult parts of the system to change. Like Eden, Kazman, and Hirshfeld, he defines architecture as the design decisions that must be made earliest in the process.

The value of strategic, foundational design decisions should be obvious. Since these aspects of the system are both difficult and costly to change, there should be considerable incentive to make optimal choices. As noted by Kevlin Henney in “What is Software Architecture?” on developerFusion:

The issue is not whether or not a system has architecture, but whether its architecture is good or not. All systems have architecture, whether intentional or accidental, explicit or implicit, good or bad – even “no architecture” systems have architecture!

Having related architecture to cost of change, we have a simple way of evaluating architectural quality. It is not that a good architecture makes a system cheap to create; it is that it is also cheap to evolve. In other words, a good architecture is one in which the significance of design decisions is minimised. You are free to change many aspects of a system without the fear that such changes are challenging, costly or create a cascade of bugs. A good architecture is therefore a sustainable one.

Given the criticality of these design decisions, it makes little sense to leave them to chance. Sustainable, flexible architecture is unlikely to emerge organically. Sufficient planning and coordination will be needed from someone in the architect role (regardless of whether the role is full or part-time). Localized design decisions can then be made within that framework in a decentralized manner.

Occasionally I hear people still raising the agile mantra against Big Design/Requirements Up Front. The thing is that Agile Manifesto never said to intentionally bury your head in the sand with regards to the purpose of the system. It was a push-back against spending months in analysis without anything but documents coming out, but the goal was to reach a middle ground. Nobody ever said “no design up-front” or “no requirements up front”.
(Udi Dahan from “A CQRS Journey – with and without Microsoft”)