Monday, August 31, 2009

The System Metaphor is Still Lame

The eXtreme Programming System Metaphor practice makes a pretty easy target. I've seen large development teams grind to a halt because of persistent broken builds without any continuous integration. I've seen teams' productivity drop to a crawl under the burden of technical debt and lack of test driven development. But what happens when a team lacks a good metaphor for how the system works? Can you really name a reasonable, realistic negative impact from a lack of system metaphor? Just last week I was dismissing it in an internal agility training as an unneeded XP practice. So I was surprised to see Joshua Kerievsky's and Brain Foote's "System Metaphor Revisited" talk at Agile 2009. Seriously, the guy who wrote Refactoring to Patterns is also hyping the System Metaphor? We'll see...

The thesis of the talk was that a System Metaphor provides illumination, inspiration, and integrity (...and alliteration). Briefly and in my own words, it illuminates an unfamiliar design by providing a reference point in the familiar. It inspires unexpected design ideas by providing a frame of reference in which to apply your creativity. And it builds integrity by suggesting a single, coherent, and consistent framework and set of names into the system.

And the Industrial Logic case study is just so cool. I've loved their marketing since they started with the "Let the Good Designs Roll" idea. I want to be a rock star and I want to take their training classes. And now their trainings are all hinged around the ideas of albums, tracks, and playlists. Very cool. I guess it helps to have a great product.

I have no doubt that the guys presenting have deemed their system metaphor a qualitative success for the project. But I still think the practice is totally lame.

A metaphor embedded in code is rigid. Having a great marketing metaphor is fine; marketing campaigns sell products. But they're also easy to change and refine, while an IT system is not. How many defects will be introduced if you change your marketing metaphor from a rock and roll concert to a book store? Not many. How many defects are introduced by changing the code to reflect this? Is none really the answer?

A metaphor is a 2nd ubiquitous language. One universal domain language is of clear benefit to a project. And that language should be the language of your users, domain experts, and programmers. A system metaphor is usually not this same language. For my projects, it's hard enough to try to get all the stakeholders to agree on terms of use. Introducing another layer of abstraction and the associated verbiage isn't going to help things. Ubiquitous language is important; but create it out of your domain not your metaphor.

A metaphor illuminates in the large, but confuses in the small. A metaphor guides you towards understanding when contemplating projects as a whole. It provides familiar signposts and a framework on which to hang ideas. But a lot of programming involves making small changes to systems you only partially understand. When this is the case, the metaphor becomes accidental complexity in the system. Having postage stamp, postage meter, and postage machine objects in your system helps the original design team, but doesn't help the contractor being asked to figure out why reports aren't printing.

A metaphor will likely become a mixed metaphor over time: consider a system that treats all data as streams. It's consistent and elegant. But eventually the Enterprise knocks on your door and you develop some sort of messaging service. Now your streams have mailboxes and can be put in message queues. This undermines the benefit of integrity via consistency. We live with this sort of ambiguity every day, but it doesn't mean we should accept it.

Metaphors do not decompose well. You system will grow, it will take on technical debt, and eventually it will need to be refactored, decomposed, and modularized. This is the natural rhythm of agile systems. When it comes time to break out components, will your modularization boundaries be natural boundaries within your metaphor? At a minimum, you'll probably end up discussing how the two don't line up correctly, and now you're spending time solving a self-created problem... surely a bad process smell. It seems like only the most dependency-obsessed team leads could foresee and prevent this. A YAGNI approach may not be your ally here.

In the end, I see a metaphor as a set of constraints. Humans can do their best and most creative thinking when provided rigid constraints. But constraints limit design ideas as much as suggest new ones. I'm sure some people have had success with a system metaphor, but I find success because of system metaphor a much harder pill to swallow. To all those espousing the use of system metaphor as a useful practice, I quote a famous and apocryphal doctor and say, "Clearly I can see you're nuts".

And just for fun, I used eight metaphors in this blogpost. There is no prize for finding them all.


Curtis Cooley said...

I think you have some valid points, but you are attacking the wrong concept. System Metaphor came long before ubiquitous language. Ubiquitous language is the "natural system metaphor"

By promoting Evan's domain language concepts you are supporting system metaphor.

The very first XP project was an accounting system at an automotive plant. They were able to come up with a metaphor of assembly line for accounts. It worked because the customers and the developers could both get it. A non natural metaphor is a risk, because everyone has to be on board among the other problems you pointed out. Almost every XP project I have been on has chosen the natural metaphor, or what Evans call the ubiquitous language.

Hamlet D'Arcy said...

@Curtis I accept your criticism. System metaphor should be lauded in the places where it overlaps with Evan's DDD work. When the two diverge is when I have a problem.

Anonymous said...

The way that I work with metaphor is to say to the business, "if you only had five minutes to describe your system, how would you do it"
Most projects I've come across have a simple and consistent way to describe a complex set of interactions.
For example, the 5 minute pitch for NarrativeFixture is that each test is like a movie scene, we have actors playing out particular action sequences, with the result being a take. If it was recorded as part of the ci build, this metaphor would be quite accurate.
As a result, we have a CastingDirector, Actors (playing Roles), Action sequences and even Therapists. We can explain the motivation behind each of these in seconds, and the interactions between components are intuitive. When I first introduced the CastingDirector, Antony knew the relevant method would be whoIsPlaying(theCharacter) because we are so consistent. Contrast this with trying to work out how to use an ActorFinder or ActorRepository or (horrors!) BrowserImplFactoryImpl (rails style find_by methods reduce this learning overhead, but then this is itself a kind of metaphor)

My feeling is that, if your business has a common, simple metaphor, then this is your ubiquitous language, not the formal language of the domain (which can then be pushed to the boundaries).
Very powerful systems can be produced by the emergent behaviour of many simple components interacting in a consistent manner.