Pragmatic Application Architecture

I saw a tweet on Friday about a SlideShare deck that looked interesting, so I bookmarked it to read later. As I was reading it this morning, I found myself agreeing with the points being made. When I got to the next to the last slide, I found myself (or at least, this blog) listed alongside some very distinguished company under “Reading Material”.

Thanks, Bart Blommaerts and nice job!

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”.

It worked in my head

It started with a tweet from Dan North:

This triggered a discussion on the nature of architecture versus design, to which Ruth Malan contributed, linking to one of her journal entries (which has inspired another post I have queued up to follow this one). My first takeaway from the discussion, however, was a tangential one: beyond their value in communicating decisions, design artifacts serve to assist in making those decisions in the first place. Rather than being just an output of the design process, they can serve as an input as well.

Dan North’s observation that writing the document describing how to use the application was causing him to simplify it should not surprise. I’ve often found that writing up a problem allows me to get out of my head and see it more clearly (I can’t count how many unsent emails/unposted forum comments have resulted from this). My first sequence diagrams were put together for my own use, to ensure that I understood the interactions involved in code I was working on. Writing and/or diagramming forces you to organize your thoughts and makes it more difficult to gloss over issues in your design.

Terry Bunio’s latest post discusses using visualization to design a data warehouse. These visualizations provide a powerful tool to both define and refine the design as well as communicate it to customers and development team.

The use of visualization in this manner isn’t restricted to design. One of the tenets of Kanban is being able to visualize the process. This visualization forces issues into focus, rather than allowing them to hide in the background noise.

Most of those reading this should be familiar with “but it worked on my machine”, indicating that the developer likely failed to do the due diligence required to make sure his/her code deployed correctly. Using design artifacts to organize and visualize your design makes it easier to evaluate. After all, you don’t want to be in the position of saying “but it worked in my head”.

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.