Designing Communication, Communicating Design

The Simplest metamodel in the world ever!

We work in a communications industry.

We create and maintain systems to move information around in order to get things done. That information moves between people and systems in combinations and configurations too numerous to count. In spite of that, we don’t do that great a job of communicating what should be, for us, extremely important information. We tend to be really bad at communicating the architecture of our systems – structure, behavior, and most importantly, the reasons for the decisions made. It’s bad enough when we fail to adequately communicate that information to others, it’s really bad when we fail to communicate it to ourselves. I know I’ve let myself down more than once (“What was I thinking here?!”).

Over the past few days, I’ve been privileged to follow (and even contribute a bit to) a set of conversations on Twitter. Grady Booch, Ivar Jacobson, Ruth Malan, Simon Brown, and others have been discussing the need for architectural awareness and the state of communicating architecture.

This exchange between Simon, Chris Carroll and Eoin Woods sums it up well:

First and foremost, an understanding of what the role of a software architect is and why it’s important is needed. Any organization where the role is seen as either just a senior developer or (heaven help us!) some sort of Taylorist “thinker” who designs everything for the “worker bee” coders to implement, is almost guaranteed to be challenged in terms of application architecture. Resting on that foundation of shifting sand, the organization’s enterprise IT architecture (EITA) is likewise almost guaranteed to be challenged barring a remarkable series of “happy accidents”. The role (not necessarily position) of software architect is required, because software architecture is a distinct set of concerns that can either be addressed intentionally or left to emerge haphazardly out of the construction of the system.

Before we can communicate the architecture of a system, it’s necessary to understand what that is. In “Software Architecture: Central Concerns, Key Decisions”, Ruth Malan and Dana Bredemeyer defined it as high impact, systemic decisions involving (at a minimum):

  • system priority setting
  • system decomposition and composition
  • system properties, especially cross-cutting concerns
  • system fit to context
  • system integrity

I don’t think it’s possible to over-emphasize the use of “system” and “systemic” in the preceding paragraphs. That being said, it’s important to understand that architectural concerns do not exist in a void. There is a cyclic relationship between the architectural concerns of a system and the system’s code. The architectural concerns guide the implementation, while the implementation defines the current state of the architecture and constrains the evolution of future state of the architecture. Code is a necessary, but insufficient source of architectural knowledge – it’s not enough. As Ruth Malan noted in the Visual Design portion (part II) of her presentation at the Software Architect Conference in London a year ago:

Slide from Ruth Malan's presentation on Visual Design

While the code serves as a foundation of the system, it’s also important to realize that the system exists within a larger context. There is a fractal set of systems within systems within ecosystems. Ruth illustrated this in the Intention and Reflection portion (part III) of the presentation reference above:

Slide from Ruth Malan's presentation on Intention and Reflection

[Note: Take the time to view the entirety of the Intention and Reflection presentation. It’s an excellent overview of how to design the architecture of a system.]

The fractal nature of systems within systems within ecosystems is illustrated by the image at the top of the post (h/t to Ric Phillips for the reblog of it). Richard Sage‘s humorous (though only partly, I’m sure) suggestion of it as a meta-model goes a long way towards portraying the problem of a language to communicate architecture.

Not only are we dealing with a nested set of “things”, but the understanding of those things differ according to the stakeholder. For example, while the business owner might see a “web site” as one monolithic thing, the architect might see an application made up of code components depending on other applications and services running on a collection of servers. Maintaining a coherent, normalized object model of the system yet being able to present it in multiple ways (some of which might be difficult to relate) is not a trivial exercise.

Lower-level aspects of design lend themselves to automated solutions, which can increase reliability of the model by avoiding “documentation rot”. An interesting (in my opinion) aspect that can also be automated is the evolution of code over time. What can’t be parsed from the code, however, is intention and reasoning.

Another barrier to communication is the need to be both expressive and flexible (also well illustrated by Richard’s meta-model) while also being simple enough to use. UML works well on the former, but (rightly or wrongly) is perceived to fail on the latter. Simon Brown’s C4 model aims to achieve a better balance in that aspect.

At present, I don’t think we have one tool that does it all. I suspect that even with a suite of tools, that narrative documents will still be way some aspects are captured and communicated. Having a centralized store for the non-code bits (with a way to relate them back to the code) would be a great thing.

All in all, it is encouraging to see people talking about the need for architectural design and the need to communicate the aspects of that design.

Modeling the Evolution of Software Architecture

Herve Lourdin‘s tweet wasn’t aimed at modeling, but the image nicely illustrates a critical deficiency in modeling languages – showing evolution of a system over time. Structure and behavior are captured, but only for a given point in time. Systems and their ecosystems, however, are not static. A map of the destination without reference to the point of origin or rationale for choices is of limited use in communicating the what, how, and why behind architectural decisions.

“The Road Ahead for Architectural Languages” on InfoQ (re-published from IEEE Software) recently noted the following reasons for not using an architectural language (emphasis added):

  • formal ALs’ need for specialized competencies with insufficient perceived return on investment,
  • overspecification as well as the inability to model design decisions explicitly in the AL, and
  • lack of integration in the software life cycle, lack of mature tools, and usability issues.

All of the items in bold above represent usability and value issues; a failure to communicate. As Simon Brown observed in “Simple Sketches for Diagramming Your Software Architecture”:

In today’s world of agile delivery and lean startups, some software teams have lost the ability to communicate what it is they are building and it’s no surprise that these teams often seem to lack technical leadership, direction and consistency. If you want to ensure that everybody is contributing to the same end-goal, you need to be able to effectively communicate the vision of what it is you’re building. And if you want agility and the ability to move fast, you need to be able to communicate that vision efficiently too.

Simon is a proponent of a sketching technique that answers many of these communication failures:

The goal with these sketches is to help teams communicate their software designs in an effective and efficient way rather than creating another comprehensive modelling notation. UML provides both a common set of abstractions and a common notation to describe them, but I rarely find teams that are using either effectively. I’d rather see teams able to discuss their software systems with a common set of abstractions in mind rather than struggling to understand what the various notational elements are trying to show.

Simon’s colleague, Robert Annett, recently posted “Diagrams for System Evolution”, which proposes using the color-coding scheme from diff tools to indicate change: red = remove, blue = change, green = new. Simon followed this up with two posts of his own, “Diff’ing software architecture diagrams” and “Diff’ing software architecture diagrams again”, which dealt with applying Robert’s ideas to Simon’s structurizr.com tool.

Simon’s work, coupled with Robert’s ideas, addresses many of the highlighted deficiencies listed above (it even touches on the third bullet that I didn’t emphasize). Ruth Malan’s work also contains some ideas that are vital (in my opinion) to being able to visualize and communicate important design considerations – explicit quality of service and rationale elements along with organizational context elements. A further enhancement might be incorporating these into a platform that can tie elements of software architecture together with elements of solution and enterprise architecture, such as the one proposed by Tom Graves.

Given the need for agility, it might seem strange to be talking about modeling, design documentation, and architectural languages. The fact is, however, that many of us deal with inherently complex systems in inherently complex ecosystems. Without the ability to visualize a design in its context, we run the risk of either slowing down or going down. Not everyone can afford to “move fast and break things”.

Communicating Visually

In my last post, I noted some of the ways in which I use modeling (mostly UML) to capture and communicate aspects of a design. As I was finishing the post, Simon Brown and I shared the following exchange on Twitter:

I find this bemusing for a number of reasons, not least of which is my somewhat iconoclastic nature. It’s my belief that form follows function; that much is pretty hard to miss. Even more so, I believe that form should never trump function. Diagrams are a means of communication, not an end in themselves. Being afraid to use a communication tool just because you’re afraid of “breaking the rules” is as shortsighted as producing artifacts that are syntactically correct but infeasible in practice. Design artifacts, whether intended as blueprints for work in progress or documentation of the system’s current state, must enhance an understanding of the system. If they fail at that aspect, then any other consideration is moot.

the Udder diagram

The other side of the coin is that if the artifact serves to communicate effectively, whether it conforms to a particular modeling language or not is irrelevant. I used the diagram on the right (affectionately dubbed “the udder diagram”) a few years back to communicate the strategy of integrating four line of business customer portals with four back-end systems using a messaging platform. It served to illustrate that strategy to both business and technology, across all levels from development teams to channel presidents. Refusing to use it because it wasn’t part of some standard notation would have made no sense at all.

It is possible, however, to over-communicate. The stereotypical architect who spends time drawing pictures of systems that will never be has its roots in those who try to micro-manage the design. Even if it were possible to design every aspect of the system up front in detail, it would be inefficient. From the time wasted modeling duplicate (or nearly so) interactions to the bottleneck introduced by relying on the architect for all design, a useful tool can be turned into an impediment. Little wonder teams have thrown the baby out with the bath water. That being said, it is a waste to abandon useful techniques because of the potential for abuse. The key is to find a happy medium.

In “C4: context, containers, components and classes”, Simon Brown discusses a lightweight modeling process designed to capture architecturally significant information across different levels of detail using a Class Responsibility Collaboration (CRC) card metaphor. Context diagrams are used to picture the system under development in context with the rest of the technology environment (i.e. integrations) and those who will be using the system. Container diagrams capture the execution environment of the system: sites, services, databases, etc., visually depicting the major pieces of the system and their interconnections. Component diagrams illustrate the major groups of code that make up the containers. Class diagrams are used only when warranted. This system, which concentrates on the information and not the syntax or tool, makes perfect sense.

In the “Getting there from here” post, I mentioned a number of different UML diagrams I use during the architectural design process: use case diagrams to capture “who does what”, class diagrams to capture the key “things” the system deals with, package diagrams to illustrate system structure and activity diagrams to document the users’ interactions with the system in the course of a particular use case. All of these tend to be high level and relatively static aspects of the system. Likewise, they are aspects that are not readily reverse-engineered from code. As such, I maintain these as persistent artifacts that live from one release to the next for the life of the application.

When I’m doing lower-level design, class, activity, and sequence diagrams can be useful as well. These, however, I consider to be transient artifacts, useful for the moment, but not worth maintaining over the long-term. Particularly when you have access to tools that can synchronize with the code (I use both Visual Studio’s built-in features as well as Altova’s UModel), effort spent maintaining these types of diagrams is wasted. It makes far more sense to re-generate from the authoritative source: the source.

In my opinion, keeping a few simple principles in mind makes the difference between effective modeling versus just drawing pictures. First and foremost, is to focus on communication. Being understood is more important than being “right” (at least in terms of using the notation/tool). Next in importance is to know when to stop. Just enough detail provides value; too much extraneous information can cause confusion at worst and at best introduces delay. Lastly, know what to keep and what to throw away. Anything that illustrates existing code should be generated from that code rather than maintained manually.

Used correctly, modeling can be a powerful tool for communication. Communication and understanding are force-multipliers that contribute to success. A picture may well be worth a thousand words. It’s certainly quicker to put together (not to mention comprehend) a picture than a thousand words.