Archive for the ‘Architecture’ Category.

Guidelines for the System Metaphor

Extreme Programming’s system metaphor, as traditionally presented, has a fatal flaw. It has a nudge which encourages teams to describe the system at too high a level, as one large monolithic thing. The result is nearly always the same: a generic metaphor that doesn’t really describe the software and provides next to no guidance for implementation. This has led many in the Agile community, including Kent Beck, XP’s creator, to abandon the system metaphor entirely. I have three big worries with this.

  1. While Beck may have changed his mind about many practices from XP, both versions of Extreme Programming, available in two editions of Extreme Programming Explained, are readily available and actively promoted by the publisher.  Treating both editions as equals curbs the adoption and spread of better practices.  The metaphor lives on in spite of being abandoned by its creator.
  2. Agile teams, while improving, have been generally slow to adopt now common knowledge on software architecture.  Deemphasizing the system metaphor has created a black hole in the software lifecycle around architecture and design.  Those teams that are software architecture-focused have a hard time figuring out how to remain agile while incorporating architecture best practices.
  3. Metaphors aren’t going anywhere.  They are a natural reaction to describing complex things – in literature, in life, and in software.  Ignoring the system metaphor makes it more difficult to use effectively.

So rather than fighting the metaphor as a tool for describing software architectures, we should embrace it.  It’s time to refresh the system metaphor by combining current best practices from software architecture with what we know works for metaphors in literature.

The System Metaphor, Refreshed

The ultimate goal of the system metaphor is to create a common vision and vocabulary for discussing and reasoning about a system – with all stakeholders.  This stands for the refreshed system metaphor too.  Communication is king in the abstract world of software architecture, and so communication is the ultimate metric for determining whether a system metaphor is good or bad.  Metaphors that enhance communication are better than ones that confuse or mislead the team.

To this end, there are five guidelines for evaluating metaphors to determine their fitness as aids for describing software architecture, and one corollary for sharing and using metaphors.

A good metaphor:

  1. Represents a single view.
  2. Deals with only one type of structure.
  3. Gives clear guidance concerning design decisions.
  4. Sheds light on system properties.
  5. Draws on a shared experience.

Corollary:  Even a good metaphor still requires explanation.

A good metaphor represents a single view.  It is now common practice when thinking of software architecture to describe a system using multiple views.  Views are like taking pictures of a 3D object.  While it would be nice to see the whole object, because a picture can only capture two dimensions at a time you’ll need several pictures to get a good representation of the object.  What this means for the system metaphor is that you will need more than one metaphor to adequately describe the system.

A good metaphor deals with only one type of structure.  Structures are the building blocks for an architecture and there are three basic kinds of structures in the software world.  Static structures deal with code – classes, modules, layers, and so forth.  Dynamic structures deal with running code – objects, tiers, processes, connections (e.g. a client connecting to a server) and so on.  Physical structures deal with, well, things in the real world, the hardware – computers and servers, routers and switches, as examples.

When creating a metaphor it should be a single view and deal with only one kind of structure at a time.  This aids with communication and reasoning by keeping things simple and by helping you compare apples to apples.  Use metaphors of things (i.e. nouns) to represent static structures.  Use metaphors of actions (i.e. verbs) to represent dynamic structures.  Physical structures are less abstract and are generally best served by being represented directly.

A good metaphor gives clear guidance concerning design decisions.  The metaphors you use should provide a guiderail for implementation by clearly communicating design decisions, background, and rationale.  Great metaphors will make it easy to connect higher-level, architecturally relevant design decisions and guidelines to the lower-level, implementation oriented design decisions.  Maintaining architectural integrity is, after all, a team responsibility.

A good metaphor sheds light on system properties.  One of the most important reasons to think about the architecture of a system is ensure that desired properties are promoted by the design. These properties are commonly articulated as quality attributes or quality requirements.  Having a clear understanding for why a set of structures and guidelines were chosen helps everyone to continue to support those properties in their low-level design decisions.

System properties are communicated through storytelling with the metaphor as the impetus for the story.  A good metaphor will make it easy to tell a story about desired (or undesired) system properties and how the design promotes (or inhibits) the properties.

Software architecture diagram showing use of the layered style as a bento box metaphor.

A good metaphor draws on a shared experience.  Shared experiences are the bedrock of any good metaphor.  Metaphors create a new vocabulary for discussing the architecture of a system and often rely on subtle nuances for sharing meaning.  For the metaphor to be effective, everyone on the team must have the background necessary to not only understand the metaphor but also understand the implications of the metaphor.  This shared experience might be technical in nature (documented architectural styles and patterns are an excellent source for a shared experience) or can be non-technical such as references to pop culture, movies, and food.

A common experience is also created through the act of choosing a metaphor and the best metaphors are those that the team arrives at together.  Metaphors bring with them a payload of information, pointers to design decisions, whiteboard discussions, arguments, code, guidelines, and many other important ideas important to a particular part of the system.  Having a relatable metaphor better facilitates communication and more easily brings to mind this history and data payload.

Corollary:  Even a good metaphor still requires explanation.  No metaphor can survive in isolation.  It is naïve to think that a metaphor, even a great one which satisfies all the other guidelines, will immediately make sense to a person who is hearing it for the first time.  Take the time to explain the metaphor to your team and create the shared experience necessary for everyone to relate to it.  Doodle on the whiteboard.  Sketch on paper.  Show them code.  Talk about quality attributes.  Once the intent and rationale behind the metaphor is commonly understood you may not need any documentation since the metaphor should immediately bring to mind all the important structures, guidelines, and properties relevant to that view of the system.

System Metaphor, a Great Addition to your Silver Toolbox

I’ve found the refreshed system metaphor to be extremely helpful, but it is not a panacea for agile architecture – it is no silver bullet.  The refreshed system metaphor is, however an excellent addition to your silver toolbox.  With this set of guidelines the system metaphor becomes, in my opinion, a viable tool for describing the architecture of a software system in many situations.  But your mileage may vary for non-collocated or especially large teams.  In these cases, metaphors will still be useful (they’ll come up naturally anyway), and you will need to supplement the metaphors your team uses with additional documentation.  A little documentation (the right documentation) never hurt anyone and even a lightweight architecture description document that assists with communication and understanding is worth its weight in gold.

Making metaphors that matter is difficult work.  It takes iteration and breakthrough insights over time to really discover the great metaphors that make sense.   With this set of guidelines in hand, knowing when you’ve discovered a good metaphor will be easy.

The system metaphor is dead!  Long live the system metaphor!

These guidelines were born from reflection on a recent project in which we used the system metaphor, as presented here, to effectively describe the architecture of our system as we built it. The guidelines, along with examples, were presented as an experience report, “Making Metaphors that Matter” (PDF), at the Agile2011 conference in Salt Lake City, UT. Slides from our talk are also available (PDF). Don’t hesitate to get in touch with questions, feedback, or insights using the comments here, email (mkeeling[at]neverletdown[dot]net), or twitter (@michaelkeeling).

See you at Agile2011 in Salt Lake City!

Here’s an introduction to my Agile2011 talk. Come hang out with me for 30 minutes on Tuesday, August 9 at 2:00pm in the LA Teton and bring your thoughts and questions about agile, architecture, and the system metaphor. And please show your interest on the conference schedule or twitter!

The system metaphor is one of the 12 key practices from XP and it is probably also the most controversial. Researchers at the Software Engineering Institute have observed that, of all the practices from Extreme Programming, the system metaphor is used the least. Other research done on graduate students at Carnegie Mellon concluded that natural language metaphors are useless for either communication or architecture design.

These are damning findings for the system metaphor, and yet on nearly every technical team with which I’ve built software, natural language metaphors were a daily part of how we communicated with each other. Maybe it has to do with the inherent abstractness of software, something that can’t be touched or tasted, only described. Maybe my teams have simply lacked the technical vocabulary needed to communicate in more precise words.

In spite of this nearly all of these projects were successful. Certainly there must be some merit in using natural language metaphors to describe a software system?

This got us thinking. Metaphors frequently come up in our everyday lives quite naturally and they are used effectively in books and movies. Is there something special about software that makes metaphors not work? Why would folks have such a hard time applying the system metaphor in practice when it’s obvious that metaphors in general are so effective in other places throughout our lives?

The simple answer is that we’ve been doing it wrong this whole time.

There’s nothing wrong with the system metaphor. It’s our application of the technique that has been wrong.

What’s missing from the prevailing literature on the System Metaphor is clear guidance that shows what a good metaphor should look like. Without this guidance, and without the background in software architecture to backfill this knowledge, teams are left alone to cobble together our own metaphors based on the limited information available on the Internet; a web of information that is largely an echo chamber of the same few sentences from the XP book. It should be no wonder that the system metaphor is unsuccessful in many cases.

What does a good metaphor look like? How do you know if you’ve created an effective metaphor? When should you create or update a metaphor? Why is one metaphor better or worse than another metaphor?

In looking for answers to these questions we combined what we knew about literary metaphors and software architecture practices to come up with a clear set of guidelines for the System Metaphor. These guidelines completed the System Metaphor definition and provided us with the guidance we needed to effectively design, analyze, and communicate the architecture of the software system we were building. We were no longer fighting our natural tendencies to create metaphors but instead were embracing them. And we created a more solid architecture as a result.

Interested in hearing more? If you’re going to Agile2011, why don’t you come to hear my talk? During this session I will explore our six guidelines for making better metaphors and walk through examples from our project. In only 30 minutes you’ll learn how to make metaphors that matter to your project, your team, and the system you are building in a way that improves team communication and encourages architectural thinking. This is a session you won’t want to miss!

I am speaking at Agile2011 in Salt Lake City, UT

Exploring the Design Space

In Choosing a Software Design Strategy I proposed that your understanding of the design space will determine what design strategies are appropriate for your project. That is, how much you know about the problem domain and solution space will determine how much design work is appropriate for your project. Rather than fussing over dogma, the power is clearly in your hands. If you feel uncomfortable with what you are capable of designing, then you need to further explore the design space! Otherwise, you are free to design in a way that is appropriate to your understanding of the system and a way that makes sense to your team be it Big Design Up Front or a more minimalistic design approach.

Personally I’m a visual person so having a graphical representation which shows how to think about what I know about the design space is extremely helpful to me. In this graphical representation, there is a real boundary which will eventually prevent me from exploring the infinitely large design space. This boundary is formed by things like time, budget, and schedule as well as thought stuff such as your team’s training or overall knowledge and the existence of research or even existing technologies. For example, once I was involved with a project that required large amounts of data to be transferred from Australia to the United States in real-time with an aggressive deadline, on the order of tens of milliseconds. Crunching the numbers, we quickly realized that this was completely impossible with the existing telecommunications infrastructure. In fact, the only technology we could find which might promise this kind of performance was entangled quantum particles which are only today becoming a reality…sort of. The solution boundary in this case severely limited our ability to find a viable design. Sometimes you can move these real boundaries, for example by increasing the budget and schedule or hiring a consultant, but any system you design will come from your understanding of the area in the highlighted space shown below.

The Rational Design Space

Another interesting thing about this representation is that it’s actually parametric. The X and Y axes will tell you what you know, but your understanding of the problem you aim to solve and the solution you are using to solve it will change over time. It’s also possible that you might not start at (0, 0) in every case. And the way you learn about the design is going to be different every time, rarely (if ever) taking the direct, efficient route to enlightenment. As time goes on, as you learn more about the problem and solution, you’ll create a parametric curve, the shape of which will give you a pretty good idea of where your knowledge gaps might be. And thinking about design in this way exposes some interesting things about what you know, and what you might need to learn in order to make a satisficing design.

Design Knowledge over Time

So if you have a design curve that starts off almost horizontal, it means that you know a lot about the problem but don’t know very much about solutions. Teams with lots of specific domain knowledge might face a curve like this. Most of the projects I did with the US Navy started with a curve that looked like this. The problems the Navy was trying to solve were well understood and the teams were initially made up of veteran subject matter experts. One of my jobs then was to help understand how to solve these well understood problems using more recent advances in hardware and software.

A curve which starts off steep presents the exact opposite case. Here the team has plenty of knowledge about possible solutions but knows very little about the problem. This is the case with most software development teams. We’re experts in building software and in most cases, when someone comes to us with a problem they want a software solution. The team’s main focus will be on understanding requirements and then applying their software engineering knowledge in creating a solution. A great example of this scenario is web development shops who specialize in creating web applications for clients. For these teams, every solution will involve some kind of 3-tiered system, probably using one of a handful of languages the team is an expert in. Now it’s just a matter of understanding the problem so they can iron out the specifics of the solution.

Design space - knowledge discovery opportunities

Most of the time your team is going to have a pretty good mix of knowledge, and as you work to complete the project you’ll embark on a circuitous journey through the design space, eventually coming to a point where you’ll feel comfortable moving forward with design and full scale development.

Your team will have some base knowledge at the start of the project. From there you’ll start to explore requirements which might lead you to thinking of certain solutions. Of course any solution will involve trade-offs which will expose new problems to consider so it’s back to the client to talk about the positives and negatives of one solution over another (quality attribute scenarios work great in this situation). As you explore these new problems, you’ll gain new knowledge which will then help you learn even more about the solution. Throughout this journey you might create prototypes, architecture descriptions, sketches, or code stubs. Each of these things will serve as a communication aide for your team and clients and give you tangible evidence of your understanding of the design space.

Exploring the design space - knowns and unknowns

The ultimate goal of this line of thinking is to figure out a better way to understand how to effectively explore the design space so you can more effectively reach a point when you have enough knowledge to be able to move forward with implementation. At some point, you’ll feel comfortable with what you know and create an appropriately detailed design. Or maybe you’ll just jump right into implementation. Exploration might take a few minutes or several weeks, all depending on what you already know about the problem and potential solutions, not to mention the size of the design space that needs exploring (more space implies more complexity and bigger systems). You might leave large swaths of the design space unexplored when you create your design or move onto implementation or you might explore everything fully. Regardless of your knowledge, it is important to realize that the amount of detail you use in your design and when you do that design work – the design strategy you choose – is an independent matter but your knowledge will limit your design capabilities.

The awesome part about thinking about design in this way is that even though you’ve moved on to a different phase of your project’s lifecycle, your knowledge and understanding of the design space will not cease. You’ll continue to learn more about the problem and solution with each step of implementation until the project ends. And by the end you will have the most complete understanding of the problem and solution yet. Of course, this will also be the time when this understanding is least helpful to you since the project is over! The essential key then is to apply methods which help you to quickly and efficiently understand when enough is enough so you can create useful plans, organize your team, and begin implementation with confidence that you will succeed.

Choosing a Software Design Strategy

I was reading an article from the Joel on Software archives and was struck by this quote from The Project Aardvark Spec:

I can’t tell you how strongly I believe in Big Design Up Front, which the proponents of Extreme Programming consider anathema. I have consistently saved time and made better products by using BDUF and I’m proud to use it, no matter what the XP fanatics claim. They’re just wrong on this point and I can’t be any clearer than that.

When thinking about design there are two extremes pivoting around how much up front design work needs to be done before you start writing code. Proponents of up front design point out, as Joel has in the quote above, that making changes in the design is a lot cheaper in a 20 page design document than a partially or fully implemented system. With a solid plan you stand a better chance of not painting yourself into a corner and avoid having to make expensive design changes in the code later. Opponents of BDUF worry greatly about analysis paralysis, which can severely delay a team’s ability to provide working software to the client. Codified in this thinking are the assumptions that clients don’t really know what they want until they see it and that only by getting working software in the hands of users can we understand whether a proposed solution is a good enough solution. To these folks, writing a design document is wasted effort because they don’t know what they want and they believe to their core that things are going to change anyway.

Both of these perspectives are correct. Both of these perspectives are also wrong. Since everyone loses when thinking in extremes and ultimatums, let’s figure out what is really going on.

Choosing a Software Design Approach: Theory

Building software falls into an interesting case of problems known as wicked problems. This means basically that there are many possible solutions and that no solution is really “right” or “wrong” only “better” or “worse” given your current understanding of the problem. Further each problem is essentially unique, there isn’t an explicit stopping rule, and as the designer you will be held liable for consequences of your solution.

With this in mind, in thinking about software design there are two variables which will determine how you go about designing a solution.

  • How well do you understand the problem domain?
  • How well do you understand the solution space?

In the software world, understanding the problem domain means thinking about technical constraints, functional requirements, quality attributes, and business constraints. Understanding constraints is critically important since these will define some of the boundaries of the solution space. Functional requirements deal with what the system will do while quality attributes deal with how a system should behave when performing certain functions. Finally business constraints are things the customer simply requires of a solution usually for business reasons (a common example is a budget or delivery date).

The solution space is a multi-dimensional landscape filled with nearly limitless possibilities. As the designer it is your job to figure out how to navigate this space in search of a solution to a problem. Your current understanding of the problem limits your ability to see solutions and often the fitness of a solution can only be understood in reference to another possible solution. I imagine the solution space as a mountain range and my job as the designer is to find the “best” mountain for my client. Of course some mountains might block my view from others which means I may have to climb a peak just to see a better solution. This implies that my understanding of the problem dictates my understanding of potential solutions and that my understanding of the solution will yield further insights into the problem. This is one reason why it is often helpful to get working software in front of users quickly.

Graphical depiction showing how a team's knowledge of the soultion space and problem domain will be bounded by constraints prevent fully rational designs.

When designing something we have a natural tendency to prefer making rational design decisions where, after careful examination of all information we choose the best or optimized solution. To make a rational choice requires not only that we know everything about the problem domain but also everything about every possible solution to the problem. Both business constraints, by constraining time or money, and shortcomings in the human brain limit on our ability to seek this knowledge creating a boundary around which a solution must be found. And it is in this world of bounded rationality that we must find a solution for our customer’s problem. Searching for a solution then is not as much a matter of optimization (finding the “absolute best”) as it is a matter of satisficing, finding the best solution with the information currently available. To complicate matters further, an individual’s understanding of the problem domain and solution space is relative to that individual’s experience and capabilities, the size of the problem, and the complexity of the solution.

When designing software it’s natural to want to move as far up the knowledge curve, get as close to making a rational, optimal design, as possible. This tendency stems from our instinctual preference to avoid loss [1]. In other words, designers assume that an optimal solution exists and so are predetermined to reject less than optimal solutions.

Choosing a Software Design Approach: Application

In the software design world there are four basic types of design strategies.

  • Planned Design: All design is completed before beginning implementation. Often referred to as Big Design Up Front by detractors and associated with waterfall lifecycles. The essential assumption is that you can fully design a system before beginning construction.
  • Minimally Planned Design: Some design is completed before beginning implementation. Sometimes referred to as Little Design Up Front. In using this strategy you acknowledge that some change is likely to occur but still want to avoid painting yourself into the obvious corners.
  • Evolutionary Design: The design of the system grows as the system is implemented , but growth is deliberate and controlled by experienced engineers and proven engineering practices such as reference designs and refactoring. At least some requirements are usually specified in the beginning but it is not expected to be exhaustive.
  • Emergent Design: The design of the system is allowed to occur organically as the system is implemented without specific intentions.

Graphical representation showing when specific design strategies are applicable based on design stabilty and the amount of desired planning

The design strategies appropriate for your team to choose is going to be determined by the amount of risk remaining in the bounded knowledge graph. Less risk implies that you anticipate less change (or at least that you feel you can deal with the change reasonably) and the more options you will have in choosing a design strategy. Choosing a design strategy then is a matter of deciding the degree to which your team would like to plan within the determined appropriate strategies. The amount of planning will depends on your team’s preferences and experience, or can be driven by customers’ business needs. From a theory perspective, the amount of planning appropriate to the project is directly proportional to how much you know about the problem domain and the solution space. In other words, the less you know about a problem and the fuzzier the solution seems to you, the less capable you will be in making planned designs. As designers we run into problems in our designs when we are wrong about what we think we know about the problem domain or solution space. Unfortunately as eternal optimists, software engineers get these things wrong often.

Don’t feel comfortable with the design strategies appropriate for your project? Remember that the appropriateness of a design strategy is based on your current understanding of the solution space and problem domain. Therefore, to make more design strategies available to your team you must learn more about the solution space and problem domain. I find that examining the project risks is the best way to determine what you think you know about the problem domain and solution space. Understanding the engineering risks your project faces also serves as a blueprint for moving along the knowledge curve. For example, if your team feels that they don’t know enough about the problem based on the identified and prioritized risks, you can increase your knowledge about the problem domain. On the same token, if the team feels there is a lot of risk concerning the solution space you can explore different designs, run experiments, or create prototypes for your users to try. Another option other than looking at risk is to use a design process such as Architecture Centric Design Methodology (ACDM). ACDM is a staged design process that encourages teams to explore the design space through experiments by addressing issues in proposed designs. ACDM strongly focuses on quality attributes and will nudge your team toward a planned design strategy but the process can be adjusted to use a different design strategy, if that is something your team strongly desires, by adjusting the go/no-go criteria between stages.

Remember too that you learn more about the problem and solution as you implement the system. So by the end of the project there will be no risk, you’ll know everything about the system you can, and you’ll have all the information necessary for a great (and practically useless) planned design.

The Project Aardvark Design Approach

Let’s apply this information to Project Aardvark and figure out why Joel is such a strong supporter of BDUF at Fog Creek Software. Project Aardvark, like most other software systems developed at Fog Creek, is a developer tool. This means that the folks developing the system are also going to be at least one of the groups of end users. We can assume based on Fog Creek’s hiring strategies that the developers are pretty smart. Further, Aardvark falls into a class of problems which has been well studied meaning there are examples available for study and some folks at Fog Creek may have even implemented similar (but not identical) systems or subsystems.

Determining what design strategies are approporate for Project Aardvark based on knowledge concerning the design.

The implication is that the Project Aardvark problem domain is well understood and the solution space doesn’t need much exploration because Joel doesn’t perceive much risk in the solution. Since Joel has a firm grasp on the problem domain and since he feels confident about the solution space, he doesn’t anticipate much change in the design throughout development. Based on the information Joel has available about the project relative to his knowledge and experience with the problem domain and solution space, a planned design strategy is appropriate for this project. Joel could use other approaches further down the application curve too, but since Joel has relevant experience with planned design, the design probably won’t be that big (in fact it was less than 20 pages), and the Fog Creek team is used to following planned designs, planned design is probably a good fit for Project Aardvark.

One last note. Bounded rationality implies that the planned approach to design may not always be possible. There is a limit based on the size of the problem domain, solution space, and business constraints (especially time and resources available) that may prohibit you from effectively using Big Design Up Front. In other words, it may not always be possible to be high enough on the knowledge curve for a planned approach to make sense. Opponents of BDUF will tell you that most software falls into this category. In the case of Project Aardvark, the system was relatively small and Joel ensured that he had plenty of resources and time for exploring the solution space. It is critically important to understand where the boundaries that might prevent you from rational design are. Since we prefer rational optimization over decision making with less information, failing to recognize these boundaries will result in analysis paralysis.

By understanding some of the theory behind design decision making it’s easier to know where in the spectrum of possible design strategies your project belongs. Examining a project’s engineering risks is a relatively simple and repeatable way to determine where you are on the knowledge curve for a project. Now it’s possible to move your team up the knowledge curve, as necessary, to reach a point where you feel comfortable with the risks your project faces. You move along this curve by addressing the project’s risks through prototyping, research, experiments, evaluating proposed designs, and interacting with the customer. You could also use a specific design process such as ACDM. It is important to recognize that by moving up the knowledge curve you are necessarily moving your team closer to being able to use a planned design strategy. Your location on the knowledge curve will determine which design strategies you can use but you still need to determine which makes the most sense for your team and the project. Finally, these curves are relative and the scale is going to change from project to project and team to team. I think the principles behind the curves are more important than the curves themselves and you shouldn’t take the curves literally as a mathematical function.

Further Reading

End Notes

[1] This also explains why humans behave the way we do in free market economies, gambling, and other similar situations. I am attempting to apply information I learned watching this TED Talk on monkey economics and irrational decision making by Laurie Santos.

Improvisational Architecture

If you were to go to two improvisational jazz performances, even two concerts by the same band, you’d hear different music at each show. The thrill of experiencing something unique, as it is created, without any kind of real plan or rehearsal, is both exciting and entertaining. Sometimes the music is so spectacular you feel like you’re witnessing a miracle. Other times the group can’t seem to get it together and the show is one long, painful indulgence in artistic expression. No matter the outcome, what you hear during that performance will never be experienced again.

Music has always served as a great metaphor for thinking about software development. At XP2010 during one of the most original key notes I’ve ever seen, Bjørn Halterhaug and John Pål Inderberg, professors of musicology and improvisation respectively, from the University of Technology and Science in Trondheim, Norway and both veteran jazz musicians, discussed, through music and words how they approach improvisational jazz, the mechanics for making it work, and the general implications on collaboration among artists. It’s tempting to romanticize improvisational jazz as a truly spontaneous creation but this isn’t exactly how it works in reality. For any improvisational jazz band to be successful its members must exhibit seven key characteristics.

  1. Provocative Competence Interrupting Habit Patterns
  2. Embracing Errors as a Source of Learning
  3. Minimum Structures that allow Maximum Flexibility
  4. Distributed Task: Continual Negotiation toward Dynamic Synchronisation
  5. Reliance of Retrospective Sense Making as Form
  6. Hanging out: Membership in Communities of Practice
  7. Alternating between Soloing and Supporting

I propose that these seven characteristics apply directly to how teams who espouse emergent design should approach software architecture.

XP2010 Keynote: Bjørn Alterhaug and John Pål Inderberg improvising jazz music on stage.

Music and Design

Experienced musicians have an attenuated ear which enables them to hear music in ways that novices can’t. Drawing on a well-developed playbook of clichés, an expert in the standup bass for example can not only follow the minimally, well-defined structure of a song but also weave pleasing bass licks into the musical ramblings of his band mates, adjusting his actions based on the paths his band mates choose with appropriate responsiveness as the song develops. Part of it is musical maturity, a taste or style developed over years of playing, part of it is also trust both in himself as a musician but also in the rest of the group, that they too will not overreact to mistakes and are also able to follow a musical flow as it develops.

Well-defined but minimalist structure. Contrast this with the music played by a symphony which is also well-defined but has explicit and detailed structure.

When I hear this I immediately think of architecture as seen through the lens of agile software processes which advocate strongly for emergent design. Agile software development processes and agile culture in general strongly encourages teams to become improvisational architects. Create a minimalist, well-defined design of the system and then allow the developers to evolve the system, creating the design as they develop, playing off the code written by their fellow teammates as the system emerges. The romantic view of this is appealing to some: “Let’s go have a code jammin’ session, you dig?” But the results of an emergent design can be just as varied as improvisational jazz bands; some designs are elegant and spectacular successes, some designs are flaming piles of disaster, most turn out somewhere in between – usually good enough for customers who aren’t paying too much and who expected a somewhat unpredictable but functionally adequate outcome.

So if you enjoy the thrill of experiencing once-in-a-lifetime moments of creation, the outcome of which can never be predicted or known ahead of time, then emergent design is probably right up your alley. As demonstrated by the near exclusive emphasis on code and shipping, many agile developers fancy themselves as code jammin’, improvisational architects.

The exact opposite of emergent design, of course, is the easy to hate (and rightly so) enemy of creating things that actually work, Big Design Up Front, where a heavy cost is levied against a project in the beginning without producing any usable code whatsoever. Sticking with the music metaphor, the well-defined, explicit, and detailed structures of a symphony might take a composer months or even years to create. But in exchange for this planning you get a piece of music that is guaranteed to be executed (for all intents and purposes) in a nearly identical way in every performance in which it is played. I am not saying you should use a Big Design Up Front approach, in reality, even Mozart tried out music and made incremental deliveries to his sponsors as he wrote.

While certainly a degree of improvisation happens when we develop software, customers paying for software usually expect more predictability in the outcome. So, while it might be ok to spend 30 bucks for a fun first date with a girl at a jazz club – if only for the experience of it – when I pay 100 bucks a ticket to see the symphony play Mozarts’s Requiem, I would be more than a little disappointed, angry, and confused if the first chair violinist “felt a groove” in the middle of the second movement and began jamming. The greater the cost of a project, the more highly valued predictability in it will be.

Who can be an Improvisational Architect?

Mozart was a true genius, a master of composition. To play Mozart, you need to be well practiced but you don’t need to have his level of genius. On the other hand, most members of a great improvisational jazz group must be experienced musicians – experienced in composition as well as technical playing ability. Even then, a great group will usually avoid disaster but occasionally it will still happen because of the nature of improvisation.

In my experience, teams that plan to allow their designs to emerge do an ok job of providing the minimal structure that is essential for evolving a design. But only a few developers have the necessary experience and background to truly improvise a design. The implication? Most teams are terrible at improvising architecture because they have neither a solid enough understanding of the core fundamentals for software architecture nor the experience with using architectural design to reason about a system.

I believe that most of the seven characteristics of improvisation are deeply ingrained in agile culture, but agile teams often fail to fully embrace all seven characteristics of improvisation when designing a software system. A team without the experience, who doesn’t understand design cliché’s (architectural styles and patterns) will have an unpredictable outcome when allowing the design of a system to emerge as the system is developed. This is something the agile community must work to resolve.

Bonus

Cory Foy was thinking ahead and had the foresight to record video of the performance/keynote.  It comes in 6 parts.

Ingvald Skaug was also inspired by this talk and wrote an interesting essay which explains kanban as agile jazz. Check it out for a process perspective on the idea of “minimal structure for maximum flexibility.” If you believe Conway’s Law, then it isn’t coincidence that we would apply the characteristics of improvisation in jazz to both process and design.

Exploring Archetypes of Architects

During a brainstorming session in a recent OOPSLA workshop I participated in we were discussing what qualities make for a “good” architect in an agile world. I jotted down this list during the discussion based on the group brain dump. Some archetypes are “good” while others are “bad” but I don’t think any of them necessarily describe the perfect architect. When you’re designing software, what kind of architect are you? What kind do you prefer to work with?

The Megalomaniac Architect: “You will implement the system as I have designed it because I am the most important person on this team, the project will fail without me, and I am the only one smart enough to know everything that needs to be known!”

The Benevolent Dictator: “Implement the system precisely as I have designed it and I will make your work easier.” [via Dennis Mancl]

The “Everything’s a Nail!” Architect: All problems can be solved by a single tool, idea, or way of thinking. He’s got a hammer…and everything he sees is a nail.

The Diva: “I’m the architect of this system! Are you questioning my ability to design? If you’re not going to appreciate my talents, maybe I’ll just go to another team.”

The Magician: Excellent at high level abstraction, vague on how the design actually achieves architectural drivers.

The Over-Accommodating Architect: “You want that change? No problem.” There are no trade-offs to consider when making architectural decisions.

The Chess Master: To achieve victory, it is simply a matter of being able to see enough moves ahead. Every element in the architecture can be strategically placed in a perfect position to checkmate your opponent: requirements changes.

The PowerPoint Architect: “Architecture is just pretty pictures!”

The Ninja: Infiltrates a project from the outside, crafts an amazing design, then disappears into the shadows before anyone realizes he’s gone. Ninjas do not suffer fools and their designs are technically correct, thorough, and beyond your ability to comprehend.

The Navigator: Creates a map (with legend) and uses it to plot a course through implementation, testing, and deployment.

The Movie Producer: Leads the team indirectly by providing technical design support. [via George Fairbanks]

The Coach: Teaches the team about architectural practices and concepts as well as the design.

The Puppeteer: Able to manipulate multiple levels of abstraction simultaneously to design the architecture, the Puppeteer effortlessly manages the various threads influencing the design (commonly known as architectural drivers).

The Seasoned Veteran: He’s tried a lot of things and is pretty good at all of them including programming, design, processes, and management. Thanks to his experience, having walked 10,000 miles, he understands the role of architecture across the lifecycle, has seen many different situations, and is an excellent technical practitioner. [via Bill Opdyke]

The Long-Bearded Wise Man: A little philosophical but always willing to share an enlightened thought that will help resolve whatever concerns are ailing the project, though somewhat indirectly.

The Team Captain: A bona fide member of the team, playing on the field with everyone else, leading the team from the field.

The Design Evangelist: Excited about the architectural drivers and architecture to the point of near fanaticism. His enthusiasm for architecture and the system’s design is infectious and helps maintain conceptual integrity of the system.

The Student: Takes time to learn about the problem domain and the customer’s needs to the greatest extent possible so that he understands and solves the right problems. [via Gail Harris]

What other archetypes have you worked with? Which archetypes do you think might combine to make the perfect software architect?