Recently I posted a question on StackOverflow (Plug Plug) regarding
'what is a metaphor in Extreme Programming XP' ? I got a few answers but wasn't placated. It seemed (to me) to be the secret door in XP, which separates the masters from the wannabes. The other practices are relatively transparent.. easy to pickup.. but this one is elusive.. open to interpretation. So I dug up some books that I have and went about seeking the truth
Let's start with something simple.
Ron Jeffries: Metaphor is a supporting practice in XP. A metaphor or System of Names provides a common language for talking about the design of the program - helps communicate quickly and effectively. e.g. 'This system is like an assembly line for checks instead of cars'Pretty simple.. but is that all? Let's see what the master has to say in XP Explained: Embrace Change
Kent Beck: Each XP Project is guided by a single overarching metaphor. Helps everyone understand the basic elements and their relationships. The words used to identify technical entities should be consistently taken from the chosen metaphor. Metaphor in XP replaces much of what is normally termed 'architecture'. Calling a 10000 meter view of the system the 'architecture'.. doesn't push the system into any sense of cohesion. The goal of architecture should be to give everyone a coherent story within which to work, a story that can be easily shared by business and technical folks. Asking for a metaphor is more likely to provide this.
You can start development armed with 'just a metaphor' as long as - you have concrete feedback from real code and tests validating if the metaphor is working in practice
- the customer is comfortable talking in terms of the metaphor
- you refactor to continually refine your understanding of what the metaphor means in practice.
Hmm... the third bullet is a bit mystic for me.. but let's move on.However in the second edition of the book, Metaphor has been knocked off its pedestal as an XP practice. Passingly mentioned...
Interaction designers on an XP team choose an overall metaphor for the system. Conventional interaction design mandates a phased approach.. however this should be avoided as phases reduce feedback and restrict flow of value.Finally in TDD By Example, as part of the retrospective for Part 1.
I have programmed money (around 20 times). Then while writing this, I thought of using expression as the metaphor and the design went in a completely different direction. I really didn't expect metaphor to be so powerful. A metaphor should be just a source of names, shouldn't it.? Apparently not. The metaphor Ward C. used for 'several monies together with potentially different currencies' was a mathematical vector, I've used MoneySum, MoneyBag and finally Wallet, which imply merging 2 values with same currency. The expression metaphor freed from this, the code came out cleaner and clearer than ever before.Seems like Mr. Beck specifically spoke about its importance @ OOPSLA 2002.. titled 'The Metaphor Metaphor' where he offered to finally 'give it up' if a show of hands confirmed that metaphor isn't working in practice. I searched for a while... but the transcript isn't anywhere to be found. All I could find was
some notes from a human memory.. couldn't grasp much.. maybe 'you had to be there' (OR could it be that I was missing the metaphor :)
Let's dig into the matter a bit more... this time we follow 'software development's archaelogist cum anthropologist'.
Alistair Cockburn: discuss the value of XP's metaphor-setting exercise, we need to step back to a piece called 'Programming as Theory Building" (1985)
Peter Naur: Programming should be correctly regarded as an activity by which programmers form or achieve a certain kind of insight, a theory, of the matters at hand. This is in stark contrast of the common notion of programming as production of a program and other texts. This is the 'Theory Building View' of programming.Example: Group A built a compiler for language L. Later, Group B had the task of building a compiler for a language L+M, a modest extension. GroupB worked out a contract with GroupA - terms of support : full documentation, including annotated program text (Src code with comments?), additional written design docs and personal advice. GroupB went through the design phase and formed suggestions on how to accommodate the extensions & submitted it to GroupA for review.
GroupA found instances where the proposed solutions made no use of the facilities inherent in the existing structure of the compiler & which were discussed at great length in the documentation. Instead they were patches or 'grafted on' effectively destroying its power and simplicity. They were able to spot these cases instantly and propose simple and effective alternate solutions framed entirely within the existing structure.
A few years down the line, GroupC took over the reins for the compiler, without any guidance from GroupA . A member of the original A-Team later commented that the structure though still visible, had been rendered ineffective by varied amorphous additions.
Point: Full Source code + additional Documentation is insufficient in conveying the theory to another (motivated) group of programmers.Mr. Naur does another backreference to the work of Ryle(1949) and Kuhn (1970)
Theory = knowledge a person must have in order to not only do certain things intelligently but also to explain them, to answer queries and debate, etc. The notion is not confined to what may be the called the general/abstract part of the insight. e.g. For a person to have Newton's theory of mechanics doesn't equate to just knowing the central laws such as F = m a. He/she must have an understanding of the manner in which the central laws apply to certain aspects of reality. e.g. must understand how the theory of mechanics applies to motion of pendulums and planets and must be able to recognize similar phenomena in the world to be able to employ the theory properly. The dependence of theory on a grasp of certain kinds of similarity between situations and events of the real world gives the reason why the knowledge held by a person who has the theory cannot be expressed in terms of rules. (e.g. Newton's laws)
A programmer who has built a theory
- Can explain how the solution relates to the affairs of the real world that it helps to handle. Conversely, for any aspect or activity of the world the programmer is able to state its manner of mapping into the program text.
- Can explain why each part of the program is what it is.. is able to support the actual program text with a justification based on the programmers' direct intuitive knowledge.
- Able to respond constructively to any demand for modification of the program to support new behavior in the world. Can perceive any similarity between the new demand and the operational facilities already built into the program (if it exists).
When faced with a change request (maintenance), one hopes to achieve cost savings by making modifications to an existing program rather than writing one from scratch. The metaphor of civil construction in this regard doesn't hold true. Secondly the expectation may be based on the premise that the program is a text held in a medium capable of being edited easily.
Similarly, the idea of including flexibility into a program - we build in operation facilities that are not immediately demanded but which are likely to be useful. However this comes at substantial cost of design-implementation-test-description, incurred for a feature whose usefulness depends entirely on future events.
The theory building view debunks both of the above. When faced with a change, first of all, what is needed is a confrontation of existing solution with the demands called for by the desired modification. The degree and kind of similarity has to be determined.. which brings out the merit of the theory building view. The decay of program text as a result of modifications made by programmers without a proper grasp of the the underlying theory now is understandable. If viewed merely as a modification of program text and of external behavior of execution, any given modification can be realized in different ways, all correct. But if viewed with the perspective of the theory behind the program (only possible for a programmer who has built the theory), these ways may look very difficult.. some conforming to it and extending it in natural ways while others may be wholly inconsistent. To retain the program's quality, simplicity, good structure, etc. it is mandatory that each modification is firmly grounded in the theory of it.
The death of a program happens when the programmer team possessing its theory is dissolved. The program itself may continue to be executed by a computer and produce useful results. The actual state of death becomes visible when demands for program modifications cannot be intelligently answered.
Oh! you're still reading.!... just a little bit more.
Alistair Cockburn: Viewing programming as "theory building" helps us understand "metaphor building" in XP. Kent suggested that it's useful to a design team to simplify the general design of a program to a single metaphor e.g. assembly line, restaurant etc.
If a metaphor is good, the many associations the designer creates around the metaphor turn out to be appropriate to their programming situation. (Naur's idea of passing along a theory of the design). Later programmers will make guesses about the structure of the software (based on their knowledge of 'assembly lines' for instance) and find that their guesses are "close". That is an extraordinary power for just 2 words. The value of a good metaphor increases with the number of people working in parallel. The closer each designer's guess is "close" to other designers, the greater the resulting consistency of the final design. In its absence, each will develops his/her own theory with time. As each one one contributes code to the pool, the theory loses coherence. Not only does maintenance become difficult, development also is harder. The design becomes a 'kludge'. An appropriate shared metaphor lets a person guess where someone else on the team just added code, and how to fit her new piece in with it.
The designers are allowed to use multiple metaphors if they don't find one adequate for the entire system. e.g. this piece is like people waiting at the bank, this piece is like a school bus, etc.
Are we there yet?David West: Some would claim all thinking is metaphor-based. Metaphors are essential for bridging the familiar and the unfamiliar; selection of the "right" metaphors is critical for further development of fundamental ideas (discovery) . Every story/test/code module employs labels and terms that metaphorically connect things in the domain with their simulated coded counterparts.So now do I have my answers?
- A System of Names, common language shared by customers and developers.
- Guides discovery of objects, responsibilities, relationships, etc. for a coherent software solution
- Helps Peter Naur's 'theory building' and passing it on to future developers
- Instrumental for keeping the evolving design coherent and preserve theory in the face of multiple designers working on discrete pieces in parallel.
- So how do I identify a metaphor for the System under development?
Look at how entities interact in the real world ecosystem that is (or part of which is) being modelled as software. Correllate it with similar smaller simpler systems in the real world that display self-similarity with the ecosystem. (
This looks like a bee-hive/ant-colony except...) Run with it till the metaphor breaks or is inconsistent with some real world observation.. then change to a better metaphor.
- How do I know its a good one? What makes a good metaphor good? edit-clarification: Can a bad metaphor do more harm than good? What does it enable?
The 'goodness of a metaphor' concept has been described by Alistair Cockburn's excerpt above.
Bad (or relatively worse) metaphors exist and can lead to mediocre designs
e.g. Consider David West's example of finding a metaphor for an object in software. If your metaphor for objects is something like this image, you'd come up with a UML-ish design with static class diagrams and relationships. However if your metaphor for an object is a
person and use that to guide your design, you're bound to have a good design with fewer classes that fully communicate intent.
- People don't like to be told how to work.. you should ask them to do something and provide them with the information needed & expect them to do a good job. It's possible to insert wires into your head and make you dance by sending you the right electric impulses to make you dance... but that doesn't mean someone should do it. Don't build X_controller and X_manager classes whose only job is to tell other objects how to do something.
- People are lazy.. if something is too complex for them to do, they enlist the help of a specialist. Don't create large objects. Distribute responsibilities to cohesive classes and let them collaborate to perform the complex task.
- Each person may be different. Avoid type explosion..Don't create class hierarchies based on data/attributes. A bluebird is just a Bird object with an additional :color = blue entry in its NamedValueCollection member.
- and so on...
- How do I get good at metaphor finding... or better than I am currently?
I'm afraid I haven't found an answer to this.. As Peter Naur said '(to further talent for theory formation) The most hopeful approach is to have the student work on concrete problems under guidance, in an active and constructive environment.'
Thanks for reading! I've paraphrased most of the statements above and included examples as per my understanding. You'd be well advised to actually read the following references for more details..References: Get your own copy. Highly recommended.
Kent Beck * Extreme Programming Explained : Embrace Change First &
Second Edition *
Test Driven Development By ExampleAlistair Cockburn *
Agile Software Development : the co-operative gameRon Jeffries *
Extreme Programming Adventures in C#David West *
Object Thinking