The lean principle "See the Whole" is about seeing the whole of the project - not just the whole product, but the whole process. Ideally, Lean companies are lean all the way from Marketing to Human Resources, not just the development process. One way to see what waste there is in the development process is to compress it down to a week or three. If there are delays (wasting time) in going from requirements to design to deployment and testing, it will be more obvious -- a big, slow company that takes weeks for someone to approve something will have to change, or reject going lean.
Similarly to making the whole process smaller to make things clearer, XP recommends working on user-centric stories -- implementing a "whole" feature all the way from bottom layer to top layer (or back end to front end). Many people would rather implement the bottom layer first, and the top layer last, or vice versa, but then you don't have a "whole" feature to test and demonstrate and learn from. Building the software "in layers" risks building a LOT of stuff before being able to demonstrate and test a single user-centric story or feature.
Let's look at the seven core principles of lean, and compare them to Extreme Programming practices:
1. Eliminate Waste. Waste is anything that doesn't contribute to adding value to the product. One-hour status meetings waste time, so XP has 15-minute daily standup meetings instead. Excessive documentation and planning wastes time and energy, so XP recommends creating just enough documentation and planning, at appropriate levels of detail. Debugging is a waste, so XP does test-driven-development, which reduces debugging time and reduces time spent manually testing. Slow communication to/from the Customer/Domain Expert is a waste, so XP recommends having the Customer on-site.
2. Amplify Learning. Creating software is a 'learning' process. Typically developers do this learning alone, and that knowledge doesn't spread around to other developers very quickly. XP does coding in pairs to spread knowledge around faster. (Code reviews can also do this, but with higher overhead.) The Customer/Domain Expert is learning, too, as he sees his ideas implemented and developers ask him for details needed for acceptance tests. XP teams often do Retrospectives each iteration to bring learning to the whole team. Having all the developers and Customer working in a "war-room" also helps the whole team learn together.
3. Decide as Late as Possible. In Release Planning, stories are "promises for future communication" - the Customer/Domain Expert describes each feature/story in just enough detail for the engineers to provide a rough estimate. In Iteration Planning, the Customer describes the story in more detail, so the engineers can break it down into a task-list and/or rough design. The Customer/Tester specifies acceptance tests, which test the "what" not the "how", and then the programmers do test-driven-development where "what" tests and "how" coding are interleaved in a short cycle.
4. Deliver as Fast as Possible. "Simple Code" does everything necessary for the current requirements, but not more, so the team can ship it quickly. Keeping the quality high via test-driven-development avoids coding on an unstable foundation, wasting time debugging. Having the Customer/Domain Expert within range of spoken questions allows getting requirements into code in a minimum of time.
5. Empower the Team. XP encourages all team members to design, test, and code, instead of restricting those activities to a few. It encourages people to sign up for tasks, instead of assigning them to those who may not be as willing or as able. Anyone can improve code at any time, as long as the tests continue to run - allowing new learnings to be reflected in the code/design.
6. Build Integrity In. With short iterations where something isn't "done" until it passes (automated and manual) acceptance testing, and test-driven-development insuring that every line of code is tested, the XP team always builds on top of working software. In every iteration, all automated testing is repeated frequently, detecting as soon as possible any "breakage" of code. Any bugs found by manual testing or automated tests failing are not just fixed, but also force the creation of new automated tests.
7. See the Whole. Before beginning the first iteration, the XP team has a release plan. The Customer/Domain Expert has created that plan with the development team, and together they maintain and update the plan throughout the project, measuring and charting progress. Code is only implemented according to the current and previous requirements, so there is no work wasted on a requirement that may be dropped... however, engineers are not going to write code that will be difficult to adapt to that future requirement in that future comes around. To use the (not very good bridge-building analogy): the draw-bridge may not have motors in this iteration, but the builders are not going to build the bridge out of stone in this iteration, ignoring the need for mobility in the future.
By the way, I hate the "bridge-building" analogy, because writing software isn't building, it is designing. Running the compiler and linker associated "build" scripts, etc., are the "building". If building a bridge were as quick and easy as running a compiler and linker, we'd build bridges multiple times in order to test them. Any comparison of software development to bridges should be to designing bridges - an iterative, learning activity where multiple solutions are designed and tested (via mathematical/computer models or physical models) until all the requirements are met.
Your team is handed a huge pile of legacy code, to enhance or maintain. What are the first things you should do?
First, get it under source-code-control, if it isn't already.
Second, build it and run it. If it has tests, build and run those.
Third... review the code. Since your team is unfamiliar with the code, they will be reading it all anyway, just to figure out what it does and what they have to modify. It would be wise to organize that effort. If you can get the original writers of the code involved in the reviews, that will help, as long your company culture is mature enough to do reviews without blaming, put-downs, or criticisms that sound like attacks.
For agility, don't print out sources and hold whole-team reviews away from the computers. Have the team do the reviews in pairs and trios at computers that can build and run the source code. The reviewers should draw rough diagrams on paper to help document their understanding of the code, and have the reviewers present their findings to the whole team in verbal summaries.
Unlike reviews written up in the computer science literature, these are not reviews to find bugs, though no doubt with most legacy code, you will find lots of bugs. Don't fix them yet! The intention is to try to understand how the features are implemented, where the data flows (inputs, modification/processing, outputs), and what classes or functions are responsible for various things. When you find a possible bug, add a comment with an easily searchable tag, and/or add an assertion. Careful renaming of functions, files, and classes can be done here, when you identify names that don't explain the intentions of the code. If there are no layers, moving files/classes/modules into "Domain", "Infrastructure", "UI" and so on can help with understanding their roles.
You will probably identify lots of redundancies - several classes, modules, or functions that do the same thing. Move those things closer to each other in the source code directories and files, but don't yet do any refactoring that changes the function-bodies or class structures. You and your team should identify which functions/classes/modules would be the "preferred" ones to use for new code, and which ones you will avoid using (and eventually refactor away).
Identify and remove dead code, but be sure it's actually dead - if you're using a static language like C or C++, having a successful compile, link, run usually indicates that you didn't remove any live code.
You want a stable foundation on which to build your modifications, so now write unit tests that detect the bugs you identified in the reviews. Work on one bug at a time, with minimal refactoring to make the code testable. Fix the bug, and test the entire application to make sure the fix doesn't have any side-effects. Fixing uninitialized variables can create unexpected side-effects because the code may be relying on the (coincidental) value that the uninitialized variable had.
If you have requirements documents or some other description of the desired features, review those and the running application with your Customer (if you have one) to find out which features are actually present and working as desired, and what new features are desired.
Use XP-style story cards and release/iteration planning for new features (or features to be reworked) and if possible, write automated acceptance tests and unit tests when implementing the new features. If you don't have QA people to write the acceptance tests, write them yourselves.
All this advice supposes that you have some time to do the right things. If you don't have time to the right things, plan to spend time fixing bugs and stepping through the debugger trying figure out what's going on -- which will probably take longer than doing the reviews and bug-fixing up-front. Measure your progress against estimates - sometimes it's better to throw away bad code than to try to fix it, but that decision must rest on measured costs. Throwing away code doesn't have to an all-or-nothing situation. Replacing home-grown string classes with a standard string class, (ditto for container classes) and so on can increase the maintainability of the code without significantly affecting the domain-related design.
For entertainment - drama/action/comedy, science fiction, and "old west" bad guys and much badder guys, in a package that sometimes turns clichés upside down (or at least provides a fresh vision), check out Firefly - Joss Whedon's too-short series that aired on Fox -- a network that couldn't understand it, promoted it poorly, and didn't give it a chance to find an audience. The DVDs have episodes that were never aired, and several episodes have commentary audio tracks. Excellent cast. Excellent writing, set design, costume design, very good special effects... Unfortunately for us (and Joss and crew), much of the back-story of these interesting and sometimes mysterious characters remains unexplored, though the commentary hints that there might be some kind of revival/continuation for Firefly - perhaps a movie, a revived TV show, or something in another medium - Joss has been involved in comic books, and perhaps could be involved in writing novels... I haven't check the rumor sites yet, so you may know more than me.
Trivia fact: Ron Glass, who plays a Christian preacher in Firefly, is a Buddhist.
I occasionally see advice to wrap 'legacy code' behind a facade or
wrapper, putting new, tested, code "in front" of the wrapper, and
leaving the old untested legacy code behind the wrapper. The
recommendation is to "gradually" replace functionality behind the
wrapper with new code.
I'm sure this comes from good intentions, but I see this kind of thing
in legacy code itself -- layers and layers of code written by different
people over the years, large portions of it being 'dead' code, and the
one thing all these layers have in common is that their authors avoided
changing any of the previous layers of code.
It seems to me that "wrapping" should be a last resort, and continuing
to engage in the legacy code, simplifying it, removing dead code and
unnecessary layers, adding tests and refactoring, should be preferred.
I have to add some disagreements to the Lava Flow write-up that I linked to above. That author writes "There is only one sure-fire way to prevent the Lava Flow AntiPattern. That is by ensuring that sound architecture precedes production code development." There is more than one way to skin a cat. The other, less phasist way, is to apply Merciless Refactoring as you evolve the architecture as reflected in the production code, so that you have a good architecture at all times, even if it isn't the architecture you had planned to have three months ago, before you understood the domain as well as you do today.
I think of value objects (mutable and immutable), entity objects, and "Other" including "stateless" objects...
For example, a "configuration object" may be a platform-independent wrapper for the Registry API on Windows, the User Defaults API on MacOS X, and reading/writing ~/.somefile on unix/linux. None of the platform-dependent versions of this object necessarily need to have their own state, though caching the state might be useful if profiling determines that there's too much overhead in using the native APIs all the time. I like the stateless object for this particular case, because we can have many of them, possibly in multiple threads, without having to synchronize them -- the APIs we're calling are already synchronized (at least on Windows and MacOS X). Being a normal object, we can pass around Mock versions in our tests.
Note that a generic preferences object would not be in the Domain layer - it would be part of the infrastructure layer.
Eric does mention Policy objects as stateless objects implementing the Strategy pattern in examples of the freight-routing model; these would neither be Value objects nor Entity objects, as far as I can tell, but they would reside in the Domain layer.
SWIG allows Java code (etc.) call C/C++ code, not the other way 'round. That's the opposite of JACE, which lets C/C++ call Java. Maybe SWIG can be extended...
"Doctor, it hurts when I do this," says the patient. "Don't do it," replies the doctor. Here's a language translation task that makes me say "double-ouch" - some guy in India has to translate legacy (undocumented, untested) C++ into COBOL!
So much of language trends in the software industry come from marketing and price. Objective-C is a language that easily allows mixing Object Oriented programming with C. Back in the day when the major languages were C, Pascal, FORTRAN, BASIC, and COBOL, and they were interoperable, Objective-C continued to be interoperable. Unfortunately Objective-C was initially rather expensive, and had the reputation for being slow, because of one or two poor implementations. At the same time, C++ was gaining ground, because it was essentially being given away for free to universities and cheaply to companies that licensed CFront from AT&T; it was often used as a "better C" and had a (not always deserved) reputation for high performance. By the time that Objective-C had a free (gcc) implementation, the momentum for commercial compiler vendors and GUI programming environments (other than NeXTStep/Cocoa) was firmly in the C++ camp.
Xerox didn't market Smalltalk well, and later the Smalltalk vendors had a meltdown from mergers and loss of focus, and many people decided the language was dead. Smalltalk also didn't encourage interoperability - mixing C and Smalltalk is difficult in many Smalltalk environments. (Dolphin Smalltalk seems to be one of the exceptions, though their use of the phrase "Pure Object Oriented Programming" may be scaring away potential customers.) Now there are some free versions of Smalltalk, and several good commercial versions, but no major company (like Sun, IBM, or Microsoft) is hyping Smalltalk, even though IBM has a commercial Smalltalk implementation, and Sun and Microsoft are hawking virtual-machine-based languages that owe a large debt to Smalltalk virtual-machine research.
Like Smalltalk of old, Java makes it difficult to interoperate with C. I've used JNI fairly extensively for calling Java from C and vice-versa, and it is incredibly painful to use. Calling Java from C seems to be particularly problematic on MacOS 9 - all the threads that are supposed to be running inside the JVM are only active during the course of the call into the JVM, and maybe not even then, and one of those threads is the garbage-collection thread.
One tool for making JNI work easier is JACE, by generating (and using) C++ template-based code. Unfortunately, the most recent version of JACE is using templates that I can't compile properly with CodeWarrior -- when I told the author this, he told me to get a better compiler! I tried to suggest to the author that instead of relying on templates so much he could generate code without templates, because templates essentially are code-generators after all. He said something about wanting type-safety, which completely misses the point -- if you specify types as part of the code-generation process, then you can have exactly as much type-safety as you would get from templates. Given the arrogance of the author ("get a better compiler!"), I am not going to link to JACE, and would recommend that you use SWIG instead, for your JNI and other language-interoperability tasks. Once you've gotten SWIG as an executable tool, it generates C code, compatible with a large number of compilers.
There are over 7000 programming languages, so think twice before creating a new one. If you're looking at creating a way to script your application there are several alternatives to creating a new language:
Python can be "embedded" in an application, and is free and cross-platform.
On Windows, you can export functionality in your application via COM, and thus any COM-compatible scripting language can then script your application -- VBScript, VisualBasic, JScript, Python, Perl, and so on.
On MacOS X, programming in Cocoa or PowerPlant make it fairly easy to make your application scriptable via AppleScript, and via AppleEvents (the supporting layer for AppleScript) your app can be scripted via Python and other languages.
Because Cocoa/Objective-C has bridges to/from Java, Ruby, Python, and FScript, your MacOS X application implemented with Cocoa can be scripted or interfaced with several other languages.
Java, Python, Squeak Smalltalk, and so on, are very 'portable' languages, but they are implemented in C, so C is even more portable (though portable GUI frameworks via C/C++ are problematic -- sometimes more trouble than they are work). Smalltalk and many other languages which have environments "built-in" actually restrict portability -- I can't write a TWAIN plugin in a portable dialect of Smalltalk, for example.
Unfortunately, popularity of a language does not correspond to fitness of purpose. Many people program in languages that are optimized for machine-performance rather than programmer-performance. CPUs are 100's of times faster now, compared to when those languages were designed, and for the most part these days, the CPU is idle most of the time.
Rather than trying to find cheaper programmers, businesses should be looking at a less "expensive" programming languages/environments/methods: ones that provide power and speed to the programmers who are the most expensive "part" of the process.
At work, I can get myself (and others) to do the things that need doing, even though sometimes it's hard. At home, sometimes I know what I'm resisting doing, and yet I still watch TV or whatever. I can have an excuse like "I'm tired", but I know it's an excuse. I'm not convinced that I need to search for deeper reasons -- for some resisted tasks, I'm comfortable enough with things the way they are now; for others, there's some discomfort involved, or I don't perceive enough benefit for the effort.
Mark has a few tricks to help yourself get started, like "I'll just open the file" (or get out whatever materials you need to do the task)... once it's easy to get started on the task, you often do the task. This trick sounds like something Theodore Sturgeon once did to get over his frequent bouts of writer's block: he put a piece of paper in the typewriter, and would write something, anything until the paper was filled. He ended up writing a story this way, and he said about this experience: "it was so effective, that I never did it again."
I was a bit worried that Mark Forster had died or gotten sick (he's not a young man); he had been putting something in his blog every day, but nothing had appeared for over a week! Finally he wrote this:
By the way, I have a place to put blogging ideas, a "to blog" file, but so far, I have just about never written a blog entry based on something in my "to blog" file. Maybe putting something in the "to blog" file gives me just enough feeling of "having taken care of it" that I never take care of it for real.
I'm going to blog every day, and if I can't think of something to blog about, I will dig into the "to blog" file. And if I see something I want to put into the "to blog" file, I will instead blog about it immediately, instead. So you may be see me blog more than once a day.
Grumble. There are about three or four non-blogging writing tasks I am resisting doing... maybe I should just open the file, right now...
4 minutes compiling and debugging * 8 times/hour = 32 minutes/hour. Imaging how much worse this is in C/C++ environments where just compiling and linking costs 5 minutes or more before getting into the debugger.
Add in pair programming, which provides instant code review, finding those problems which are obvious to a person who didn't write the buggy piece of code, and XP-style development really rocks! The pair partner helps you find problems before you run your code, (or helps you diagnose why a test didn't perform as expected), so again you spend less time in the debugger.
Because I keep reminding people that Smalltalk (and C) begat Objective-C, and Objective-C (and C++) begat Java, James Bullock let me know of a good article on reasons to love and hate Objective C. Check it out: http://rentzsch.com/papers/loveHateObjC.
All of the writer's points are good, except #14 "id should be id*" is really a quibble, not worthy of "hate". He mentions PyObjC, which allows writing Cocoa apps in Python, and don't forget RubyCocoa as well.
On hate #1, "Method-call Syntax", I'd like to see Objective-C's brackets become optional (I think it could be done, and still have a simpler parser than C++), but I think more people should be forced to love Smalltalk, and so of course they will then love Objective-C by extension. ;-)
In regards to Hate #8, "Hard to Write Good Getters/Setters," part of the problem is Cocoa's semi-automated memory management - hopefully someday solved by using real garbage collection. The other part of this problem happens in any language where objects variables are only references (in other words, just about any language other than C++, which can copy objects around on the stack "by value"). You have to decide if you want to share references to your class's private members with the outside world, or make copies to give to the outside world. At least Cocoa/Objective-C has an immutable string class, so you can return references to member string variables without risk, like Java. More programmers should be writing immutable value classes to avoid copying objects in getters and setters.
This getter/setter issue reminds me of a the distinction between "value objects" and "entity objects" described in the book Domain-Driven Design by Eric Evans. "Entity" objects have the responsibility of maintaining an identity representing real-world thing, like a person. A person's age changes, weight changes, names changes; they change jobs, they change addresses, and so on, but their "identity" -- as far some software is concerned -- doesn't change.
Few programmers make the distinction between value and entity objects, and failing to make this distinction can create problematic OO designs/implementations. Unfortunately, no programming language is helping us here. It would be great if we could tag a class as an "entity," and have the compiler/run-time system let us know if we ever try to create non-identical duplicates of what is supposed to be a unique object. Tagging a class as "value" and "immutable value" would also be nice, and better than C++'s "const" syntax, which only tags variables and methods, not classes and objects.
So many groups doing software development are just groups of soloists, even though we call them "teams". James Bullock made a comment on SHAPE on creating and sustaining teams of software developers:
I dreamed I was in a high-school class, studying Smalltalk, and there was only one other non-high-school-age student in the class. My dream-interpretation is that "attending a class" represents that I am learning, and the lack of other people my age in the class represents how few people continue to learn after they leave school, as evidenced by the code I still see people writing.
There are "experienced" programmers who still declare local variables without initializing them. After spending hours (or days) tracking down a bug due to an uninitialized variable, a programmer who reflects on his or her work should realize the cost of always initializing variables is very small compared to the cost of debugging.
Variables that are not automatically initialized to 0 or null are a symptom of a bad programming language. Maybe they made sense in the old days of 1 Megahertz CPUs and languages that didn't allow combining declaration and initialization, but not today.
C and C++ default to not initializing variables. The exceptions are variables declared "static" -- those are initialized to zeroes -- and reference variables in C++. A good general tactic in using C and C++ in particular is to pick the "non-default" behavior whenever there is a choice -- it is almost always safer than the default behavior. (I could give plenty of examples, uninitialized variables are just the tip of the iceberg.)
Java and Objective-C also do not initialize local (stack) variables, though they do initialize member variables to 0 or null, so this lesson applies to those languages too. Smalltalk and probably several other languages do initialize local variables as well as member variables.
Here is a little C++ program to illustrate non-initialized variables. Try translating this to your favorite language and see what happens.
I tried to do "Replace All" in ProjectBuilder (replacing each tab with four spaces, preparing to paste the program text into my web-page) and got this error message after all my tabs were removed (and not replaced by spaces):
Continue actually works, so the 'uncaught' exception was actually caught safely, and one would hope that this output would help Apple's engineers prevent this problem from happening again.
The stack output is Objective-C / Cocoa: "+" indicates a 'class method', "-" indicates an 'instance method', "__" indicates a function not in a class. The first piece of text in the [] is the class name, the second piece of text is the method name (and yes, colons are part of the method names in Objective-C). The names in parenthesis indicate extensions/replacements to existing classes without subclassing - a powerful feature not found in many environments. Almost all the methods/functions on the stack are part of the Cocoa framework, the only items specific to Project Builder are the class/method PBXSimpleFinder _replaceAll and the 'PBXTextViewFindExtensions' method replaceAllStringsMatchingString....
The protagonist is one of those non-clone children, ejected from her the clan of her birth, so she views her world partly from an outsider perspective -- but not one as disenfranchised as the males on her world. Men in the society portrayed in this book are viewed as too emotional and too immature to run businesses, or be involved in politics or science or sports. For some reason, my wife likes this book a lot, even though she doesn't in general enjoy science fiction as much as I do. ;-) One character in the book is an unprecedented visitor from off-world, who tends to be under-estimated because he's male (and he gets kidnapped, part of the adventures we follow).
The "odd" aspects of the world portrayed in this book are the result of genetic engineering as well as social engineering. Sexual arousal is triggered by seasonal environmental clues - men are aroused by the summer auroras, and women by the winter frosts (glory frost). The world is oddly non-sexual, compared to ours. Women can conceive clone-children in winter, and varient-children in summer. The participation of men is required in both cases, though in winter the men don't make a genetic contribution.
Like other Brin books, there are many layers and currents and ideas to explore. Enjoy!
"We judge ourselves by what we feel we are capable of doing while others judge us by what we have already done." (Longfellow)
"People have opinions on everything -- especially things they know nothing about." (William Bonner)
"The problem is not that there are problems. The problem is expecting otherwise and thinking that having problems is a problem." (Theodore Rubin)
"After I'm dead I'd rather have people ask why I have no monument than why I have one." (Cato the Elder)
"People don’t want their lives fixed. Nobody wants their problems solved. Their dramas. Their distractions. Their stories resolved. Their messes cleaned up. Because what would they have left? Just the big scary unknown." (Chuck Palahniuk's Survivor)
"Many people are given good advice but the ones who profit from it are those who are prepared to take action." Karl George.
"Today there is a failure of what I call authoritarian leadership . . . Rather than look for new leaders, I believe we need to find our own inner leadership. When more people begin to discover the deeper part of themselves, then the world will be a better place." (Sir John Whitmore)
"Don't say you don't have enough time. You have exactly the same number of hours per day that were given to Helen Keller, Pasteur, Michaelangelo, Mother Teresea, Leonardo da Vinci, Thomas Jefferson, and Albert Einstein." (H. Jackson Brown, Jr.)
Mark Forster: "The expression 'time management' is in itself an example of the wrong mental attitude which prevents people from getting things done. It's as if a fish in the ocean were to say that it had a problem with 'water management'. Time is simply the medium in which we exist.
"It is said that power corrupts, but actually it's more true that power attracts the corruptible. The sane are usually attracted by other things than power." (David Brin)
"The problem is never that we don't have enough time. It is always that we have too much to do, and the answer is always to do less : to only do the things that matter." (Morendil)
"Realize that now, in this moment of time, you are creating. You are creating your next moment. That is what's real." (Sara Paddison)
"Every difficulty slurred over will be a ghost to disturb your repose later on." (Frederick Chopin)
"If you want to build a ship, don't herd people together to collect wood and don't assign them tasks and work, but rather teach them to long for the endless immensity of the sea." (Antoine de Saint-Exupery)
"If your success is not on your own terms, if it looks good to the world but does not feel good in your heart, it is not success at all." (Anna Quindlen)
"Putting off an easy thing makes it hard, and putting off a hard one makes it impossible." (George H. Lonmer)
"Mediocrity is the parent of regret." (R. Thompson)
"What is boredom but disengagement with reality? It is the feeling of wanting to be somewhere else at another time. There is no destination specified. Yet reality is only here and only now." Mark Forster
"Each problem that I solved became a rule which served afterwards to solve other problems." (Descartes)
"What I am doing is to ask myself the very simple question: "What am I resisting?". Then answer the question, do whatever it is, and ask the question again." Mark Forster
"A man may fail many times but he isn't a failure until he begins to blame somebody else." (J. Paul Getty)
"I know quite certainly that I myself have no special talent; curiosity, obsession and dogged endurance, combined with self-criticism have brought me to my ideas." (Albert Einstein)
"Life may have no meaning. Or even worse, it may have a meaning of which I disapprove." (Ashleigh Brilliant)
"I was interested in your comments about 'overlearning' and think this is a valuable concept and one which it is easy to overlook. I was taking part in a singing masterclass some years ago, and the distinguished singer taking the class said 'Amateurs practise until they get it right, professionals practise until they can't get it wrong' Those words have stuck with me and I find they apply in many ways - language learning as well as music. Of course, it is important to know when perfectionism is not helpful or not necessary, but my experience is that the only way to get 100% is to aim even higher." One of Mark Forster's readers.
"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore all progress depends on the unreasonable man." (George Bernard Shaw)
"Nothing is easier than being busy - and nothing more difficult than being effective." (R. Alec MacKenzie)
"Ninety percent of the politicians give the other ten percent a bad reputation." (Henry Kissenger)
"Those who are too smart to engage in politics are punished by being governed by those who are dumber." (Plato)
"If a million people believe a foolish thing, it is still a foolish thing."
(Anatole France)
"It's not worth an intelligent man's time to be in the majority. By definition, there are already enough people to do that". (G. H. Hardy)
"Discovery consists of seeing what everybody has seen and thinking what nobody has thought." (Albert Gyorgyi)
"We can be knowledgeable with other men's knowledge, but we cannot be wise with other men's wisdom." (Montaigne)
"One way to create momentum is by creating a series of small successes. So pick small goals, goals that are easy to create and then create them. Think of each success you create as a warm up exercise for bigger creations. Just like musicians practice and athletes practice, practice creating. All of the things you create will give you even more skill and more momentum." (Robert Fritz)
Sometimes someone says that they can't do an iterative and incremental software development process, like Extreme Programming with its "frequent releases" practice, because the product is "all or nothing". They can't imagine a "partial" product being useful. This is, of course, a failure of imagination. A thread on this topic is on the XP mailing list.
Note that if we had dug all the post-holes for the entire fence first, followed by post-planting, we'd have a less predictable situation for estimating the end of the entire job. The portions we have done so far do not form a good basis for estimating how long the next portions we're going to do, because the activities are so different. If we had done a 'complete' fence for just Bob's yard, we would have done ALL of the activities for building a fence, and thus estimating the fencing-building for Mary's yard would be more accurate.
If we had dug all the post-holes for the entire fence, and then decided not to fence away two of the three neighbors, (business requirements have changed), then we've wasted our effort, and he'd have to fill in those holes. If we did a partial fence first, that might be valuable enough "as is" not to remove, even though our plans have changed. The post-holes by themselves have little value.
Now, construction analogies to software are NOT my favorite thing. So let's talk about breaking down requirements for a software application. Steve Howell proposes thinking about the requirements for a coffee-house order system. "Until you put the entire menu on the system, you can't really use the system... How do you break this down?"
Now an infrastructure-first approach might have decided that a full-fledged (*) relational database with transaction processing would be a necessary first step, and a distributed system of order-station-clients a necessary second step. This is a bit like digging all the post-holes before planting any posts. However, that's not the XP way. The first several stories could have been done with a single station with a few simple text-files instead of a relational database.
(*) Footnote: how may of us recall that the literal meaning of "full-fledged" is having all of your feathers -- "having fully developed adult plumage". Birds don't get all their feathers/features at once, neither do software applications.
To the Smalltalkers who keep using this phrase, please change it to "writing code in your IDE." Because that's what you're doing. It just happens that your program is "live" while you're doing it. Other environments have something like this, too, but people using those environments don't call their "fix-and-continue" feature "writing code in the debugger".
There's a call for experience papers, tutorials, workshops, panels, PhD Symposium, etc.
Check it out.
And, of course, it is relatively easy to add "Undo/Redo" support to command objects and store stacks of command objects to be undone/redone.
In a dynamic language that supports reflection, one could create generic command objects by creating a class that retains a reference to an arbitrary object [call it a 'target'], a reference to an arbitrary method of that object [call that an 'action'], and a list of arguments to pass into that method [or perhaps only one argument, the 'sender'].
Instances of this class could be created by reading a configuration file or deserializing instances that had been created in an Interface Builder. I'm not saying that Apple's Interface Builder does exactly like this, but it is doing something kind of like this. See this page for more.
Cocoa and Interface builder allow creating powerful programs without writing (or generating) a lot of code. It's been one of the most advanced development environments for at least a decade (it used to be part of NextStep), and it still is one of the most advanced development environments.
Smalltalk, Objective-C, and no doubt Python and Ruby could generic command-object classes like this very succinctly. Java would be more difficult, but it can be done in Java, as well.
Perhaps if methods and method-calls (and classes) were more easily thought of as first-class objects [which is very far from the case in C++], tools for Aspect-Oriented programming would be easier or unnecessary.
I think the power of a Smalltalk environment is not just the language, and not just the environment. It's the combination of those and the Object Model - the concepts that underlay the syntax. (And a good class library helps a lot.)
I'd like to use a programming environment which has a choice of syntaxes but which uses the same object model. I could enter code in any of the following syntaxes, and see existing code decompiled into any of the following syntaxes:
Interestingly, there is one environment that is approaching the nirvana of multiple-syntaxes with a common object model. Apple's Cocoa, which is implemented in Objective-C, which has an object model inspired by Smalltalk, interoperates with Python, Ruby, AppleScript, and Java. Apple's XCode/ProjectBuilder environment allows writing code in these scripting languages and C/Objective-C/C++/Java/etc.
There are a lot of good Cocoa books out there. My favorite so far is by Aaron Hillegass: Cocoa Programming for Mac OS X It's not a lengthy as the others, and it covers a lot of what makes up a Cocoa application.
The authors main points are that (1) established companies almost always get "trapped" by their customers into only supporting "sustaining" innovations - incremental improvements in their products or services, and (2) only (for the most part) new companies are able to take advantage of "disruptive" innovations that create new markets and eventually take over established markets "from below".
For example, in the steel-mill arena, Minimills using a new, cheaper, process were at first only able to sell into the lowest-quality product area: rebar. The established companies stopped producing rebar because of the low margins, and concentrating on satisfying their most "demanding" customers in profitable high-quality product areas. But the minimills continued to improve their quality, and eventually took over more and more product areas - always coming in from below, always taking lower-margin business away from established players. At any time, the established traditional steel mill companies could have bought one of the existing minimill companies, or established their own minimills, but the lower margins are too unattractive for people used to higher margins. It seems likely that minimills will eventually take over the entire steel industry, and the people used to high margins will have to get used to no margins at all.
Disruptive Innovation can also create new markets where none were before. The established companies, particularly large ones, do not have an incentive to sell into a new market, because the new market is so small compared to their existing markets. Sales would be 1/100th or smaller in comparison, and not attractive to people used to making larger sales numbers. Apple experienced this with the Newton. It pretty much established a new market and sold more Newton MessagePads in two years than they had sold Apple IIs in its first two years. The difference is that Apple was a much smaller company when it was selling Apple IIs (and had invested less money in Apple IIs than it had invested in Newtons.) A small company (like Palm originally was) would spend less on the product's development, and be more satisfied with sales totals that a large company would find to be too small.
One difference between Pokayoke in manufacturing compared to software, is that software is always unique and fresh (if it isn't, some re-use is lacking). To "manufacture" a software product, simply copy the CD-ROM or post the installer on a web-site. However, pokayoke is always about quality assurance in either domain; either detecting problems as soon as possible, or preventing problems from happening.
Let me rant about bit a the Standard C Library. This library represents not the best or most appropriate set of functions that C programmers need to use, just the the ones that were most commonly implemented by C compiler vendors when the standardization process was begun. The string functions provided by the library are dangerous. For example, the string-copy function "strcpy(destBuffer,srcBuffer)" doesn't check the size of the destination buffer, so copying a too-large string can overwrite the stack or memory, provided us with countless bugs and security holes. Also countless lines of duplicate code where the programmer checked the size of the source string against the destination buffer-size before doing the copy.
The Standard C Library contains what might be considered a safer string-copy function "strncpy(destBuffer,srcBuffer,destBufferSize)" that will not copy characters beyond last byte of the destination buffer. But it will not terminate the string with a null-byte in the destination buffer if the source string is longer than the destination buffer. This lack of string termination means that functions expecting a well-formed string in that destination buffer will misbehave: accessing memory beyond the end of the buffer. A programmer who does not know this "gotcha" will have created another bug and/or security defect. Once again we will have countless amounts of duplicated code as the some programmers either write a "safe strncpy" function, or add a line of code to insure the destination buffer has a terminating null-byte every time they use strncpy.
And guess what? There's another problem with strncpy (and most "safe strncpy" implementations). It doesn't copy characters, it copies bytes. In multiple-byte encodings like SJIS and UTF8, half of a multiple-byte character could be left at the end of the buffer, if the buffer just happens to be one byte too short.
C and C++ have a problem where its static type-checking falls down: integers are freely (and silently) convertible to pointers and bools, and vice-versa. In this domain, the language is "loosely-typed". The bool value 'false' can be passed into a std::string constructor because the compiler changes it character-pointer (whose value is the null-pointer). A character-pointer can be assigned to a bool variable - if the character-pointer is the null-pointer, then the bool variable takes on the value 'false', otherwise it takes on the value 'true'. Microsoft's CString class used in MFC has a "type-cast" operator method that returns a character-pointer to the CString's internal buffer. I recently found some code that "assigned" a CStdString (a cross-platform class with an API similar to CString) to a bool variable -- this silently called the character-pointer type-cast operator and assigned 'true' to that variable, since CStdString allocates its own non-null buffer. Not at all what I wanted.
Fortunately, I can avoid std::string and CString and use (and customize) CStdString. My version of CStdString has an assertion to detect being passed a null-pointer. My version of CStdString does not define a character-pointer type-cast operator. These two changes help mistake-proof my code.
You might think that explicit/static typing is all we need for fool-proofing, but we know from experience that the presence of explicit typing does not eliminate bugs. Let's show this with an example in Java.
Now the above code satisfies the compiler's explicit type-checking, but it doesn't satisfy the requirement. Let's build a way of detecting this failure to meet the requirements - using Test Driven Development.
So how do we know the test is a valid one for the requirements? Well, it looks good to me. I ask my pair partner; he thinks it looks good, too. Since we're doing Extreme Programming, we ask our on-site customer what the log should look like. She looks at our test and says "This displayed text should should have an exclamation mark at the end." So we add "!" to the end of the strings in our tests.
We also validate the test by running it now, even though the displayWinningPlayer function is empty. The test fails (as we expected) because the necessary code to make it pass hasn't been written yet. If it had passed, then we would know something is wrong with our test.
Now we write just enough code to pass the tests. Unlike some examples in the TDD literature, I'm going to write the 'right' code directly, instead of taking tiny steps.
Whoops. Our second assertion failed. We can immediately see that the failure has something to do the points, since it got the name right. We don't even have to get into the debugger. Doh! Look at the source: when player-two has the higher score, we still append player one's score. We fix it, and the now the test passes. Pokayoke.
We ask the customer about ties, and he says that it can't happen according to the rules of the game. I would probably document that kind of 'negative requirement' with an assertion in the code. (The assertion has no effect in 'release builds' but it does have an effect in 'debug builds' that we use in test-driven development and manual pre-release testing).
And one last point. I could have written all of the above in Python, which does not have explicit/static typing. The tests would still detect my failure to meet the requirement, and the code would be a lot shorter and more succinct.
Extreme Programming has another way of detecting errors relatively quickly: "Frequence Releases." If possible, some end-users of this game will see versions of the game perhaps as often as every iteration. But that goes beyond pokayoke into the general area of feedback.
Calling something you don't understand and don't know how to do "religion"
is an entirely specious argument. There are people all around you doing
these things and having them work. Tell us what happened when you tried it.
Until then, it seems fatuous to tell us that we can't be doing what we are
doing.
The first thing wrong is using C++. I've used C++ for close to 16 years, but for the purposes he wants (persistence, extending a system without modifying code), it is the wrong tool. This is a case where you need a dynamic language with good reflection capabilities. Python or Smalltalk (or even Objective C or Java in some circumstances) would be better choices.
The second thing possibly wrong is very likely using the relational database. Unless interoperability or scalability issues require it, it would probably be better to use persistence/serialization options available in Python or Smalltalk instead of trying to get around the relational-object impedance mismatch.
The third thing, which Bruce goes into, is premature framework building. What is the problem being solved? Maybe it doesn't need a full-blown, extensible framework.
The writer also complained about Visual Basic applications being too rigid to re-use. There is another tool can help for this problem: separate the GUI from the model by incrementally implementing the model test-first (Test Driven Development) and implementing thin GUI code afterwards.
The interesting thing is that Toyota's practices don't even stay the same from month to month. Their continual search for improvement (driven by all levels of employees - not just management or a few driven people), means trying things and fixing things all the time. See what Joe Ely has written here:
PS: We as programmers will be much better off if we could tune and periodically modify not only our practices, but the IDE and programming language we use as well. (Toyota can refine and build new tools for making cars, we should make it easy for us to do refine and build new tools for making software solutions.) Smalltalk is one particularly malleable system. In Squeak and many other implementations of Smalltalk, the compiler is written in Smalltalk and is something you can modify (as well as the IDE). [Unlike for complicated languages like C++, a Smalltalk compiler is succinct and relatively more understandable.] I don't have it handy right now, but some time ago I was given a piece of code, less than third of a page in size, that adds an "increment assignment" operator to the language, so you can write something like "a :+= b" instead of "a := a + b". Many other things that would be additions to the language in other languages, are just new methods or classes in Smalltalk.
There is, of course LOTS of code out there that was not written this way (some of it is mine). Just browse some of the code on the internet or in your company's source-code-control system - probably most of it isn't written using test-driven techniques.
You'll probably find these things in non-test-driven code (particularly in projects that don't do code-reviews or pair-programming and refactoring):
I find that once my tests are passing, I almost never have to go back and fix any bugs later. This saves me a lot of time. At the worse, it takes about the same time as coding + debugging, but it's less stressful. If a bug arises during TDD, it is most likely in code that I wrote less than five minutes ago -- easily found and fixed.
For those people who say they don't have time to write tests: why do you have time to write dead code, duplicated code, and where does the time to fix bugs come from?
In traditional development and testing, you create a lot of defect-ridden code, and then test the defects out. The underlying assumption is that this is the only way it can be done. Test-Driven-Design works with a different assumption: You can put the quality in first, and not have to spend time getting defects out.
Traditional (maintenance) development, since it usually isn't supported by a suite of tests, eventually grinds to a halt: the code becomes so fragile that it can't be modified without breaking something. I don't know if the IRS has depreciation tables for source-code assets, but the reality is that code eventually loses value unless you take steps to keep it from losing value. Sometimes, code becomes unmaintainable while the company is still trying to make money off of it - the result is the company loses money or doesn't get the opportunity to modify the code to make more money. Test-Driven-Design provides a suite of tests that allows you to refactor - keeping the code maintainable so it is easy to enhance, re-use, etc., so you can make money.
I've recently reread an article which describe a process-adoption experience, which was viewed by some as a success and others as not so successful. Those who saw the new process as a success felt that they had gone through a paradigm change, and the ones who didn't think it was so successful were still operating in the old paradigm. Their summary:
Burn-Down Charts graph the work left to do, which is reduced by having done work, or by reducing scope. See the "progress" chart here. The project is done when the work left to do reaches zero (or time runs out).
Here's an ascii art burn-up chart where, about half-way through the project, scope was reduced in order to be able to finish by the ship date:
"The question is," said Alice, "whether you can make words mean so many different things."--Lewis Carroll
One of the problems with Metaphor is that literal-minded people can always find cases where a metaphor doesn't apply to a situation. When Shakespeare wrote "Shall I compare thee to a summer's day," he didn't intend for us to think about a daylight savings time, or people dying from the heat. Industrial XP has replaced the XP Metaphor practice with "Domain Driven Design". There's a book with title that many people have recommended. I bought it, but I haven't read it yet. Check it out: Domain Driven Design by Eric Evans.
Test-Driven Development can making stepping through code to understand what's going wrong mostly unnecessary. Here's what people on the XP mailing list have said recently:
I haven't used a debugger since 1999. But I guess there are lots of
people who haven't written a test since 1999 either. I wish IDE makers would focus on profilers instead of debuggers. -- Bill de hÓra
Writing a test rig for 'strcpy()' is obvious. Writing a test rig for a WTL
ActiveX Host window containing an embedded control under apartment model
threading and multiple toolbars that hook into window events is ...
non-trivial. [...] We must stop blaming ourselves and start blaming the tool vendors. If they can't test it, they shouldn't ship it. -- Phlip
Hmmm... actually, you just need a better test runner. The test runner knows
what test failed, and it should be able to show it to you. Why isn't it? -- Robert Watkins.
Because its vendor has sunk millions into polishing an elaborate and
full-featured debugger, to clean up the mess after making it. -- Phlip
If IDE makers focused on tests...
- wizards would create both code and the test-first rig
the wizard author used to generate that code
- the source browser would distinguish between
production code & test code, and would flip
automatically from a test case to its target code
- the Go button would not ask any stupid questions,
such as "you want to save files?" or
"you want to compile?"
- Undo would have the ability to roll back to any
previous GreenBar
- there'd be an Integrate button - NOT a bunch
of goofy checkmarks on each file stating
if it's "checked out".
- integrating would run the tests, and would
back the integration out if the tests failed.
- Extract Method would be on the toolbar
- at assertion failure time, the IDE would know
both the call stack of the production code
and the fixture of the assertive code
- the Workspace panel on the left would have
a third tab, containing the test suites and cases
- one could run any subset of tests, or any superset
of folders with tests, from the IDE
Imagine all the effort the past 2 decades spent on debuggers, spent instead
on test rigs. -- Phlip
I've never used a debugger for Java much... there were never very good
tools.. by the time there were (that I had access to) I was practicing
TDD. Back in '98 I was on a team that had a "test everything that
could possible break" mentality (with a homegrown test framework), and
code wasn't complete without tests, etc. We also evolved our design,
refactored as needed, and on occasion threw out subsystems when it
turned out that we had gone down a dead end. All this without any
"Agile" buzzwords (none of us knew about XP at that point). Best team
I've ever been on... so far. --Dave Astels
If I have a "bug" I write
a test to find the bug. -- Nathan Paris
I don't like the debugger at all. It's a weird sort of personal failure
mentality, where if I have to debug then maybe I don't understand the
code enough to be writing it in the first place. -- Curtis R Cooley
Yes, the debugger is a valuable tool. I only use it as a last resort,
when I can't get to the green bar from a failing test that I think
should be passing. -- Kathie Drake
And what is a real shame, is that in some shops, it is quite acceptable for
someone to be sat
their wasting time in a debugger, not pairing or writing tests, but not
acceptable for two people
to be sat at a machine. -- Nick Robinson
I program in C++ for work and am very familiar with the debugger there.
Unfortunately, even with rigorous tests it seems the debugger is almost
unavoidable in C+. [...] On the other hand, I program my own for fun programs in either Java or
Python, all test first with merciless refactoring. I don't even know
how to use the debugger in those languages. I've never needed one. -- Brian Christopher Robinson
[/docs]
permanent link
How To Go Faster
Johanna Rothman mentions a few ways to produce software faster. A few more ways are:
- Don't use the conventional solutions that everybody else uses - use the tools that can allow developers to go up to seven times faster. For example, use Smalltalk (see also Cincom) or Python or Cocoa instead of Visual Basic or Java or C++. Use WebObjects instead of EJB. If you do use Java, use Eclipse or buy IntelliJ IDEA.
- "Sharpen the Saw" -- provide training for the above tools for your developers
- Don't use virus-ridden servers and clients. MacOS X is more productive for most users, MacOS X Server is cheaper than Windows servers, and MacOS X clients have a lower cost of ownership than Windows clients
- "Sharpen the Saw" -- provide training in object oriented design, test-driven development, design patterns, and refactoring for your developers -- don't assume they know this stuff already.
- Find out what the most productive developers use by asking the developers - don't believe marketing hype from the big companies who want to sell you their tools.
- Beware "resume-driven-development." XML may be trendy, but may not be the simplest (and fastest) thing to use in your application.
[/docs]
permanent link
For Managers - Tracking Progress
How do you (a non-technical manager) track how much of the project has been done? Have your programmers implement a few features at a time, and have QA verify them with automated tests. A feature is done when its tests pass. Do manual testing as well, but you need automated tests to make sure that working features don't get broken when later features are added. Track your progress with a "burn-down" chart. Robert Martin explains it (with two simple graphs) here: http://www.artima.com/weblogs/viewpost.jsp?thread=16880.
[/docs]
permanent link
Last Words On Exceptions
Bill Caputo sums it up well: The real problem is bad coders.
[/docs]
permanent link
Exceptions Are Not Gotos
Joel says exceptions are just as bad as "Go To"s.
What was the danger of "Go To"? Too many of them would make the control-flow hard to understand. The the whole point of "while", "do", "for", "break", "switch", "if/else if/else" and "return" was to allow changing the control-flow in easier to understand ways than "Go To". Of couse, over-usages of these can also make the control-flow hard to understand. In particular the following piece of code is just as bad a using "go to," and can be confusing if you expect "do...while" to loop. (This example doesn't loop.)
do
{
statements;
moreStatements;
if ( cond )
break; // equivalent of "go to"
otherStatements;
} while ( false ); // destination of "go to." Does NOT loop.
A "Go To" links a source point to a destination point -- this increases coupling between two points of the code. In C++, a "Go To" can be dangerous because it could skip initialization or destruction of local variables.
What is the danger of exceptions? Too many of them can make the control-flow hard to understand -- but so can other control-flow statements. An exception does not link a source point to a destination point. It does not increase coupling between two points of code (generally speaking). In C++, the compiler (and the scope rules for try/catch) insures that throwing an exception does not skip initialization or destruction of local variables.
The key point of using exceptions is to only use them for exceptional situations. If you're calling a search function, you expect to either find or not find find what you're searching for, so the search function should not be throwing an exception when something is not found (or when something is found). If the search function runs out of memory, an unexpected situation, then throwing an exception would be appropriate. Some place higher up the call-chain, perhaps in the user-interface code, should catch "out of memory" exceptions -- no matter who throws them -- and safely handle the situation. In the "old" days on MacOS pre-X, our "out of memory handler" would free up a reserve of memory, display a pre-fetched error alert, and then the user was in control again -- hopefully able to save and quit safely.
I've seen very readable C code that used "setjump/longjmp" to do the same thing as throwing an exception -- to exit from any of several places, to an exception-handler, in the case of an unexpected or unrecoverable error situation.
[/docs]
permanent link
JoelOnExceptions
My reply to James A. Robertson:
Joel may be working in C++, perhaps with a lot of legacy C code... the only problem with exceptions I have seen, is that mixing exception-safe code with non-exception-safe code is ... unsafe. If the bottom-most layer returns errors code, then all layers above it can be written to use exceptions and be exception-safe. If any code calling exception-throwing code is not itself exception-safe... then you've got problems.
Exception-safety requires, in C++, a lot of reliance on "construction is resource-acquisition/destruction is resource-releasing" idioms. However, making that effort to be exception-safe turns out to be a good place to use XP's "once and only once" rule. Calling "delete" on an dynamically-allocated object should be done only once in a class that pretty much exists only to handle delete -- a smart pointer template class. Calling the operating system's "close file" function should only be done once, in a class that handles files.
When you use objects "by value" (allocated on the stack), C++ insures that their destructors are called when an exception is thrown - allowing you to close files, delete objects, and perhaps even roll-back a partially-completed database transation.
In Java and other languages that have garbage collection, most of the need for "resource-releasing" goes away, and the remaining can be taken care of by occasional "catch" or "finally" blocks. Not sure what the Smalltalk equivalent is (has this been ANSI-Smalltalk standardized?)
My reply to Joel's Oct 15 blog entry:
void InstallSoftware()
{
DoCopyFiles();
MakeRegistryEntries();
}
void InstallSoftwareGUI()
{
try
{
InstallSoftware();
}
catch( NoDiskSpaceException& ex )
{
// don't log - no space
DiskErrorMessage( ex.DiskName(), ex.DiskSpace() );
}
catch( RegistryException& ex )
{
Log( ex.SrcFilename(), ex.SrcLineNum(), ex.what() );
ErrorMessage( kNoRegistryPermission );
}
catch( std::exception& ex )
{
try
{
Log( ex.SrcFilename(), ex.SrcLineNum(), ex.what() );
}
catch ( std::exception& ex2 );
{
// ignore problem with logging
}
ErrorMessage( kUnknownError );
}
}
Curious about recovery for copying files...?
void DoCopyFiles()
{
FileCopierWithRollback appCopier( "app.exe" );
FileCopierWithRollback libCopier( "lib.dll" );
appCopier.DoCopy();
libCopier.DoCopy();
appCopier.CopyIsDone();
libCopier.CopyIsDone();
}
These File Copier With Rollback objects will remove the file they
copied in their destructor, unless you call
CopyIsDone() to indicate that the copy of all the
objects was successful.
If DoCopy throws an exception, the CopyIsDone() methods
will not be invoked. When handling an exception, C++
automatically calls the destructors of local
(stack-allocated) objects of all the functions that
are being exited or "by-passed" between the throw
and the catch, so, since CopyIsDone() hasn't been called,
the File Copiers remove the files that they tried to copy.
This is very similar to Command Objects that support Do, Undo, and Redo. The C/C++ User's Journal has described a way to write templates to generically support specifying the action and roll-back action without writing new classes... but I don't recall the syntax.
Please ignore the absence of a destination directory parameter in the code, this is something I wrote quickly. In real life, I'd use Test Driven Development, which would flesh out the interfaces more realistically than this sample.
[/docs]
permanent link
LeanThinking
Really good post by John Roth on the XP Mailing List. Snippets:
Lean thinking didn't take over manufacturing because everyone saw
it and said: "oh, wow!" It took over maufacturing because when
Toyota started importing significant numbers of cars to the US,
it started eating Detroit for lunch and asking for seconds.
Someone on a blog stated their opinion that software development going overseas was equivalent to the Japanese car manufacturers taking business from Detroit. I think it's much more like the garment industry moving its work from the U.S.A. to overseas -- the work going overseas is not being done differently (for the most part), it's just being done cheaper. When it is being done differently, it's because the management is different.
For example, see Johanna Rothman's blog: "I'm convinced that the reasons outsourcing works is that it forces organizations to document requirements and the outsourcers work on only one project at a time. The outsourcers' management can then choose any number of useful product development practices that increase the outsourcers' productivity. Management can't change their minds and refocus the outsourced project(s) in the same way they feel free to refocus the internal projects.".
To continue John Roth's posting about Lean Manufacturing and Lean Development:
With that kind of example, the early adopters tried it and found
that it solved a lot of endemic problems. In the last two decades
it's become the 'heads up' thing to do in manufacturing, but only
now is the effect on inventory turns becoming aparent in the US
national statistics.
And that is without full participation from the industrial establishment.
If manufacturing was fully Lean, you wouldn't see jobs going
overseas. It's impossible to operate a pull environment when
one of your processing steps takes a month to transport goods
by ship. That's old Henry Ford / Frederik Taylor thinking.
[...] I didn't start to see the difficulties with what the Poppendieck's had done before I read "Lean Thinking" by Womak and Jones.
[...] XP turns the fundamental process motif of plan driven
development on its head. Plan driven development tries to take a
work unit and run it through several processing stages: Requirements,
Design, Coding, Testing, Deployment. XP runs smaller work units
through a single developer who is responsible for taking it from
requirements through a fully integrated, production quality deployable.
Everything else, and by that I mean *everything* else, in XP is a
supporting practice to that one fundamental difference. The fact that most
of those supporting practices have been in the environment for
decades was simply luck: Kent didn't have to invent them.
You know you're doing "plan driven development" when each stage is done by different people. In XP, the practices for eliciting Requirements from the person(s) who know the domain/requirements, for doing Designing and Coding and Testing, are done all the time in small batches, by the same small group of people (maybe a few specializing in testing), and Deployment is (ideally) automated to the point of painlessness so it could be done after each iteration.
[...] In manufacturing, sooner or later you've got to take the plunge of
making a fundamental reorganization of the factory floor. In software
development, you've got to take that same fundamental plunge of
reorganizing your development process. The Poppendiecks put it
quite well: "in manufacturing, inventory control is the starting place
that always works. In software development, the short, fixed length
iteration is the starting place that always works."
Once you make the fundamental committment that you are going
to take some part of the system you are building from requirements
to fully integrated, production quality deployable in two weeks (or
one week or one month,) all your other practices have to change.
You cannot have handoffs and approvals for requirements analysis,
nor can you have a separate, end of the line QA department. You
can't have a godlike Data Base Administration department that
takes months to optimize your data model either.
[/docs]
permanent link
Agile Management
David Anderson, who wrote a book on the subject, announces:
I'm going to be co-authoring a regular column at the Borland Developer
Network website called (unsurprisingly) "Agile Management". I'll be
working with Mike Watson, a developer manager I work with daily. His
hands on, first line management, downward focus will compliment my
second/third line manager upward focus.
The URL for the site is http://bdn.borland.com/coadletter/agilemanagement/
I have posted a draft of the first article to the files section of the
group, http://groups.yahoo.com/group/agilemanagement/files/ [ZenOfAgileManagement.pdf]
I recently finished reading the Cutter Consortium's "Executive Report on Agile Project Management, volume 4, number 6" on "Challenging the Fundamental Notions of Software Development" by Robert N. Charette. Lots of good stuff. I got this report for free, but the subscription (which I don't have) costs a whopping $2400.
Charette writes, in a summary of the Japanese experience with Lean Manufacturing of automobiles, "In performing lessons-learned studies, the Japanese discovered later that process and technology improvements on the factory floor contributed only 25% towards achieving their six original targets. Humanware issues account for the rest."
I found another interesting read while Looking for Robert N. Charette on the web: Center For Quality of Management Journal. Check it out.
[/docs]
permanent link
Steve McConnell on Extreme Programming
Dave Hoover compares advice from Steve McConnell's Code Complete with advice from XP and TDD books, prompted by Steve dissing XP in a Wired magazine article.
Notice Steve's self-contradictions in his Wired quote; he calls it a fad and also calls it nothing new (he also uses the term "sloppy" and yet says "the rules are too rigid":
This industry has a long history of latching onto fads," says programmer and consultant Steve McConnell [...] "and few [practices] are new; project management guru Tom Gilb came up with similar guidelines years ago."
Steve McConnell's web site has a slightly more balance appraisal of XP here: http://www.construx.com/docs/open/CxOneXpWhitepaper.pdf. In that paper, he writes "XP is based on longstanding industry best practices, including evolutionary prototyping, short release cycles, and active end-user involvement in requirements definition."
That paper is also promoting McConnell's own methods toolbox, "CxOne", of which he writes: "CxOne tailoring must be performed by highly trained and experienced staff [...]. Once tailored, CxOne can be used by staff at any skill level." Which is the same claim made by RUP, which also has an "tailored" set of methods equivalent to XP.<.p>
He claims XP can't work in several areas because it is "inflexible", but ignores the fact that XP is supposed to adapted to the local situation once the team using it has experienced its synergistic practices. As Kent Beck wrote: "XP is a starting line. It asks the question, 'How little can we do and still build great software?'" - XP does not disallow adding practices appropriate to each team's circumstances.
Ron Jeffries wrote "[T]he twelve practices are intended to be a starting point. Projects who want to know how to start XP are pointed to the twelve practices and told to do them for a couple of iterations and then to modify and adapt them to their local circumstances." in "When is it not XP".
Martin Folwer reminds us that there are principles of XP, not just practices in "Principles Of XP" from which I'll quote the list here:
Fundamental Principles:
- Rapid Feedback
- Assume Simplicity
- Incremental Change
- Embracing Change
- Quality Work
Further Principles:
- Teach Learning
- Small Initial Investment
- Play to Win
- Concrete Experiments
- Open, honest Communication
- Work with people's instincts - not against them
- Accepted Responsibility
- Local Adaptation
- Travel Light
- Honest Measurement
[/docs]
permanent link
Superstitious Coding
Superstitious code is code that works, but the author doesn't know why it works, and doesn't know why alternative pieces of code that should do the same thing don't work. It may also be called "programming by coincidence".
The driving force behind superstitious code is ignorance. In some cases, the programmer doesn't understand programming very well. In other cases, the problem is that there are too many "black boxes" -- too many layers of code that are not available in source form, not well-documented, and which may be buggy. Sometimes the source code is correct, but the compiler is buggy.
I'm seeing a pure Java program that crashes the virtual machine. It crashes under MacOS 9.2.2, using Apple's Java VM (MRJ 2.2.5), on a dual-processor Mac with 1000 MHz G4 CPUs. My code is simple, but it's calling someone else's Java code that is multi-threaded and doing network I/O.
Since JVMs are never supposed to crash, I can assume that the problem lies in MRJ JVM or in one of many other black-boxes: the operating-system, any one of many system extensions, any one of many other processes that are running concurrently. The bug may even lie in the disk-driver software, or in one of many pieces of firmware, such as the firmware on the ethernet card.
And by the way, setting a break-point in my code using a debugger makes the crash go away, and I don't see the problem on a 500 MHz dual-G4 Mac, nor on single-processor Macs. It happens with virtual memory turned on or turned off. (I may also try running it on MacOS X, though this code isn't intended to run on MacOS X.)
MacOS 9 is particularly hard to debug because it doesn't have protected memory -- any running process could write in any other process's memory-space. Multiple-thread code can be hard to debug, because threads are not necessarily scheduled deterministically, and a buggy thread could set up a problem that is not visible until later, possibly in a different thread.
I really admire people who can use a low-level debugger to reverse-engineer and debug multiple layers of black-box code... it not only takes a lot of knowledge, but it also takes a lot of time and effort.
However, I don't have a lot of time, and since Apple held a funeral for MacOS 9, complete with coffin and eulogy by Steve Jobs, I probably can't expect to see Apple fixing MRJ or MacOS 9, even if I identify a bug in their code. So the only solution for this problem may be changing the Java code to work around the JVM's problem, without ever knowing exactly what that problem is. (I'm guessing that a network-call-back function is calling JVM code that has a stale pointer to an object that was garbage collected, but it could be something else.)
Some other time I may write about the misconception that Test-Driven Development is a form of Superstitious Coding.
And isn't it interesting how scientists are opening up the black-boxes of humans, plant, bacteria, viruses, and animals, by examining the source-code -- the DNA -- by poking values into the code and seeing what happens?
[/docs]
permanent link
Learning Time
How much time do you allocate for learning new things? Have you been told you don't have the budget for training? Learning doesn't require classes and workshops. Jim Little tells his experience with "continuous learning" on the Industrial XP mailing list:
Back in 2000, I saw a post John Brewer made to the Extreme Programming mailing list. Every week, he said, his team took half a day to "play." They could use that time for anything they wanted.
I saw that post and thought it was a great idea. I was leading an XP project at the time, so I went to my manager and proposed it. She thought it was a great idea. [...]
Eager to try it out, I told the team that I had convinced management to give us free time. Every Thursday afternoon, we would experiment with any technical concept that interested them. The only rule was that it couldn't be project related. Using spike solutions to demonstrate the concepts was highly recommended.
I thought the team would jump at the opportunity. Instead, they balked. "That's a waste of time," they complained. "We're here to write software for our company, not play."
I pushed the issue anyway, and the team grudgingly agreed. People went off and learned about XML, XSLT, JavaMail, and other technologies. The effort paid off within weeks as we incorporated the new knowledge back into our product. For example, we used our newly acquired JavaMail knowledge to start sending HTML email.
It took a month or so, but people's objections to continuous learning faded. [...]
I think the initial reluctance to play time came more from a sense of being lost. There's so much to learn how do you find something that's really interesting? Half a day isn't really all that much time. Working in pairs helped people get over the hump, as did plain old pushing from the coach. Once people got used to it, they liked it.
I've heard companies claim that they allocate 20% of their time for learning. Half a day every week is 10%. Doing all 20% in one chunk would be ten straight weeks of learning. (Yeah, like that's going to happen.) If you're serious about that much learning, the only practical approach is continuously.
[/docs]
permanent link
Embedded Extreme Programming
On the XP mailing list, Nancy Van Schooenderwoert described her successful embedded software project that used XP. Her team started out with good (XP-ish) practices and then went full-bore XP.
[...] In 1999 I got my embedded software project staffed at a large company
in the Boston area. At the time I knew nothing of XP, but I was
determined to apply good practices I'd picked up in the school of hard
knocks, as they call it. I instituted strong unit tests for each module,
coding standards, source code management, common code ownership,
frequent code reviews (more as knowledge sharing than as a police
action), solid build control, and iterative development. I was also very
conscious of good naming & shared design concepts - i.e. we were using
what XP calls 'metaphor'.
This all worked quite well. [...] Our bug rates were very low - about 1 bug per 2000 lines of code. Bugs were tallied at integration test, not unit test. [...]
In spring 2000, I found out about XP and later we tried the Planning
Game, Pair Programming, and made more effort at 40-hour week. We worked
for smaller releases, and were glad to see Refactoring brought out of
the closet (we'd been doing it but feeling guilty because it didn't add
features). Our bug rate stayed low - at the very same level in fact. But
our releases became much more regular and all the developers learned to
estimate.
The key practices we added to deal with the embedded realities were:
- Leave a bread crumb trail - a trouble log that is always "on" so it
doesn't distort your troubleshooting by having to be enabled.
- Dual targetting. Make your app run on a desktop as well as on the
target CPU to isolate board-specific problems.
- Stand-alone module execution. Each loosely-coupled domain of the app
should build and execute alone on either target.
The above 3 practices allowed us to cut through the toughest bugs like
a chainsaw! They are incredibly powerful especially when used together.
At the start of the project, 3 of the team members had no experience
with real-time or embedded software. The team practices had the effect
of putting a safety net under everyone, so they could learn without
getting hopelessly tripped up (or wrecking the code). I also taught them
all I knew about multitasking - another skill that was absent from all
the staff except me. The funny thing is that the worst multitasking
problem we had was a deadlock that held us up for a few hours, and it
was my bug.
Ron Morsicato (a team member) and I wrote an article for Cutter's IT
Journal last year about our experience. Here's a link (it was mentioned
in a previous posting by Charles Poole) --
http://www.cutter.com/itjournal/xp.html
Phlip adds his comments:
Note what they did, compared to the "traditional" way:
You used more code to solve the root problems, not cause more problems. You
did that by obeying the emergent principles - when in doubt test; when
testing is hard make it easy.
These are more important than the grunt work of writing production code.
Some bosses see all the bugs, and decide that nobody should write >more<
code. They only predict that infrastructure would bring its own burden.
[/docs]
permanent link
Productivity Comparisons
Thanks to Martin Fowler for providing a link to his description of Jim Johnson's speech at the XP2002 conference, vaguely mentioned in my previous blog entry. Fowler wrote:
Johnson's comparison of two SACWIS systems. SACWIS is a child welfare system that all the states in the US must implement. He stated that Florida began its SACWIS system in 1990 with an original cost estimate of $32 million for delivery in 1998 with a development team of around a 100 people. When they last looked the new cost was $170 million due to ship in 2005. He pointed out the state of Minnesota has to build the same capability with pretty much the same demographic issues as Florida - leading to very much the same broad system requirements. Minnesota started work in 1999, finished in 2000 with eight people costing $1.1 million.
Measuring by effort, 16 person-years versus 1500 (projected) person-years, shows the Minnesota project was 93 times more productive.
James A. Robertson links to a comparison of two implementations of an example web application. It compares source code rather than effort... the Java/Struts sources are six times larger than the Smalltalk implementation, and have three times more classes. The author of the Smalltalk implementation says "I do recall the folks at the users group saying that they typically spent about 5 to 10 times as long to do wafer in the Java based frameworks (1 day vs 1 - 2 weeks)".
[/docs]
permanent link
Measuring Productivity
Martin Fowler has blogged on this subject, saying that we can talk sensibly about the effectiveness of tools and methodologies because "we can't measure the productivity of development teams. Strictly the problem is that we can't measure their output - how much stuff gets cranked out."
I suggest we can measure productivity, but only at a higher level: how much time and effort does it take to satisfy the customer? Not just for the initial product, but also for changes to the product.
For example, if the customer only needs a simple word processor, and team A delivers a simple one like MacWrite in three weeks, and team B delivers a complicated one like current versions of MS Word in three months, and both satisfy the customer, I would say that team A was more productive, regardless of number of lines of code generated or the number of function points implemented.
I'd like to quote the example of two states' implementations of the same federally-mandated tracking system (Florida and Minnesota?), where one was developed in two years or less with less than a dozen people, and the other (over-budget) one was predicted to take five or more years and employ up to a hundred people, but I can't find a link. I think it was first mentioned in a keynote speech of an agile conference.
[/docs]
permanent link
Mac Success Stories
Some quotes from a MacIntouch page on justifying buying Macs...
Converting from Windows to Mac server:
Actually a 100% Windows client company that I'm familiar with went the other way. They bought a Mac OS X Server to replace their farm of Windows servers. If "it all comes down to $", this was much cheaper as X Server has an unlimited license version that is more cost-effective than the Microsoft offerings. Windows clients seem to work as well with the Mac server as with a Windows server.
Their previous Windows servers crashed regularly, caught viruses on occasion, were rather slow and cost a lot of money and time to buy and maintain. Patches every week and constant trouble calls from users. This kept the admin more than well employed.
The single Mac server that replaced them is blindingly fast, can't catch Windows viruses and hasn't been rebooted in all the months since it was installed. The admin now only has maintenance on the Windows client machines; the server requires little more than changing backup tapes....
"Today there is not a single known virus on the Mac OS X -platform"
Virus woes
I teach at the University of Texas in Austin. Recently at a faculty meeting we heard a report from our school's computer support director. She was relating the experience of her department in the weeks before school started, when the university was plagued with the now-familiar series of Windows-related viruses and worms.
It was a nearly unbelievable tale of woe and hair-tearing frustration....
For a couple of weeks, it was a common sight to see computer techs rolling around large carts filled with PCs headed for "remediation."
The head of IT services later told me that another weird twist to this tale is that students, and sometimes parents, who brought a computer from home and then started using the campus network with that computer, would reintroduce a virus/worm to the campus network. And sometimes these computers were wireless, which meant that the IT services techs were literally chasing users around a building, up and down stairs or elevators, trying to find the infected machine and get it off the network.
Our school's support tech said to me, "If it weren't for the fact that a third of our computers are Macs, I would have jumped out a window."
None of the Macs on campus needed to be "remediated." Zero. After I heard this, I asked my fellow faculty members, "Why does anyone still use Windows?" Moreover, for institutions that are facing budget constraints and a shortage of trained personnel, why on earth would any institution think that it's fiscally responsible to depend on Windows machines?
Homogeneous computing is not only stupid, it's irresponsible.
"If you look at the IT departments at prestigious private schools -- Harvard, for instance -- standardization is a dirty word."
InfoWorld's Tom Yager: "Windows doesn't live here anymore" The client switch away from Windows is permanent, and the server switch is next.... I am turning away from two core assumptions: that all x86 machines are destined to run Windows and that all worthwhile entry-level servers, business desktops, and serious notebooks use Intel CPUs. "
Cost of support
I am an "army of one" supporting 20 Windows PC's, 67 Macs for teachers, and 64 iBook laptops for students. For the past two years I have documented my service calls and support issues and I have found the split to be almost exactly 50/50. This means that 20 Windows PC's require as much support as 131 macs.
Regarding Microsoft Access (the only part of Microsoft Office that isn't available on the MacOS X platform)
Absolutely nothing has 100% compatibility with Access, not even Microsoft's own Visual Fox Pro for developers. Access is the worst database I have used. It has no clean migration pathway to any other database application. You can transfer data by exporting Access database tables, but you can not transfer Access forms, macros, or Visual Basic customizations. If you jump through some hoops, you can convert Access queries to SQL and copy them to another database. That's it.
If you need an easy to use, crossplatform database, I recommend FileMaker Pro (relational) or Panorama....
[/docs]
permanent link
Joe Ely on Kaizen Events
I looked up Kaizen Events because of a blog entry by Joe Ely. He emphasizes that kaizen events take practice, must adapt to local conditions. They reshape expectations about change, and help you re-think your job. He says that goal clarity is critical, simple real-time documentation is essential, and visual tools are critical too.
[/docs]
permanent link
What's a Kaizen Event?
Google finds this definition:
The Kaizen method is a "rapid improvement process" utilizing a cross-functioning group of managers and employees working as a team to meet targets in a results-oriented focus on a predefined project area. The process may take the following steps: define the problem/opportunity, choose the best people, and correct the problem in one week or less using Kaizen tools and techniques. The ultimate goal is to significantly reduce costs, reduce lead times, reduce required inventory space, enhance workforce empowerment, eliminate waste, and focus on continuous improvement. The Kaizen process may include: new product development, robotics, total quality control, Just-in-Time, statistical quality control, labor and management relations, or other concepts.
Another page claims these results from Kaizen Events
- 30-50% Productivity Improvements
- 30-50% Reductions in Floor Space Requirements
- 50-70% Quality Improvements
- 70-80% Reductions in WIP [Work-In-Process] Inventory
- 40-50% Reductions in Lead Time
Of course, those results came from improving conditions and processes of manufacturing (not the processes of designing and engineering), but I think most typical software processes, from requirements gathering to delivery, could obtain a 50% gain in productivity and an even higher reduction in defects by adapting a lean / agile software development process.
How would a company do this? Perhaps by starting with a facilitated retrospective. Maybe followed or preceded by a few observant people walking through the entire requirements-to-delivery process - counting how many information-lossy hand-offs there are between workers, how often work sits in queues waiting for actions or approvals, and other efficiency-killers.
Just found another definition, here:
Kaizen Event
Any action whose output is intended to be an improvement to an existing process. Kaizen Events are commonly refered to as a tool that:
- Gathers operators, managers, and owners of a process in one place
- Maps the existing process (using a deployment flowchart, in most cases)
- Improves on the existing process
- Solicits buy-in from all parties related to the process
Kaizen Events are an extremely efficient to quickly improve a process with a low Sigma score. Kaizen Events are also useful for convincing organizations new to Six Sigma of the methodology's value.
The true intent of a kaizen event is to hold small events attended by the owners and operators of a process to make improvements to that process which are within the scope of the process participants
[/docs]
permanent link
Science Daily: "Testing Information Systems During Development Will Prevent Problems"
A story at http://www.sciencedaily.com/releases/2003/09/030918093222.htm> says:
"Rather than waiting to test projects until they are completed, evaluating them at increments can prevent such troubles. That can keep projects from having cost overruns and needing time extensions."
Unfortunately, this news report is vague, mostly talking about metrics:
"The researchers developed a mathematical framework that groups metrics around the stages of project requirements; design specifications; implementation; and operation in the software system's intended environment. The framework revealed that some metrics are applicable only at certain product stages while others are applicable at multiple times. The researchers also realized few metrics exist for measuring the processes employed and resources expended during software development."
The original news release is here: http://www.psu.edu/ur/2003/testinginfosystems.html. The researchers' results are published in "Product Metrics for Object-Oriented Systems," ACM Computing Surveys, June edition.
Some other news releases at Penn State:
Calling typical suburban school campuses environments in which "severe feudalism" and intolerance to change can be witnessed, Shirtcliff advocates for new, open architecture and landscape architecture styles to alleviate the psychological effects of dismal current practices.
Life would still be possible on Earth and any Earth-like planets if the axis tilt were greater than it is now.
[/docs]
permanent link
Marathons and Software Development
Dave Hoover has a nice comparison of running/training for marathons and software development at http://www.redsquirrel.com/dave/work/marathon.html.
[/docs]
permanent link
Pico Container
On the subject of separating code into loosely-coupled components... see PicoContainer. (This may be ancient history [June 2003] for some people.) Some quotes:
"PicoContainer is very simple container for very simple components. It honors the Inversion of control pattern (IoC) in a way that we calling it type 3 IoC. [...] The idea is that this might scale from embedded containers for simple beans to enterprise and distributed applications."
"Inversion of Control: What is this all about? IoC is a design pattern that is also sometimes called the Hollywood Pattern ("Don't call us we'll call you") or the Chain of Command pattern. Simply put, an IoC component does not go off and get other components that it needs on instantiation. It instead declares them to its boss, and the boss supplies them."
"Pico components (to remind you) are simple java classes that declare their dependencies in the constructor(s). No meta XML for dependencies. No classes/interfaces to extend/implement."
Note that the link to composite components is incorrect, it should link to http://www.picocontainer.org/compositecomponent.html
A blogger named Rickard wrote:
"PicoContainer: Here's something on the bright side. I just found the PicoContainer/NanoContainer projects, and to me they look like the perfect way to build loosely coupled component-oriented architectures. It's just bloody brilliant. WebWork used the type 2 IoC, and XWork currently does too, but they always felt a little awkward due to the extra coding needed. But this type 3 IoC stuff is just the way it should be. Nice and tidy, with flexibility for the implementation, and supports unit testing quite nicely. Just bloody brilliant. I can't wait to toss out our own kludgey service architecture in SiteVision in favor of this."
Rickard has an example of the usefulness of constructor-specified inversion of control here.
Last word: I was expecting a paradigm shift, and all I got was a lousy constructor
[/docs]
permanent link
Code Organization
If you have insights about the following ways of organizing and documenting code, or recommendations for reading about these subjects, please email me. How do you structure your source code or otherwise document the following aspects of your projects?
separating libraries, packages, or modules for dependency management
hierarchical decomposition of applications, modules, libraries, etc.
multiple teams dividing up a project into modules, libraries, packages, etc.
categorizing packages, libraries, modules and classes in non-exclusive categories
documenting data-flow across modules, applications, etc.
I have read Lakos's book on Large Scale C++ Design and his recommendation for acyclic dependancies of packages and bottom-up implementation and testing of packages.
I've also read Robert Martin's book on Agile Software Development that has also recommends acyclic dependencies of classes and packages, and has a chapter on package design for managing dependences.
There's hasn't been much written about "refactoring to packages" and I'd like to know why.
[/docs]
permanent link
Book Review: Extreme Programming Refactored
See Ron Jeffries' review here: http://www.xprogramming.com/xpmag/books20030904.htm.
Some quotes:
It is dangerous to read for anyone who does not understand what XP is,
because the authors have gone to such pains not to understand, to take
out of context, and to distort.
A book satirizing XP might have been amusing to some people, but would have been informative to none. A book addressing XP's limitations and how to deal with them would have been valuable to a wide range of people and might even have been made entertaining as a side effect. The intimate mixture of satire, error, and somewhat good advice is unmanageable by anyone who doesn't already know the material, and largely unnecessary for anyone who does.
Almost half the book relies on demolishing the reputation of the C3 project through mockery and satire. Unfortunately, much of the discussion is as poorly researched [...].
The authors raise one of the most important issues with XP, namely that it won't work if you don't do it. As far as I know, no process will work if you don't do it, including the authors' own favorite. While they are quick to point out, and rightly, that a so-called XP project will go off the rails if the team doesn't do XP, they do not address the same issue for other proposed processes and practices.
For more valuable discussion of the limitations of XP and what to do about them, I would recommend either Pete McBreen's Questioning Extreme Programming, or Barry Boehm and Richard Turner's Balancing Agility and Discipline.
[/docs]
permanent link
Rational Unified Scrum/XP
Marco Abis on the XP mailing list mentions a message-thread on RUP and Scrum/XP on the Scrum mailing list... here are some snippets:
Ken Schwaber: "Let us hypothesize that having a Scrum plug-in for RUP is an idea worth pursuing.[...] Is this type of metaphor appropriate for agile processes, or does this level of delineation lead to them being fodder for M/S project,for 'hands-off' management, and for robotic tracking of plans while ignoring realities?"
Ron Jeffries: "The comments from Rational clearly did not reflect the soul [of XP]. They do not get 'agile' in my opinion.[...] Their philosophy, again in my opinion, is based in large-systems experience, old-style 'up front' thinking, and a command and control orientation.[...] My involvement with the RUP XP plugin was based on my belief that it would be better with me than without me, and I think it is. Even so, it is still a long way from expressing what XP is."
Adriano Comai: "having been involved in many RUP customizations, I think RUP_Scrum makes sense (much more, in my opinion, than RUP-XP). RUP needs _exactly_ the Scrum practices to become agile. As you know, many shops with an existing waterfall culture buy RUP as an help to move towards a more effective development approach, and then misuse it."
Alan Shalloway: "You can take a committed dev group (most are) and have them do RUP/Scrum in a way that an upper management that doesn't want to hear about agile will accept.[...] here's a chapter discussing this I've just put on our public wiki (Dan Rawsthorne and I are writing a book on effective software development and this is a likely chapter). See http://www.netobjectivesbooks.com/N_O_BookFeedback_Wiki/owbase/ow.asp?DontTryToSellXP"
Marco Abis: " will try to explain why I think so (after years of effective RUP implementations!): RUP is fundamentally a very, very big framework [...] I will no spend time to write why managers like RUP but Scrum [...] makes me think that what managers want is something that isn't really useful to deliver the right project and often is the first impediment to the project success."
Adriano Comai: "Sometimes it's difficult to tell these organizations, who made huge investments into RUP: throw it off, there are more effective approaches out there, try them instead. In such cases, I believe, it is better to suggest an improvement using agile practices in the context of the existing process."
Marco Abis: "I experienced a lot of clients (of mine, of course) professing they were implementing an "Agile version" of RUP but when I analysed their work I found they were just cutting off some documents feeling "more lightweight". I definitly think this is one of the main issues: a lot of people believe Agile means just less docs, they try to cut off some of their docs and then affirm Agile is nothing more than this. As stated by Jim [Highsmith]: they are missing fundamental understanding of the unpredictability of project activities. [...] For those who haven't read it I suggest 'Agile Revolution' by Mike Beedle.
Marco referred to http://www.crystalmethodologies.org/cgi/wiki?AgileVsSelfAdapting, from which I quote Jim Highsmith: "So self-adapting, by itself isn't agile." and Alistair Cockburn: "criticisms of RUP [...] Doing the change case is very laborious. Just heard of an airline company that wants to use RUP, so they spent 6 months creating a RUP-for-them. Now every project has to spend 2 months turning that into a RUP-for-the-project. Problem is when the project is only 6 months long, this is too long."
Another Highsmith quote on that page: "But lightweight is only one aspect of agile, the other two are collaborative values and principles and a fundamental understanding of the unpredictability of project activities (although outcomes can be achieved). Agile is much more than lighter documentation and fewer processes. Rational is trying to have it both ways--still telling corporate managers what they want to hear in terms of predictability, control, productivity, etc. while at the same time touting that they are 'agile' also."
[/docs]
permanent link
Learning by Reading and Doing
I'm stating the obvious here, but it needs to be said: there is learning by doing, and learning by reading. This is the core, I believe, of the perpetual re-implementation of ideas in the software industry, and it is the bane of those trying to port software rather than re-implement it. (By coincidence, Joe Ely also writes about "the Knowing-Doing Gap" on his "Learning About Lean" blog.)
Consider that the first portable virtual machine environment and programming language designed to "run anywhere" (that I know of) was the UCSD P-System, an extended Pascal language that compiled to byte-code, a byte-code interpreter, and various other tools that ran on several machines in the early 80's including the Apple IIe. Later there was Smalltalk and its virtual machine, now there is Java and other languages on the JVM, C# and other languages on dot-net virtual machine, Perl, Python and Ruby on their own virtual machines. Lots of re-implementations of the same basic concepts, each with their own variations.
Back to reading and doing... This difference between learning-by-doing and learning-by-reading is the reason software keeps being re-invented. If I'm confronted by a bunch of code, even if it is moderately well-written and documented, I'm only reading it. My understanding will not be as deep as it would be if I had written it myself, or participated in writing it. For this reason, my recommendation to anyone confused by a test framework like JUnit or CppUnit, would be to study the documentation about JUnit, and then write your own test framework from scratch.
Consider an analogy: In learning by reading, I can read about how to rebuild an automobile engine, but that isn't going to give me the skills to actually do it. In learning by doing, I can have someone guide me through the steps of rebuilding several automobile engines, until I'm able to do it by myself, even with an engine-design similar but not necessarily identical to the ones I've practiced on.
To redesign an engine, say to burn a different kind of fuel, to fit into a different space, or to use a different number of pistons, the book-learning is far from sufficient, though books on engine theory could supplement the learning-by-doing of building and rebuilding engines. I would need know how to design engines in general, to be able to redesign an engine in particular.
Now when we write software, we learn a lot of things, not only about our design and the domain, but also about the environment our design has to live in. Particularly the "corner cases" where the platform dictates aspects of the design. What happens when you want to port that software to another platform?
In the best case, you actually implement your project on all the desired platforms at once. Just add "the integration is not complete until all tests pass on all platforms" to Extreme Programming's "Continuous Integration" and "Testing" practices. You end up learning about all the corner cases of all the target platforms by doing the work necessary to complete a story or task on all the platforms. You do this a little bit every day.
In the worst case, one team developed software on platform A, and another team has to port the software to platform B, and the B-team doesn't have the A-team helping them understand their code. The code whose design was influenced by the "corner-cases" of platform A's environment.
The B-team reads the code, but since they didn't write it, they can't easily tell which parts are of the originally-intended design, and which parts had their design modified by the target environment. The B-team has to know platform A well enough to figure that out (which may require more in-depth knowledge of platform A than the original coders had). The B-team also has to know platform B well enough to modify the design to conform to the "corner-cases" of platform B. That's a whole lot of knowledge required, and a lot of it has to come from doing, because reading isn't enough -- much of the "common knowledge" of programming for a platform isn't written down anywhere.
The B-team really needs to know more than just the source-code. They also need to know the requirements because sometimes reading the code isn't always enough to figure out what requirement it was trying to implement. (And the code could be incorrect -- not fulfilling a requirement.)
If the software hadn't been tested thoroughly, some of the code (individual functions, for example) may not even work properly for all inputs/situations on platform A. Trying to get it to work properly on platform B may not even be necessary, but reading the code may not answer that question. Trying to figure out if the original programmer intended some "weird" behavior, or was just having a bad coding day, can be frustrating.
In a non-test-first code-base, there is probably dead code that isn't actually called, and thus porting it is unnecessary. There is probably code that was prematurely generalized, and thus only specific cases need to be made to work on the second platform. There is probably code that was prematurely optimized, or correctly-optimized for platform A, but which needs a different form to be correctly-optimized for platform B.
The porting job can be made much easier if we have programmer-tests that came from Test-Driven Development. Test code is usually pretty simple compared to the code-under-test, so it is usually easy to port. If you can get the programmer tests ported over to the target environment, then porting the code-under-test is optional: you could instead write fresh code to satisfy all the tests. You would mostly likely be implementing a similar design, but you would not be having to concern yourself with the corner-cases of platform A, only those of platform B. This means that you don't have to understand the corner-cases of platform A, except as they might be reflected in the tests. If you do port the code-under-test, getting it to pass the tests in platform B can reveal the corner-cases of platform B, in a testing situation where the code under test is isolated and "exposed" and therefor easier to debug.
Some might say "write more documentation." But that relies too much on learning by reading again. The programmer tests and acceptance tests actually execute and demonstrate pass/failure. You can "do" the tests by running them. Documentation is passive, can be misleading, and rarely is there enough detail to make porting software easy. Test-driven development provides a level of detail that was essential to write the software, and was painless to write, but would have been mind-deadeningly too massive to write in a non-executable (non-automatically-validating) prose format.
To sum up: writing fresh code on platform A only requires knowing the requirements and the foibles of platform A. Ditto for platform B. Implementing the requirements helps you learn the problem domain, and to learn the target platform. To port code from A to B requires knowing the requirements, the design, the problem domain, the foibles of platform A, and the foibles of platform B, which adds up to too much.
[/docs]
permanent link
A Rose Tested By Another Name
In the XP community, names are often re-thought, in an attempt to more clearly and succinctly convey their true meaning. So "Unit Tests" evolved into "Programmer Tests" and sometimes "Test Driven Development Tests" (my preference leans to "Test Driven Design"). The latest phrasings seems to be "code-guiding examples" and "checked examples" as well as "change-detectors".
(Tim Bacon summarizes many of the names here.)
I admit that the word "tests" seems to evoke something counter-productive when trying to discuss or teach Test Driven Development. I was trying to explain TDD to someone yesterday, and he started objecting about the masses of data his tests would have to shovel through his code. I explained that if his code can handle one, two, and three pieces of data, he would not necessarily need to write additional tests for a hundred or a thousand... and the point of the tests in TDD is to drive the design, not to test the code.
As precise as we want our jargon to be, we will have to live with defining our terms. Consider that "rose", according to http://dictionary.reference.com/search?q=rose has more than 48 definitions, if you include the verb "rise". See also "Rose is Rose".
[/docs]
permanent link
Ruby TDD Example
Nice example of Test-Driven Development in Ruby: http://jimweirich.umlcoop.net/articles/tdddemo/index.html.
I'm not a big fan of Ruby. I'd rather have a method named "isFoo" than "foo?", and member variables named "bar" (or "mBar", or "myBar", depending on coding standard) instead of "@bar".
One problem of small examples of TDD is that people look at the tiny steps being taken and assume TDD will be very tedious. In real life, your steps are most likely going to be bigger than these small examples, and you will have lots of other (already-TestDriven) code to build on.
[/docs]
permanent link
Audience Empowerment
Wireless networks, palm and laptop computers, and internet chat are beginning to change the lecture experience for the audience, and soon, the presenter. Audience members can chat with each other without disturbing the speaker, commenting on or refuting what the speaker says in real-time.
Apparently some conferences have also enabled the chat to be displayed on a screen behind or in front of the speaker. Kevin Marks refers to a blog entry describing his own "heckling" of a speaker. Kevin Marks has a "HeckleBot" an LED screen for displaying live text, with internet/web access.
Quotes:
An excerpt from Conferenza, which provides a tad more traditional paid research coverage of trade shows, contains this golden nugget of controversy:
Asserting that the largest e-commerce software supplier is Amazon.com, Benioff pointed toward co-panelists from IBM and Sun Microsystems and said, "None of these companies has any position in [that] market at all. Even Apple's iTunes music store was built on Amazon," [....]
We thought this was news, until [...] an online chat charge showing that most of this was apparently untrue: Amazon uses standard XML out-of-the-box stuff, and Apple's iTunes doesn't use Amazon's software at all, the chatters charged. As Benioff continued, the audience watched as a group of online contributors disputed fact after fact, input Benioff apparently did not see. "It was sort of like a 'Saturday Night Live' skit," said one attendee. "As Mark spoke, we could see his nose growing longer, like Pinocchio."
How it played out in the Chat (Archive) was Kevin Marks did the fact checking, which was simultaneously projected on to the big screen:
[11:51] KevinMarks: no he didn't
[...]
[11:51] KevinMarks: he licensed the patent
[11:51] KevinMarks: iTunes backend is not Amazon
[...]
[11:51] Ross: Amazon's real smart move was an API for developers
[...]
[11:52] Ross: but they dont get decentralization. witness http://www.allconsuming.com
[...]
[11:52] KevinMarks: Apple had ahuge online store already selling Macs
[11:52] KevinMarks: they built on that for iTunes
[...]
[11:54] DariusD: Do you know that the Apple onnline store was not built on Amazon technology?
[11:54] KevinMarks: It is built on Webobjects
[/docs]
permanent link
Movies as Projects
Laurent wrote about Lost In La Mancha, the documentary about Terry Gilliam unsuccessfully trying to make a movie. I have only watched the first hour so far, but I can see lots of awareness of potential and actual problems, but no addressing of those problems, reminding me of that people usually know that their project is doomed from the start.
I rented and saw American Movie, another documentary about making a movie. In the case of American Movie, the director/writer Mark Borchardt actually achieved a kind of low-budget success -- he managed, in the course of two or three years, to finish a short film and show it at a theater to a sold-out audience. He probably didn't make a profit, and he and his unskilled laborers were probably unpaid, but he was able to film and re-film, record sound, and re-record sound, edit, and re-edit, while having a day job delivering newspapers and/or working at a cemetery. The documentary is fascinating. The short film that Borchardt created, "Coven", is included on the DVD and is comparable to the films of Ed Wood, but is probably even worse, though quite fascinating if used to psycho-analyze Borchardt.
It was quite the movie weekend. I also rented the Jackie Chan movie Shanghai Knights and listened to the director's commentary and the writer's commentary AND read Jackie Chan's on-line diary he wrote during the filming. One thing about this movie, which is better than Shanghai Noon, is that the director allowed Chan more time to choreograph and film the fight-sequences that Chan is famous for.
Unlike the rest of the movie - very much planned up-front, with a lot of parallel activities - the fight scenes are choreographed and filmed in a "agile/just-in-time" manner: Chan would make up a short part of the fight sequence, rehearse it with the other actors/stunt-men, instruct the directory/camera-man where to position the camera for that sequence, film it, and then move on the next bit.
This movie was an American production, filmed mostly in the Czech Republic, and the differences in process from a Hong Kong film continue to amaze Jackie Chan -- the enormous amounts of catered food and time off for lunches, the expense in set-building/special effects/costuming, shooting in two units to reduce calendar time, and the reasonable working hours. For the sake of one (not that funny) joke, they created a replica of Stonehenge in a field somewhere in Czech Republic. It was probably made of styrofoam, but still that means a day or two of filming (and having to cope with rain) - one pretty costly joke that a Hong Kong or independent movie-maker could not have afforded.
[/docs]
permanent link
Flash Mobs
Erik Benson points to a page on Flash Mobs. This is apparently derived a concept from science fiction, being made real (in a way).
The original concept, described in a short story "Flash Crowds" by Larry Niven, was that live news reporting of some event, combined with instantaneous, free transportation, would result in huge crowds arriving at the location of the event while it was being reported.
In Flash Mobs, people use the internet to announce a time and location, and people show up, perform some attention-getting non-political activities, and then leave. Apparently a flash mob in Boston attracted a lot of attention from the police.
While these "performance-art" flash mobs are innocuous, I am thinking that police have a good reason to worry -- a mob with terrorist intentions could organize, appear somewhere, do something damaging, and then disappear quickly. Such a group could do something very damaging in the USA, where we have a large supply of easily-concealed hand-guns.
See also the slash-dot effect. Thanks to google and wikipedia for letting me find the Niven reference without having to search my bookcase.
[/docs]
permanent link
Juicy Bits
Joshua Kerievsky writes on the IndustrialXP mailing list:
I'm reading Tom Gilb's Principles of Software Engineering Management. I came across the following principle, which reminded me of some discussions we've had here:
The Juicy Bits First Principle, by Tom Gilb: "If you deliver the juiciest bits of the project first, you will be forgiven for not providing all they dreamt about, or for not doing it as cheaply and quickly as they hoped."
Laurent Bossavit blogged about this concept, which read like a typical XP success story... I initially didn't notice that he was quoting Jerry Weinberg's 1988 book Rethinking Systems Analysis and Design.
XP requires a person or sub-team to prioritize requirements and calls that person or sub-team the "Customer". Ideally the customer is the person paying for this project, because they are the most motivated to prioritize requirements accurately. Often, the person playing the customer role is a project manager, product manager, business analyst, or some other job title. Successful projects have someone doing this job, whether they call their process XP or not.
If you structure your project in such a way that you spend the first 80% of your project duration developing "infrastructure" (whether that is back-end code without a user-interface, or user-interface code without a back-end, or anything else that isn't fully functional part of the application from the user's perspective) and only complete the user-visible requirements in the last 20% of the project duration, you will not be able to deliver just the "juicy bits" of a project early.
XP's requirement to build releasable software in every iteration forces you to develop just enough infrastructure per requirement -- probably less infrastructure than a plan-driven approach would do -- saving time and avoiding wasted work, and getting those juicy bits to the real customer sooner.
[/docs]
permanent link
Sleep For Bug Reduction
Thanks to Ron Jeffries, William E. Caputo, and others on the XP mailing list for looking this up: a segment on Marketplace broadcast on Public Radio -- "Overtime's not good for your health."/p>
Researchers at the University of Arkansas are set to report that the number of hours worked has a very small effect on life satisfaction, sick days and worker stress [Note that this ignores productivity or the impact of long hours on the quality of the work being done.] -- but don't try selling that to commentator Joe Robinson, who has seen some other studies.... "
Robinson, author of the book Work To Live says that a Japanese study of overtime shows that 60-hour work weeks can double or triple the risk of heart attacks. Over the last 30 years, the Japanese have recorded thirty thousand deaths from overwork. The USA has less vacation time than the Japanese, but we don't record deaths from overwork, if we did, it could be a very scary number. Quoting from the broadcast:
"Almost 40% of us, now, work more than 50 hours a week, the vast majority of it completely counterproductive.... [More hours are not better,] neither for your arteries, nor for your productivity. A study by the Business Roundtable found that excess overtime not only reduces productivity during the excess hours, but during regular hours, too... People working seven 50-hour weeks don't get any more work done than people working seven 40-hour weeks... We actually work better when we're rested, not fried. Long hours are a tragic failure of the knowledge economy."
Listen (using RealOnePlayer) to the link half-way down the page at http://www.marketplace.org/shows/2003/07/31_mpp.html
More info here: http://www.worktolive.info/index.html, such as: "MRI images of fatigued brains look exactly like ones that are sound asleep."
[/docs]
permanent link
Catching Up
I've been on vacation and otherwise occupied recently, so I'm catching up. I've got more than 70 emails to read, SHAPE forum, AYE wiki, and these blogs I'm reading this morning:
[/docs]
permanent link
Spaghetti Objects and Packages
I'm not a fan of "anti-patterns", but sometimes seeing badly designed classes and packages helps you appreciate well-designed classes and packages. About the only source of advice on package design that I've seen appears in Robert Martin's excellent book Agile Software Development: Principles, Patterns, and Practices, which also has good advice on class design and test-first programming.
We often are advised to have cohesive classes, and it isn't too hard to figure out that a method which doesn't reference any member variables of its own class is a candidate for belonging to another class. This and other heuristics help us break down a too-large class into smaller, more cohesive classes.
Sometimes you have lots of cohesive classes, but they depend on each other in a tangle... it is particularly nasty if the tangle has cyclic dependencies. Robert Martin's tool for untangling dependent classes is the "Dependancy Inversion Principle" [pdf]. Classes are cohesive and independent if you only have to change one class when you want to change one thing.
An aside: Of course, with manifestly-typed languages like Java, changing one thing (like changing coordinate values from ints to floats) could bubble up and across many classes purely for keeping the compiler happy. Advocates of dynamically-typed languages say that manifestly-typed languages promote leaky abstractions because of this need to keep the compiler happy.
Perhaps even worse than classes tangled within one package, is having your packages tangled. Ouch, that hurts! Martin helps us figure out what constitutes a cohesive package by asking us to think of a package as a unit of release - what is the smallest group of classes that has to be re-released if one thing changes? This can lead to small packages, which is probably better than the alternative.
Of course, just as tangled and cyclic class dependencies make classes hard to modify or even compile, tangled and cyclic package dependencies make packages hard to modify or compile, and hard to use in isolation. The dependency inversion principle again helps break these dependency traps.
Imagine that an application (which is one of your packages) depends directly on fourteen other packages. If ANY of those other packages changes, you have to (at the minimum) rebuild your application, and potentially modify it. If each of those other packages depend on five other packages, you may have to recompile your application if any of 84 packages changed.
By using principles of framework design (the "don't call us, we'll call you" principle) and the Dependency Inversion Principle, as well as the other good advice in Robert Martin's book, you can break the nightmare of spaghetti package design.
[/docs]
permanent link
Wright Interview
I picked up a tape of the Mike Wallace Interviews of Frank Lloyd Wright the other day. It consists of two 25-minute interviews that were recorded around 1957, when Wright was around 88 years old. The first interview says a LOT about 1950's art of "the celebrity TV interview" and not much about Wright. The second interview was better, but neither one is the place to go to hear Wright say anything specific about any of his buildings.
"My name is Mike Wallace; the cigarette is Philip Morris". In the first interview, Wallace is apparently trying to get to know "Wright, the man" by asking controversial questions like "what is your opinion on organized Christianity?" and "What do you think about mercy killing?" and questions about the "Mobocracy". Wright answers the questions very carefully and reasonably, well aware that he's on nation-wide TV. Unlike modern-day interviews, the interviewee isn't prompted or allowed to tell stories about his life.
Sometimes the first interview degenerates into asking about other celebrities: "What do you think about Salvador Dali?" and Picasso? Wallace tries to get Wright to say something about Charlie Chaplin's "anti-Americanism" (Chaplin was forced to leave the US because of accusations of Communistic tendencies), but changes the subject when Wright mentions McCarthyism. The last question of the first interview is: what do you think of Marilyn Monroe's architecture?
Quote from the first interview:
"I don't think Architecture is for the Mob, it certainly isn't for education. Education certainly knows nothing of it. And very few architects in the world know anything about it. I've been accused of saying I was the greatest architect in the world, and if I had said so, I don't think it would be very arrogant because I don't believe there are many, if any. For 500 years architecture has been phony... in the sense that it was not innate, it was not organic, it didn't have the character of Nature."
In the second interview, (several months later, back by popular demand) Wright is more comfortable, and can express his philosophy at more length. Still almost nothing "concrete" about architecture, though.
Quotes from FLW in the second interview:
"I would like to make architecture appropriate to the Declaration of Independence, to the center-line of our freedom; I would like to have a free architecture. I would like to have architecture that belong to where you see it standing, an architecture that was a grace to the landscape rather than a disgrace."
[The New York skyline] "never was planned; it's all a race for rent, and it is a great monument I think to the power of money and greed, trying to substitute money for ideas. I don't see an idea in the whole thing anywhere, do you?"
Answering "give me something to live by" (the question young students ask of Wright): "The answer is within yourself. In the nature of thing that you represent as yourself. Jesus said it, I think, when he said the kingdom of God is within you. That's where Architecture lies, that's where Humanity lies, that's where the future we're going to have lies. If we're ever going to amount to anything, it's there, now, and all we have to do is develop it."
[/docs]
permanent link
These are not opposites
Is "passive" the opposite of "aggressive"? In software development, is "disciplined" the opposite of "agile"? I don't think so.
A passive person may be inactive, but still denies or resists others and context, just like an aggressive person. (Virginia Satir "self, other, context" concepts.) A healthier alternative to passive is "accepting" -- not active, but not in denial. A healthier alternative to aggressive is "assertive" - actively protecting one's self, but not denying the rights of others nor denying the reality of the context.
Dr. Barry Boehm (with Richard Turner) has a book coming out titled Balancing Agility and Discipline: A Guide for the Perplexed. The title does not reassure me that Boehm really understands agile development (in spite of the fact that he invented the "Spiral Development" model - an incremental/iterative process). We know that XP is the one of most disciplined of the agile methods, and that no process will work well with undisciplined people. The blurb from the back cover sounds better than what the title suggests:
Agile and disciplined: These apparently opposite attributes are, in fact, complementary values in software development. Plan-driven developers must also be agile; nimble developers must also be disciplined. The key to success is finding the right balance between the two, which will vary from project to project according to the circumstances and risks involved.
Fine, but then it goes back to saying these are opposites:
Developers, pulled toward opposite ends by impassioned arguments, ultimately must learn how to give each value its due.... The authors describe a day in the life of developers who live on one side or the other. They expose the bureaucracy and stagnation that mark discipline without agility, and they liken agility without discipline to unbridled and fruitless enthusiasm.
Alistair Cockburn, on the XP Mailing list, says this about "agile":
"Agile" is a value-set, a prioritization of whatever you think it means over
other things.
Therefore, it is not so meaningful to ask, "Can agile be used in this
situation?" Rather, the question is, "How agile can we be in this situation --- How can we be agile in this situation?" ... and then you get various interesting answers.
Picking up the theme of the value sets from my previous append, one might
look at a missile guidance system and say, "time to market not crucial.
people-centric not crucial. cost not crucial. correctness is crucial." In that situation, one could look to blend correctness-prioritized development with agile-prioritized development to get an appropriate mixture of the two.
Cockburn also wrote:
Consider "agile" development as a particular specie of development, e.g., a
Bengal tiger. Then asking "what is the opposite of agile development?" is like
asking "What is the opposite of a Bengal tiger?" Is it an elephant, a mosquito, or perhaps a non-Bengal tiger, or a Bengalese non-tiger?
Brad Appleton came up with a nice definition of agile (notice the first letter of each point):
- Adaptive - plans, designs, and processes are regularly tuned and adjusted to adapt to changing needs and requirements (as opposed to predictive methods that attempt to develop comprehensive and detailed plans/designs/requirements "up front").
- Goal-driven - focus on producing end-results (working functionality) in order of highest business value/priority (as opposed to being task-driven, document-driven, process-driven, or risk-driven).
- Iterative - not just iterative, but *highly* iterative, with very short development cycles, very frequent releases, and exremely frequent+regular feedback.
- Lean - simple design, streamlined processes, elimination of redundant information, and "barely sufficient" documentation and methodology.
- Emergent behavior - quality systems (requirements, architecture, and design) all "emerge" from highly collaborative, self-organizing teams following an initially minimal set of simple, generative rules, and working in very close interaction with stakeholders.
[/docs]
permanent link
Tesugen.com on Documentation
Peter Lindberg wrote
The assumption that lies behind the question You have documented this, haven't you? is that code is inherently unreadable and that there must be a manual to explain it. Many projects indeed are like that. Many projects have grand vapor architectures that exists only in the minds of those who have devised them, and can't be found anywhere in the code. Any document in such a case only reflects the vapor architecture, and is of little help to understanding the code. Let's hope there are still survivors to answer your questions.
and
My goal donor asked me, You have documented this, haven't you? to which I replied, No, except for the 570 or so automated test cases Malte and I have written during the course of the project. Each test case captures a micro-scenario in the life of the system, by setting up the objects involved, telling them to do something together, and verifying the outcome. And the fact that they are executable means that a programmer new to a team, besides having an explanation of the code to read, written in code itself, can execute that codee to see if the system still works. So it's better than documentation.
[/docs]
permanent link
Fitting In and Standing Out
A quote from Seth Godin's Purple Cow:
If you're remarkable, it's likely that some people won't like you. [...] Criticism comes to those who stand out.
Where did you learn to fail? If you're like most Americans, you learned in first grade. That's when you started figuring out that the safe thing to do was to fit in. The safe thing to do was to color inside the lines, don't ask too many questions in class [....]
A quote from Eliyahu M. Goldratt's Theory of Constraints:
We assume that the openness of these functions [marketing, distribution, etc.] will be enhanced by the positive results achieved in the other functions [production and material...]
What we found out was this is certainly not the case. [...] The emotional resistance, which already exists, prevents almost any meaningful dialog. The only way to open the Throughput channel in these case was through personnel changes.
The lesson today is loud and clear. Before any function can go on an ego trip, demonstrating and waving results (and by that digging its own grave) -- before any function can start individual improvements, all functions should decide together on a common way.
Extreme Programming is one of those "Purple Cows" that Seth Godin talks about -- it is "remarkable". Its value comes from not fitting in with what the majority of programmers do. It does more testing and more design, and requires more discipline. The documented bug-rate reductions of projects that converted to XP and their improved time-to-market are actually not believed by many, if not most managers, even when the project is within their own company.
"Selling" XP also has to recognize the manager's fears of not fitting in. Heed Weinberg's Laws of Consulting: "In spite of what your client may tell you, there is always a problem. No matter how it looks at first, it is always a people problem.... Never promise more than a ten percent improvement. (If it were possible to achieve more than a ten percent improvement, there must have been a problem, but there isn't a problem, so...)"
I'm looking to the "project community" practices of IXP to help keep an organization from rejecting XP. Retrospectives and Readiness Assessments that include more than just the programmers. Management Tests. The value of Learning.
[/docs]
permanent link
New Page on IXP
Joshua is adding content on Industrial XP here: http://industrialxp.org/description.html. On the topic of Continuous Risk Management he recommends Waltzing With Bears and Radical Project Management.
[/docs]
permanent link
Socratic Questions and Experiential Learning
One way of teaching, developed 2500 years ago by Socrates, is to ask questions and let the student work out the answers. In Theory Of Constraints by Eliyahu M. Goldratt, the author credits Socratic questions for the success of his previous book The Goal. In The Goal, a consultant helps the main character with advice in the form of questions. The reader follows the main character as he tries to come up answers to the questions; and, Goldratt says, the readers come up with the answers themselves a page or two before the main character does. (I know I did.)
Inventing their own answers motivated the readers to see if the main character came up with the same answers, and in many cases this excitement further motivated readers to apply the lesson of The Goal to their own factories.
Goldratt also talks about the stages of "science" - classification, correlation, and effect-cause-effect. In classification, we could observe that students learn things in various ways. In correlation, we could observe that some students learning via Socratic questions were more excited about their learning than others. In effect-cause-effect, we could theorize why this happens, and use the theory to make predictions which could be invalidated (or validated) by experiment.
Goldratt goes on to say that an experiment may not completely invalidate a theory, but may constrain it. For example, Newton's laws of motion are valid for speeds we see on Earth, but are constrained by other effects when the speeds are near the speed of light.
We can have a theory that Socratic questions can be effective, because someone inventing their own answers feels ownership and the excitement of invention. In some cases they've done a lot of work, and finding the answer is a big reward. However, we can also observe that Socratic questions often fail in practice... the students get irritated by that smug teacher who obviously knows the answers, but isn't giving them out. The resentment can be very strong. The questions can have responses like "Why are you asking us?" followed by arguments about motivations and agendas.
Another style of teaching that also lets the students find their own answers is called "experiential learning." In a typical case, the teacher (or, as some preferred to be called, the facilitator), sets up a "simulation" where the students can try something out in a safe environment, followed by discussion. There's no initial question, just "try this out". In the discussion afterwards, the questions could be "What do you think about X after doing this exercise" or "What were you feeling?" These are non-threatening questions, and students don't feel that the teacher already knows the answer.
In the Agile Development Conference I just attended, some of the workshops used experiential learning. In XP Coaching workshop, facilitated by Ron Jeffries and William Wake, the exercise involved some people coaching other people doing origami (from an origami instruction manual). Some other workshops also involved simulation/practice and discussion.
Ron tells us that XP Immersions that he participates in are doing more experiential learning and less lecture. Instead of lecturing about pair programming, they have the students pair program, probably followed by discussion and reflection on what happened when they pair programmed. The whole point of many training courses is to just get the students to do reflection and discussion - and this is the point of Retrospectives... enabling learning in the organization and team.
Think about learning some skill or getting answers to some of your harder problems, not necessarily a problem with technology; in your own experience, when someone told you the answer to a problem or question, did you value it as much as when you came up with the answer yourself, or practiced the skill by yourself?
[/docs]
permanent link
New Blog
Cem Kaner's Blog has as its first entry an call to arms on the SWEBOK. Here are few snippets:
In retrospect, I think that keeping away from SWEBOK was a mistake. I think it has the potential to do substantial harm. I urge you to get involved in the SWEBOK review, make your criticisms clear and explicit, and urge them in writing to abandon this project. Even though this will have little influence with the SWEBOK promoters, it will create a public record of controversy and protest. Because SWEBOK is being effectively pushed as a basis for licensing software engineers and evaluating / accrediting software engineering degree programs, a public record of controversy may play an important role.
I am most familiar with SWEBOK's treatments of software testing, software quality and metrics. It endorses practices that I consider wastefully bureaucratic, document-intensive, tedious, and in commercial software development, not likely to succeed. These are the practices that some software process enthusiasts have tried and tried and tried and tried and tried to ram down the throats of the software development community, with less success than they would like.
Only 500 people participated in the development of SWEBOK and many of them voiced deep criticisms of it. The balloted draft was supported by just over 300 people (of a mere 340 voting). Within this group were professional trainers who stand to make substantial income from pre-licensing-exam and pre-certification-exam review courses, consulting/contracting firms who make big profits from contracts that (such as government contracts) that specify gold-plated software development processes (of course you need all this process documentation - the IEEE standards say you need it!), and academics who have never worked on a serious development project. There were also experienced, honest people with no conflicts of interest, but when there are only a few hundred voices, the voices of vested interests can exert a substantial influence on the result.
See also my entry on this subject.
[/docs]
permanent link
PowerPoint Thinking
First there was the Gettysburg Address. Then Edward R. Tufte wrote The Cognitive Style of PowerPoint. For those of us who haven't read Tufte's book, here's a summary of it in PowerPoint form: http://www.aaronsw.com/weblog/000931. (Thanks to Jim Bullock for mentioning this on the AYE wiki.)
[/docs]
permanent link
Consulting Essay and Testing FAQ
Danny R. Faught has a short paper on being a consultant. He's also maintaining Software Testing FAQs.
[/docs]
permanent link
CMMI and Agile Notes
James Robertson's notes on talk about CMMI and Agile:
[...]
Not safety critical, but unpredictable change - appropriate for Agile. Again, IMHO, this sets up a straw man that Agile is unsafe. I don't think that's fair, and I think that the overall failure rate in the software business - including in the safety critical side - is not encouraging. [...]
A Level 5 Shop
Improvements are selected based on quantitative measurements. How do you get that? It could easily be via Agile methods. [...]
[/docs]
permanent link
Conflict Haiku and other Writings
Some good papers by Rick Brenner of Chaco Canyon consulting... the Point Lookout email newsletter.
Conflict Haiku: "When tempers flare, or tension fills the air, many of us contribute to the stew, often without realizing that we do. Here are some haiku that describe some of the many stances we choose that can lead groups into tangles, or let those tangles persist once they form."
When Naming Hurts: "One of our great strengths as Humans is our ability to name things. Naming empowers us by helping us think about and communicate complex ideas. But naming has a dark side, too. We use naming to oversimplify, to denigrate, to disempower, and even to dehumanize. When we abuse this tool, we hurt our companies, our colleagues and ourselves."
Let Me Finish, Please "We use meetings to exchange information and to explore complex issues. In open discussion, we tend to interrupt each other. Interruptions can be disruptive, distracting, funny, essential, and frustratingly common. What can we do to limit interruptions without depriving ourselves of their benefits?"
Full list of past issues: http://www.ChacoCanyon.com/pointlookout/topicalarchive.shtml
[/docs]
permanent link
Strengths and Management
I just read Now Discover Your Strengths by Buckingham and Clifton, and I'm currently reading First, Break All the Rules by Buckingham and Coffman. The books are based on extensive data collection and analysis by Gallup.
The point of First, Break All the Rules is that great managers treat each of their employees as unique individuals, encouraging their strengths, and working-around (rather than fixing) their weaknesses. The "rules" to be broken are "treat everyone the same" and "concentrate on fixing flaws".
Gallup has evidence that good managers are the primary reason for employee job-satisfaction, and poor managers are a primary reason for employees leaving a company. Managers are also a primary reason for productivity and profits (or losses) at the worker level. Of the Twelve Questions that measure employee satisfaction, the top five are directly related to how managers work with their employees.
- Do I know what is expected of me at work?
- Do I have the materials and equipment I need to do my work right?
- At work, do I have the opportunity to do what I do best every day?
- In the last seven days, have I received recognition or praise for doing good work?
- Does my supervisor, or someone at work, seem to care about me as a person?
Now Discover Your Strengths identifies thirty-four "themes" or basic strengths (which I'll call "StrengthFinder types") that people have in varying degrees, and provides an on-line test to find your top five strengths. It says that the strength that managers must have to be good managers is "Individualization," which is the natural ability to observe and identify people's strengths, style, motivation, and other unique qualities. Ironically, in a book about 34 generalized "types", it says that people with the talent for "Individualization" are impatient with generalizations and "types."
Unlike MBTI, the StrengthsFinder types are not pairs of opposites. Both type systems can help people who are not strong in Individualization to learn to see people as different from each other. There's probably some statistically-relevant relationships between MBTI types and StrengthsFinder types, but I'm not aware of any documentation on that yet.
This link explains the 34 types and give advice to students with those strengths
http://student.gallup.com/strategies.html.
[/docs]
permanent link
Don't Impose Improved Practices; The Team Must Improve Their Own Practices
Reading the book Lean Development by Mary and Tom Poppendieck has reminded me that successful group-improvement comes from self-directed (self-improving) groups -- and that the principle of self-improvement is more important than the specific practices.
They have an example of a software team within a large company that decided to improve their own processes. That improvement was noticed, and a committee formed to copy their improved practices to other teams in the company -- which never worked as well for those other teams as it did for the first team.
They also say the same thing happened (is happening) as NUMMI - the auto plant owned by GM and run by Toyota. Originally it was GM's worst plant, but within a year of Toyota taking over its management, it became one of GM's most productive plants - low absenteeism, high quality (almost as high as Toyota's plants) - with substantially the same people. GM tried to copy the practices to other plants, never with much success. The principle of continuous, self-directed-improvement is what makes NUMMI different, and which GM doesn't seem able to copy.
[/docs]
permanent link
Corrections
In Fear Of Refactoring, I wrote:
Micheal Features is working on a book about making legacy testable here: http://groups.yahoo.com/group/welc/.
That should be "Michael Feathers". Thanks to Brad Appleton for the feedback.
Ron Jeffries has written on his discomfort with the Prime Directive of Project Retrosepectives here: http://www.xprogramming.com/xpmag/jatPrimeThis.htm.
The Prime Directive of Project Retrospectives is "Regardless of what we discover, we understand and truly believe that everyone did the best job they could, given what they knew at the time, their skills and abilities, the resources available, and the situation at hand."
Jeffries writes:
We wound up, not in a "wonderful place", but in an OK place.... I don't get it. I don't get how accepting badness as "we did our best" leads to learning. There must be something after the Prime Directive. What's the Second Directive?
The prime directive isn't setting the stage to accept that nothing could be improved, it is to set the stage to look for improvements without getting stuck blaming people for what they or others think they did wrong. Once you're in fault-finding mode, everyone will try to defend themselves, trying to re-direct fault-finding onto others, and will stop sharing experiences that the group could be learning from.
We can apply Dale Emery's excellent essay "Creating Empathy" to the example posed in Ron's essay: Ron wrote some code non-test-first. It took longer than expected to debug, so that it could have been done test-first in the same amount of time. Why would he do this? He says that he had a deadline; people were asking "where the heck" is this code? He didn't know how to throw characters at the GUI code in his tests... and so on. His deeper reasons were to not let down those people; to deliver as soon as possible. The prime directive helps us assume the intentions were good, even though the results were not.
Perhaps a facilitator in a retrospective would remind the team to not worry too much why Ron didn't write that code test-first, and help them realize what the consequences were, and let the team identify things to do differently in the future.
I know of a "kick-butt" manager whose every question seems like an attack. When he says "Why did you do this?" It doesn't come out as "I'd sincerely like to understand reasons why someone would do this," it comes out as "Why would anyone be so stupid to do this?" This attitude is very demoralizing to his employees. He may not realize that when he focuses a barrage of these kinds of questions onto his employees, they become demoralized and ineffective for hours or days afterwards. This is not a way to keep the project work going smoothly. If the job market was better, many of those employees would quit.
If a retrospective was attempted with that "kick-butt" manager involved, I hope the facilitator would be strong and experienced enough to kick that manager out of the retrospective - no learning is going to happen otherwise.
The XP mailing list had many good responses to Ron's essay. To quote just one, George Dinwiddie wrote
The reason they didn't do a better job is perhaps not in the list of items you're considering (knowledge, skills and abilities, resources and situation) but certainly there was something that led them to do what they did. Of course, you can attribute it to their laziness or orneriness, but in my experience this tends to lead to non-productive confrontations.
It can be much more productive to search for what can be done better in the future rather than searching for the reason(s) that one couldn't do better in the past. Just because, for reasons that are not clear, this was the best I could do at the time, is no excuse to quit striving to do better in the future. And that striving can be done without identifying
character flaws or laying blame.
Ron asked what is the "second directive?" Several people identified that as talking about the future, identifying what things you would do in the future that would be different from what you did in the past.
[/docs]
permanent link
Agile Baby Steps
Dave Hoover is writing his experiences in an e-commerce project adopting Extreme Programming. http://redsquirrel.com/dave/work/babySteps/.
[/docs]
permanent link
Code Reviews versus Pair Programming
On the XP mailing list today, Ron Jeffries responds to a question about code reviews:
Frankly, code reviews are so much worse than pair programming that a dose of them would make me fly to pair. Let's see if we can replicate my experience.
Here's one path through a network of a million decision points:
To do code reviews, everyone has to read the code beforehand, unless you're
doing a walkthrough, see below. I'd ask everyone to come together
physically to the review. Then I'd ask them to report truthfully how much
time they spent reviewing the code. Early on, I would report truthfully
that I had spent zero or very little time, in hopes of getting others to
admit the truth. When they admit the truth, I'd dismiss the meeting and
reschedule it.
Dismiss and reschedule is the appropriate response to lack of preparation, according to Freedman and Wienberg.
Then, after a while, the only alternative is a walkthrough, since no one is
preparing effectively for the review. So we do walkthroughs for a while.
They are intensely boring, and few people stay involved. Note in your mind
the people who are present but not involved. At the end of the session,
say, holding your hand up, "Who else had a real problem staying engaged
with this walkthrough?" If there's honesty in the room, hands will go up.
Prompting may be necessary. Then: "Any ideas?"
Surely someone will think of "doing this in smaller groups or one on one".
Try it. Ask the team whether "we should empower the one-on-one folks to
change the code, and under what circumstances." Don't mention that this is
pair programming.
Try an experiment. You're "interested in collaborative programming".
Interested parties should come to the room to help. On the screen, start
writing a program. Ask for help with it, get the room to pair with you. Get
stuck (no need to fake this if you are me). Someone will start telling you
what to do. Don't get it (no need to fake this either). Get them to come up
and do it ... grabbing the chair that is accidentally beside you, while you
move over.
Note that reviews often find things. Observe how many of them are resisted
by the original programmer, or are "too much trouble to fix now".
Build a few BVCs [Big Visible Charts] relating to time spent prepping, in the meetings, number of useful suggestions (by person if you can do it without problems), number of changes made in response to suggestions, ...
Code reviews are intensely painful, in my experience, and we were trained
by Freedman himself. There will be no need to set them up to be perceived
that way, though it will take honesty among the group to express it. After
doing enough code reviews, which take way more than half the groups' time
by the way, a team who has heard of pair programming should be begging to
pair. About all you have to do is make sure that no one treats the review
session as nap time, and that you are early in recognizing the people who think it's a waste of time. Because they're right.
I have done reviews on a project that was building software for a medical device. We prepared for the code review (and also reviewed unit tests). We found issues (like not enough unit tests for specific parts of the code). The programmer corrected issues after the review, and had a second review (a walkthrough with the coder and one reviewer) to confirm that the issues were corrected. We signed off pieces of paper to have the paper trail that the FDA would expect. It wasn't the most exciting work, but we were one of the best teams, people-wise, that I've ever been privileged to work with. Truly respecting each other and working together very well.
Coding and reviewing this way was very slow - for eight person-hours of programming, expect at least a half an hour of preparation (coder and three reviewers - so two person-hours of preparation), one hour of review (times four people - so four person-hours of review), one person-hour correcting issues, and another half-hour of walkthrough (times two people - one person-hour). So for 8 person-hours of programming, there was another 8 person-hours of overhead: reviews, correcting, and walkthrough.
As is often said, "basic XP" isn't intended for safety-critical applications. But I could see the following working in that environment: pair-programming and test-driven development for four hours (eight person-hours), and a one-hour walk-through by two people who didn't do the pair-programming (two person-hours). I would expect very few issues to be found in the walkthrough that hadn't already been found (or avoided) and corrected in the pair programming, and therefore there would be much less need for correcting issues. So 8 person-hours of (pair) programming would have an overhead of 2 person-hours of walkthroughs.
While I was working on the medical device project, we didn't have acceptance testers nor automated acceptance tests. If we had been doing XP, we would have had better testing -- better unit tests, and real acceptance tests. I didn't stay on that project through completion - when our (well-liked but not very political) manager was removed from the project, and our team leader quit, almost everyone else on the team quit too. I was one of the last ones to leave, accepting an offer from Apple Computer, Inc. and moving to California. I heard the the project eventually finished, with half the man-power and twice the planned schedule. Very likely the acceptance testing was done at the end of that project.
[/docs]
permanent link
La Internacia Lingvo
When I was in high school, in the 1980's, I discovered a book on Esperanto at a library and studied it. I bought a few books, and even acquired (I don't recall how) a record album of folk songs recorded in Esperanto. It was interesting, but I never had anyone to speak it with. For academic credits in high school and college, I took Latin, another language I didn't use for speaking purposes. In case you haven't heard of it, Esperanto was one of the first "artificial languages," a language created to be culture-neutral, to enable international communication. It has very simple rules of grammar, and a vocabulary adopted from root words of many European languages. Esperanto is reported to be ten times easier to learn than a typical European language.
Created over a hundred years ago, Esperanto was not just a language, but a movement for international understanding and peace. It was denounced by Hitler and banned in Nazi Germany. The USSR in 1938 shot or deported Esperanto speakers. Pre-WWII Japan mistreated and sometimes executed Esperantists. In the USA during the McCarthy era, Esperanto was associated with Communism (and perhaps some American Communists were using it as a 'secret language'.)
Perhaps at its height of popularity, between one and ten million people spoke Esperanto world-wide. In recent years, it has been reported that Klingon and Elvish are two artificial languages with more speakers than Esperanto, though I think more people are actually fluent in Esperanto than Klingon.
Why am I talking about Esperanto? Partly because I just read an article about it in the San Francisco Chronicle, which reports that about 25 people in the Bay Area get together to speak it monthly. It quotes ELNA vice president of public relations Charlie Galvin as saying "For me, I like Esperanto because it's like a secret club. I like the fact that few people know it. It makes it special." That is so depressing, in light of the intent of Esperanto's creator.
Esperanto will always be a little-known language because there is no economic reason to learn it - and that's just fine with the Esperantists. The Esperanto-enabled travel service is free and non-commercial. In this day of international organizations (both commercial and non-commercial), Esperantists are no longer making the case that that a simple-syntax, easy-to-learn language could help people communicate with each other on a level playing field, with value gained in commercial as well as non-commercial arenas.
Another reason I'm talking about Esperanto is that it reminds me of Smalltalk. Like Esperanto, Smalltalk has a simple syntax that is pretty easy to learn. Esperanto was invented by an idealist wanting international communication. Smalltalk was invented by idealists who thought it could be a computer language easy enough for children. Like Esperanto, few people today have an economic reason to use Smalltalk. No big companies are hyping Smalltalk the way Sun hypes Java, or Microsoft hypes C#. Even IBM, which sells a Smalltalk environment, is putting more energy into Java than Smalltalk.
The rules of grammar for Esperanto can be written down in few pages, including all the exceptions. The rules of Smalltalk's grammar are also simple. This PDF explains Smalltalk syntax in relatively few pages: http://www.speakeasy.org/~podenski/stug/reading-smalltalk.pdf.
Smalltalk syntax is unusual today, though I find it easier to read than Perl or Ruby. Objective-C is a language that adds object-oriented constructs to the C language using a syntax similar to Smalltalk. One of my coworkers complained "why isn't Objective C using Java or C++ syntax?" Because it predates C++. When Objective C was invented, Smalltalk was the leading OO language. Now Smalltalk is one of the language reported as dead or near-dead by Wired magazine.
Objective-C is regaining mind-share these days because it is the recommended language for implementing GUI applications on MacOS X using the Cocoa class library. There is an economic reason for people to adopt that language -- it is the easiest way to put a really nice GUI on non-gui unix-compatible code on MacOS X. At least five books on Cocoa programming have been published in the last year on Cocoa, and every one teaches the OO parts of Objective C in the opening chapters.
Unlike some Smalltalk implementations, Objective C on MacOS X plays well with others. Linking C libraries and Objective code together is trivial. Even though the Cocoa class library is implemented in Objective C, you can write Cocoa-using applications in Java, Python, AppleScript, Ruby, and a Smalltalk-like scripting language called FScript. (C++ is too "static" to easily interoperate with classes written in dynamic languages, but Apple's version of 'gcc' allows mixing C++ and Objective C code if one is careful to cope with the differences in object allocation and deallocation.)
I would use Smalltalk it if had native GUIs on MacOS X and Windows. If it interoperated with Cocoa on MacOS X. If it easily interoperated with C libraries. If it could be used to implement shared libraries (TWAIN plugins) and other non-application code on the two platforms I need to support, and not have to be written in "dialect dependent" forms on each platform. If it didn't freak out my coworkers. If it wasn't a "secret language."
[/docs]
permanent link
Stages of Failure
From Rob Thomsett's page "Project Pathology: Causes, patterns and symptoms of project failure"... "We observed this pattern of failure in every one of the 20 major projects we reviewed. Fifteen of the 20 projects we reviewed had degraded to Step 4 and the remaining 5 were at Step 3."
The four stages of failure:
- Development team unilaterally de-scopes the project.
- Project manager requests additional people.
- Unpaid overtime work becomes the norm.
- Team has lost control of the project, but the team is in denial.
For an example of stage 4: "This denial was well evidenced in a project where all team members and the project manager felt that the project could meet a deadline 3 months out and that our review was a waste of time. In one day, we identified that the project was over 12 months behind schedule and would deliver [at best] in 15 months not 3! Our findings were wrong - the project finally delivered 18 months later."
[/docs]
permanent link
Stop the Insanity
Some people very experienced in software development looked at my Extract Method refactoring example and wondered what was so unusual about doing that. One asked "Isn't this just obvious, and what any sane person would do?" Apparently not.
There are tons of "insane", unrefactored code in companies everywhere. Even in my own current XP-ish project, there are members who sometimes write (or more likely copy-paste-modify) long methods with duplicate code, and they have more than five years of experience developing software.
For many people, it seems like their tolerance level for hard-to-read, hard-to-maintain code is high, possibly because their high intelligence lets them sort things out in their minds - at least when they're familiar with the code. If only they would sort it out in the code itself.
I imagine those "tolerant" people get irritated by us "intolerant" Extreme Programmers, who want the code to be so easy to read and enhance that it looks like it was easy to write. There's an old joke in programmers circles - "If it was hard to write, it should be hard to read" - that is unfortunately too true.
If you really want to get insane code - long methods, lots of duplication - measure your programmer's productivity by counting lines of code. You'll get what you measure.
[/docs]
permanent link
Shopping
Andy Hunt blogs about shopping, not being able to find a shampoo that doesn't have fruit juice or herbal essences in it. He calls this "herd marketing" and writes: "It should be [...] the things I want. Isn't that supposed to be the essence of marketing? Give the people what they want -- not what everyone else wants to give them, or even what you want to give them."
Well, my understanding of typical marketing is that it's all about getting people to want what you have to offer, not offering what people want. Harry Beckwith's book Selling The Invisible was refreshing in that he goes against the grain, and says that selling the steak is more important than selling the sizzle.
And by the way, I don't mind herbal essences in my shampoo. My wife says she likes the way it smells.
[/docs]
permanent link
Getting Better
Laurent Bossavit quoted Beck in his blog, referring to http://c2.com/cgi/wiki?GettingBetter. Thanks, Laurent.
How good the design is doesn't matter near as much as whether the design is getting better or worse. If it is getting better, day by day, I can live with it forever. If it is getting worse, I will die.
[/docs]
permanent link
More on Refactoring
Ken Arnold points out Martin Fowler commenting on Cringley's post on Refactoring.
Somebody, possibly Kent Beck, said something very much like "If the code quality is going down, you're doomed. If the quality, however bad to start with, is always going up, you have a chance at success." (I can't find the quote. I need google to Find What I mean, not what I ask it to find.)
Every company that has invested in software has invested in an asset that they can choose to improve or let decline in value. If those software assets never need to change - no bug-fixes, no enhancements, no adapting to changes in the software ecology (new versions of libraries, new OSes) - then don't refactor.
[/docs]
permanent link
Fear of Refactoring
Fear of changing legacy code is healthy, if the legacy code is not fully covered by automated tests. You need something to rapidly tell you if you've broken something when you're doing a code improvement. Micheal Features is working on a book about making legacy testable here: http://groups.yahoo.com/group/welc/.
Probably a good motivator for improving code is measuring the cost of changing code for bug-fixes and feature additions (and measuring the Fault Feedback Ratio). The older and cruftier the code is, the higher the cost of changing it. The cost of refactoring (which will reduce maintenance costs in the long run) has to be weighed against the increasing costs of maintenance when no refactorings are being done.
Perhaps the best way of addresssing fear of refactoring is by practicing it on toy projects. William C. Wake has a book called The Refactoring Workbook due in July. Preview chapters are on-line: http://www.xp123.com/rwb/.
The other key thing about refactoring to improve the design by taking small steps. For example, most code has functions and methods that are too long, containing multiple 'bundles' of lines, sometimes with comments describing the intent of each bundle. Use the extract method refactoring to move each little bundle of lines into a new function, named after that comment. (See my example below.) When big methods have been broken down into small methods, duplicate code becomes more obvious, and can be removed, reducing the amount of code to be maintained and raising the level of abstraction in the code.
Big refactorings are much easier if lots of small refactorings have already been done. It is important that the team members agree on the value of the small refactorings - you don't want inviduals to 'undo' each other's code improvements.
Example of "extract method" refactorings - pseudocode
"before"
procedure testVerylongmethod
var result = Verylongmethod
var expectedResult = 2398
assertEqual( expectedResult, result )
end procedure
function Verylongmethod
// set up foos
var foos = array [1..3] of foobar
foos[1] = new foobar(2,2,3,4)
foos[2] = new foobar(3,4,6,3)
foos[3] = new foobar(4,67,83,3)
// calculate muckiness
var muckiness = 0
for index = 1 to foos.length
muckiness = foos[ index ] . muckinessQuotient( index ) + muckiness
end for
return muckiness
end function
"after"
(the test doesn't change, so I don't reproduce it here.)
function setupfoos
var foos = array [1..3] of foobar
foos[1] = new foobar(2,2,3,4)
foos[2] = new foobar(3,4,6,3)
foos[3] = new foobar(4,67,83,3)
return foos
end function
function calculatemuckiness( foos )
var muckiness = 0
for index = 1 to foos.length
muckiness = foos[ index ] . muckinessQuotient( index ) + muckiness
end for
return muckiness
end function
function Verylongmethod
var foos = setupfoos()
var muckiness = calculatemuckiness( foos )
return muckiness
end function
Now imagine that there is Anotherlongmethod similar to the original function Verylongmethod, where the only difference in how it sets up the foos array. It can be refactored to call the same calculatemuckiness method that had been extracted from Verylongmethod.
"before"
procedure testAnotherlongmethod
var result = Anotherlongmethod
var expectedResult = 9487
assertEqual( expectedResult, result )
end procedure
function Anotherlongmethod
// set up foos
var foos = array [1..4] of foobar
foos[1] = new foobar(2,9,3,4)
foos[2] = new foobar(3,9,6,3)
foos[3] = new foobar(4,9,83,3)
foos[4] = new foobar(9,9,9,9)
// calculate muckiness
var muckiness = 0
for index = 1 to foos.length
muckiness = foos[ index ] . muckinessQuotient( index ) + muckiness
end for
return muckiness
end function
"after"
(the test doesn't change, so I don't reproduce it here.)
function setupfourfoos
var foos = array [1..4] of foobar
foos[1] = new foobar(2,9,3,4)
foos[2] = new foobar(3,9,6,3)
foos[3] = new foobar(4,9,83,3)
foos[4] = new foobar(9,9,9,9)
return foos
end function
function Anotherlongmethod
var foos = setupfourfoos()
var muckiness = calculatemuckiness( foos )
return muckiness
end function
Please forgive all the magic numbers; I wanted to keep the example self-contained. While the safety of these refactorings can often be determined by code inspection, they are best determined by tests - the test don't change during (most) refactorings, and they should be passing before and after the refactoring.
[/docs]
permanent link
Data-Driven GUI Code and YAGNI
Ron Jeffries has written an essay refuting the myth that YAGNI ("You Ain't Gonna Need It) prohibits data/table-driven code. He's coding in C# and his examples are for menu items.
[/docs]
permanent link
Response to Unit Testing In Java
Previously I used my review of the sample chapter of the book Unit Testing In Java by Link and Frohlich to launch my diatribe against the typical Java-book method of creating widgets in windows/dialogs. Johannes Link send me this comment:
Subject: Unit Testing in Java
Hi Keith,
Compliments on being so quick in reviewing the sample chapter of "Unit
Testing in Java". That's really impressing.
One thing I'd like to comment on: You're perfectly right when saying that
implementing ActionListener in the window class itself usually leads to loads
of duplicated code. The code in the book, however, is in a temporary state. As
long as there are only two buttons the code is easier to read (IMO) than
when using anonymous inner classes. Refactoring to a different solution would
certainly take place during one of the next enhancements. The point is: Having
the tests in place allows you to perform this refactoring on stable
ground...
BTW, your blog really is worth reading.
best wishes,
Johannes Link
When to do refactoring is certainly worth further exploration. Martin Fowler has the "three strikes" rule to remind him to refactor away duplication when a third instance is seen. Extreme Programming recommends "once and only once" to refactor after the second instance is seen. But when your current task is test-driving a dialog or widget-filled window, at what point do you refactor to a dialog-creator class - after the second button, or after the second dialog, or never?
[/docs]
permanent link
So-Called Software Engineering Body of Knowledge (SWEBOK)
Grady Booch has this to say about the SWEBOK: "The SWEBOK I reviewed was well-intentioned but misguided, naive, incoherent, and just flat wrong in so many dimensions."
Cem Kaner writes "I think SWEBOK promotes a set of practices that are sometimes appropriate, but in many contexts thay are as outrageously expensive as they are remarkably ineffective. The idea of adopting these as a standard of care for our profession, is, at least to me, abhorrent."
It seems like the SWEBOK group ignored Grady Booch and many other reviewers three years ago. It attempts to be an authoritative reference of "generally accepted" practices, but the SWEBOK does not reflect principles and practices of agile software development, and otherwise misrepresents itself when claiming to be "generally accepted" by our diverse "industry". Do game developers, web-app developers, AI researchers, and shrink-wrap software developers need to use the same practices? SWEBOK may be representative of Department of Defense contracting practices (which is far from "general"), but even the DoD is trying to develop software systems in more agile ways these days.
The SWEBOK is again open to review. Cem Kaner recommends that we become reviewers to highlight that the practices the SWEBOK preaches are not accepted by all. I recommend that you not only review the SWEBOK and provide your comments to that group, but you also post your comments on the web, so that everyone using a search engine can see the controversy around the SWEBOK.
One danger of the SWEBOK is that it would be used to license software developers. Software development is too broad a field, too immature, and too rapidly changing a profession to have meaningful tests for licensing developers. Cem Kaner was part of the ACM task force that considered and rejected the SWEBOK and licensing based on it. Check out what the ACM task force had to say about it at http://www.acm.org/serving/se_policy/. The ACM task force writes:
- Licensing as Professional Engineers would be impractical for software engineers, because it would require examinations over subjects most software engineers neither study in their formal education nor need in order to practice competent software engineering.
- Licensing software engineers as Professional Engineers would have no or little effect on the safety of the software produced.
- The SWEBOK effort, which specifically excludes from the body of knowledge the special knowledge required for most safety-critical systems (such as real-time software engineering techniques), will have little relevance for safety-critical systems, and it dangerously excludes the most important knowledge required to build these systems.
- Each industry and software engineering domain will need to determine an appropriate mix of approaches that work together to solve their particular problems and fit within the cultural context of the particular industry. There are no simple and universal fixes to solve the problem of ensuring public safety. Effective approaches will involve establishing accountability, competency within specific application domains and job responsibilities, liability, regulation where appropriate, standards, voluntary product certification and warranties, and industry-specific requirements. Licensing as Professional Engineers would not be an effective way to accomplish any of these goals.
The task force recommended that:
- ACM withdraw from efforts to license software engineers as Professional Engineers.
- ACM take a stand against government efforts to require the licensing of software engineers as impractical, ineffective with respect to protecting public safety, and potentially detrimental with respect to economic and other societal and technological factors.
- ACM not support the SWEBOK activities, but consider supporting other efforts to validate and codify basic knowledge in various aspects of software engineering.
[...]
- The professional societies, including ACM, must pursue every possible means towards improving the current state of affairs. At the same time, they must refrain from pursuing activities like SWEBOK that have a significant chance of reducing the public's understanding of, confidence in, and assurances about key properties of software.
When reviewing, please include positive comments as well as negative comments. If it's all negative, they will feel tempted to dismiss all that you write. George Dinwiddie had a good example of both positive and negative in the xp mailing list:
They say, "One of the fundamental tenets of good software engineering is
that there is good communication between system users and system
developers." That's very good, but the next sentence says, "It is the
requirements engineer who is the conduit for this communication." I
don't see any justification for the assumption that there must be an
intermediary.
Not only could a reviewer say that good communication is a good thing to emphasize, but the reviewer could then follow that by commenting that the assumption of a "conduit" is not generally accepted, perhaps referencing materials that document the "telephone game" effect of having someone between the system developers and the system users. Sure, a facilitator of some kind ("business analyst" or "human interface designer") is very helpful, but as an aid to the communication, not as a substitute for it. Extreme Programming, for example, says the "customer" should "speak with one voice", but not that the "customer" be a single person -- and if you call him a "requirements engineer", does that mean that person will have to a licensed engineer as well? How much of a priesthood do we need?
[/docs]
permanent link
Selling the Invisible
I found the book Selling the Invisible by Harry Beckwith to be a very interesting and inspiring read. Those of us working in software development deal with the invisible all the time. While some of us may write shrink-wrap software, and can point to the box as proof that our product exists, even that product can be mostly invisible: anti-virus software, for example, should be invisible until it tells you it found and eliminated a virus (and maybe even then).
Selling the Invisible is about marketing and a lot more: some of the best marketing comes from having a good product or service, and happy clients or buyers. It comes from maintaining good relationships. I recommend this book. It gave me an idea for my company that could be profitable, and I've only read the book once through so far.
"Management" is mostly invisible - the worse management is, the more visible it is. The best managers (I'm told) often seem like they are neither busy nor doing "any work," because they've done a lot of work to keep potential problems from turning into actual problems. Managers could do with reading this book, considering their bosses, peers, customers, suppliers, and direct reports as "customers", all of whom to maintain good relationships with.
Software development methods can be invisible too. Particularly agile methods that don't produce many artifacts other than the software itself. The recommended "big visible charts" (in particular the scrum burn-down chart adapted for XP) help make the invisible stuff visible, and help keep a good relationship with the customer.
In fact, I thought Kent Beck wrote a message in the IXP mailing list that sounded like the "positioning statement" exercise of Selling the Invisible, but now I can't find it. I'll attempt to do the exercise here, using me as an XP coach/project leader. The positioning statement answers the questions of Who, what, for whom, what need, against whom, what's different, and what benefit.
Keith Ray is a coach and project leader for small to medium-sized projects (up to 10 programmers) which need to ship good quality software, quickly and/or frequently, whether the desired features are vaguely defined, changing, or very specific. Unlike many in this industry, Keith Ray has been developing software for over 15 years, and has participated in many successful projects in several product areas, creating and shipping good software at a predictable pace. Keith Ray uses good, context-specific, practices to enable you to get the important features you want as soon as possible.
You notice I don't say "XP" or "agile" in this statement - people are looking for solutions to their problems, and don't care about the techniques I use (I hope). What's your positioning statement?
[/docs]
permanent link
Unit Testing In Java, Duplicate Code in Java GUIs
Johannes Link announces that the book Unit Testing In Java by Link and Frohlich, is now available for purchase, even though Amazon says it isn't yet. Link says the book teaches Test Driven Development in Java, covering GUIs, web-applications, databases, multi-threaded applications and other advanced topics. A sample chapter is available here: [PDF, 28 pages] http://www.bhusa.com/bookscat/samples/1558608680/1558608680.pdf?mscssid=W2B78S2RV83D8K9W260JPX1W0DUJ9DC7.
The sample chapter on test-first Swing GUI programming isn't that different than other writings on Java GUI test-first. Near the end of the chapter they discuss JFCUnit, and briefly mention AWT Robot, neither of which they recommend for typical test-first unit testing. I will order the book and read it.
One nit I'd like to pick: the authors make the JFrame subclass an ActionListener, listening to the "Delete" button and the "Add" button. This is very common in Java books, but that doesn't make it right. Making the JFrame an ActionListener on multiple widgets means we have some tightly coupled pieces of code (reformatted - I like the braces to line up):
public class CatalogEditor extends JFrame
implements ActionListener, ListSelectionListener
{
...
private void addAddButton()
{
addButton = new JButton("Add");
addButton.addActionListener(this);
getContentPane().add(addButton);
}
... etc. (similar code to add "Delete" button)...
public void actionPerformed( ActionEvent e )
{ // blech... nasty.
if ( e.getSource() == deleteButton )
{
deleteButtonClicked();
}
else
{
addButtonClicked();
}
}
...
This is nasty because it couples the JFrame too tightly with the buttons it is listening to. If you add another button, you also have to change the actionPerformed method. You would rather not have to change multiple pieces of code when you add "just one more thing". There is a better way (using anonymous subclassing) - don't declare the JFrame to be an ActionListener; instead, pass anonymous implementations of ActionListener to the buttons like so:
public class CatalogEditor extends JFrame
{
...
private void addAddButton()
{
addButton = new JButton("Add");
addButton.addActionListener
( new ActionListener()
{
public void actionPerformed( ActionEvent e )
{
addButtonClicked();
}
}
);
getContentPane().add(addButton);
}
... etc. (similar code to add "Delete" button)...
// now there is no need for an actionPerformed method that uses
// cascading if statements.
I also want to point out the code duplication we have: creating the "Add" button is almost the same code as creating the "Delete" button (not shown). That kind of duplication seems to be common in Java GUI programming, but it is really unforgivable when you have lots of dialogs and buttons. What can we do about it?
First, we could have a DialogCreator class that reads the button names from a text file, creates them, and adds them to the ContentPane of the JFrame subclass (which it could also instantiate). It could also read the layout name and other information needed to lay out the GUI. In order to get the "Add" button's listener to call the method "addButtonClicked" in the JFrame subclass, we need to use the Java reflection API. Here's the pseudo-code:
class ListenerCaller implements ActionListener
{
public ListenerCaller( Object objectToCall, String methodNameToCall )
....
public void actionPerformed( ActionEvent e )
{
... reflection to call methodNameToCall of objectToCall...
}
}
Notice that the ListenerCaller class doesn't care what kind of class it is calling. You could connect your GUI buttons to your model classes directly this way. Apple's Cocoa does something similar - the Cocoa widget classes (menus, buttons, etc.) take an object (called "target") and a method selector (easily created from a string) and call whatever object and method that you specify. You would normally do this specification in the Interface Builder.
class DialogCreator
{
...
public void CreateDialog( textfile )
{
String jfClassName = read JFrame subclass name from textfile;
JFrame jfObj = ... reflection to create object given jfClassname;
String layoutName = read layout name from textfile;
// also read number of arguments, etc... this can get complicated.
Layout lay = ... reflection to create object given layoutName,
number of arguments, argument types, etc.;
jfObj.getContentPane().setLayout( lay );
while not end of buttons
{
String buttonName = read button name from textfile;
String methodToCall = read method to call name from textfile;
JButton aButton = new JButton( buttonName );
aButton.addActionListener( new ListenerCaller( jfObj, methodToCall ) );
jfObj.getContentPane().add( aButton );
}
}
}
A single DialogCreator class like this removes button-creation code from all your Swing GUI code. Given that GUIs have a nested hierarchical structure, you probably want your text file to reflect that structure as well, using XML, and creating all kinds of widgets, not just buttons. It turns out that someone has already done all this work (and more) and called it XMLTalk.
I haven't used XMLTalk myself, because I haven't needed to do very much Java GUI programming, and I'm not sure about its license agreement. I haven't downloaded the source, but I have looked at the white papers and other documentation. It is worth studying to see how ValueModel adapters and other helper classes can be used to decouple your GUI code from the model code, and to decouple some of your model classes from each other. I should point out that XMLTalk is based on concepts first(?) implemented in VisualWorks Smalltalk. You should check out their product as well.
[/docs]
permanent link
Refactoring is Not Rewriting
I'm concerned that people are getting sloppy about their usage of the word "refactoring." I had a short dialog with someone asking about refactoring, bug-fixing, and testing, where the questioner revealed that he had not read Martin Fowler's book "Refactoring: Improving the Design of Code." If he had read the book, then he would have known that refactoring is improving the design without changing behavior, and could have avoided problems from combining bug-fixing with design improvements.
If you're writing or fixing code, particularly in an object oriented language, you must buy and read
Refactoring: Improving the Design of Existing Code by Martin Fowler.
That book and Design Patterns by Gamma, et. al. are essential reading no matter what methodology you might be using.
In test-driven design, refactoring is the design step: test, code, refactor, repeat.
Martin Fowler has a blog/wiki (a bliki) here: http://martinfowler.com/bliki/, which I'm adding to my blog-roll. (I'm delighted to see I'm already on Fowler's blog-roll.) I'd love to make my site into a bliki, but unfortunately, my site is static (updated only when I'm adding a new entry) - there's no cgi. My time is full with working, reading, and blogging, so I probably won't get around to writing my own bliki software (though it would be a good exercise.)
That questioner I mentioned was asking about refactoring, bug-fixing, and testing legacy code. I forgot to point him to Michael Feathers, currently working on a book titled Working Effectively with Legacy Code, and the mailing list discussing the book, http://groups.yahoo.com/group/welc/, but I'll do that after finishing this blog entry.
Here's my advice on this topic.
First, keep refactoring and rewriting (bug-fixing) separate. These two activities may be done only five minutes apart, but you're wearing a different "hat" during each activity. Refactoring is improving the design of the code, while preserving its behavior. Bug-fixing is changing the behavior.
Since unit-testing legacy code is almost always difficult, try writing some automated acceptance tests before doing other changes. The acceptance tests will hopefully not need to be changed much during refactoring and bug-fixing activities.
When confronted by legacy code, my first step would be to review the sources, fixing up formatting problems - indentation and spacing. Badly-designed code is often badly formatted. This gets me familiar with the code without changing its behavior. This helps me understand the code. Doing this might seem too boring to do with a pair programmer, but the alternative would be to do code reviews, which are even more boring. If automatically reverse-engineering class diagrams and other UML diagrams is possible, I would do that.
If I have a bug to fix, I recommend writing an acceptance test or unit test that shows the bug's effect. Then track down where the bug is - what defects in the code cause the bug. I know from experience that it is really hard to get into the habit of writing the test before doing the debugging; I do think this test-first habit is a valuable one.
When you've found the code-defect, it can help a lot to do a little refactoring to make fixing the bug easier. Run the few tests that you now have and do manual testing to make sure that the refactoring hasn't changed any behaviors or broken anything. Then fix the bug, and run the tests to confirm that the bug is fixed. Then maybe do a little more refactoring in that area of the code and re-confirm that no behavior has changed from that refactoring.
At the beginning of this bug-fix/refactoring process, you will have to move very slowly - manual testing will take a lot of time. Trying to do too much at once will only slow you down when you find you've broken something and need to back-track. Don't forget to use source-code-control - check in frequently.
Resist the urge to refactor working code until at least the worst known bugs have been fixed.
For more on refactoring, check out http://www.refactoring.com/.
[/docs]
permanent link
What Is My Goal
First Draft: I want to work in a happy team writing software that helps creative people make stuff.
What kind of stuff? art, 3d graphics, movies, games. I'd also like to help ordinary people be more creative as well.
Software developers are creative people too. Hmm.
Second Draft: I want to help people be more creative and productive in making stuff, working in a happy team, producing software that helps people be creative.
I don't have to be writing the software myself, I could be a coach or mentor, or project lead. I've been a successful project lead on a few occasions, and I think I would be a better project lead today. Happy doesn't mean there are no disagreements, but it does mean that people value and respect each other.
An interesting analogy to programmers is honeybees. Orson Scott Card writes about it here: http://www1.things.org:8080/~muffy/pages/life_work.html. Card writes:
"If a software company provides such a hive, the coders will give up sleep, love, health, and clean laundry, while the company keeps the bulk of the money.... All successful software companies had, as their dominant personality, a leader who nurtured programmers. But no company can keep such a leader forever.... The shock is greater for the coder, though. He suddenly finds that alien creatures control his life. Meetings, Schedules, Reports. And now someone demands that he PLAN all his programming and then stick to the plan, never improving, never tweaking, and never, never touching some other team's code."
The goal of the honeybee is to produce honey. The delight of a programmer is to produce code. He/she wants to be appreciated for that skill. Beekeepers may move a hive to be closer to the flowers (making it easier for the bees to make honey), but the beekeeper doesn't tell the bees to fill a quota, backed up with threats of punishment. Make it easier for the programmers to program and the bees to find honey, and then step out of the way.
There are ways to get the programmer honeybees and those alien 'marketing' creatures more cooperative. Plans are OK, as long as they have appropriate levels of detail, and are not used as whips in a master-slave relationship. Reporting can be done in ways that don't impose burdens on the programmers. Let business steer at the non-technical levels and let the technical people do the things they need to do, to produce good software that supports that business.
[/docs]
permanent link
Practices, Links, and Books
Esther Derby reminds us that learning comes from practice and feedback, (not just a training course) and links to one of her articles at StickyMinds.
Aside: StickyMinds is the on-line forum associated with Software Testing and Quality Engineering (STQE) magazine, which published my article on adopting XP last year (July/August 2002, order the back-issue!).
Extreme Programming defines "12" practices, though different ways of counting takes it up to 13 or more. Don Wells lists way more than that at http://www.extremeprogramming.org/rules.html. You should know that "they are just rules" meaning that you won't lose your license to program if you break a rule accidentally or with good reason, though failing to follow all of the practices often makes more work for yourself and your team.
Practicing is becoming a popular topic. Ron Jeffries wrote of "etudes" and Dave Thomas is writing about "katas". Other web-logs have discussed this topic, with analogies to music practices, authors writing drafts of papers or books, and so on.
William C. Wake has posted test-first "challenges" on the XP mailing list in the past, for people to practice on, and now has a book called The Refactoring Workbook due in July. Preview chapters are on-line: http://www.xp123.com/rwb/.
On other topics, Mike Cohn is writing a book on User Stories (Requirements/Features in XP lingo) and set up a web-site on this topic at http://www.userstories.com/. I haven't read the chapters that have been made available yet, but I plan to soon.
And David Anderson recommends a book on the agile management mailing list: What Management Is by Joan Magretta. He's enthusiastic: "This book was nominated by no less an authority than The Economist as
one of the 10 best books of 2002. That's what prompted me to read it.
In summary - it is worth every cent! It's management summed up in a
nutshell."
[/docs]
permanent link
Test Driven site, Blogger Security, Corporate Cultures
Dave Astels points out another TDD resource: http://www.testdriven.com/.
James Robertson points out a security issue with the blogger API: "This is why my posting API uses encryption, and why I don't support the blogger api on this blog - that pathetic excuse for an API passes usernames and passwords in the clear." My blogger friends need to make sure they change their passwords frequently.
Interesting article by Art Kleiner about multiple corporate cultures here: http://www.well.com/user/art/s%2Bb32001.html. He describes three cultures that live within single companies:
The first, the operational culture, is the culture of day-to-day line managers - the people who get products and services out, procure supplies, process bills, and make delivery trucks run on time. Operations people appreciate teams; they understand, as nobody else does, how to get a bunch of disparate individuals to pull together.
If you want to find facility with deals, leverage, and capital flow, you have to look to the second corporate culture, the executive culture. Members of this culture typically include the CEO, the board, the business-unit leaders, and the finance-oriented staff.... their jobs and passions lie in shepherding the cash flow that keeps the organization alive.
The third corporate culture, the engineering culture, is personified by engineers and technical specialists, particularly in information technology and process engineering. They are stimulated by puzzles and problems, and by the design challenge of creating an ideal world of elegant machines that operate in harmony.
He also describes briefly how corporate cultures at the CEO level have changed over time. The most successful companies were "monopolist" until anti-trust laws were passed; "manufacturing" after that -- that is vertically integrated "operations" cultures; "marketing-oriented" after the Great Depression and up to the "golden age of advertising in the 1960's"; and "finance-oriented" oriented after inflation hit in the 1970's.
Now that we are living in what seems to be deflationary times, what CEO-level culture will become successful?
[/docs]
permanent link
A Series on Test Driven Develolpment
Software Development Magazine has been publishing a column "The Craftsman" by Robert Martin. A series of essays in the form of a conversation between apprentice and master, with code snippets in Java. Check it out: http://www.sdmagazine.com/columnists/martin/. Thanks to "Marc Hamann" and "Demyanovich, Craig" for mentioning it on the Test Driven Development Mailing List.
David Astels is holding tutorials on TDD at various conferences. Check out his list here. He also is offering training according to this page.
Robert Martin's Object Mentor does training on TDD, XP, and other topics. Check out the course catalog.
Joshua Keriefsky's Industrial Logic does workshops and "experiences" on TDD, XP, and other topics. Check out their workshop page.
This page lists training and trainers, but some of it is out of date:
http://c2.com/cgi/wiki?XpTrainingClasses.
I can teach (one person at a time) an introduction to test-driven development if the student is willing to spend a an hour or two in front of a computer with me, on a Saturday or Sunday. (C, C++, Java, Objective C.) Send me an email if you're in the SF Bay area ("Silicon Valley" area). If I get lots of responses, I'll have to charge for this tutoring. (Perhaps you can teach me how to use VisualWorks Smalltalk.)
Of course, the books on TDD are presently few:
Test Driven Development By Example by Kent Beck
Agile Software Development: Principles, Patterns, and Practices
by Robert Martin.
Test-driven Development: A Practical Guide by Dave Astels, which should start shipping summer 2003.
It goes without saying that TDD is cool, useful, productive, fun, challenging, rewarding, and the way everyone will be developing software in the future.
Oh. I forgot Ron Jeffries's essays on TDD in C# here: http://www.xprogramming.com/xpmag/index.htm
[/docs]
permanent link
An Example of the Power of Smalltalk
Here's a tidbit from James Robertson's http://www.cincomsmalltalk.com/blog/blogView.
James is using a binary file format to support his blog code (which is written in VisualWorks Smalltalk, natch.) Apparently the "class library" he is using is called BOSS, comes with VisualWorks, and it supports schema migration.
In the code snippets here, he has two very powerful lines:
oldObj become: newObj.
oldObj changeClassToThatOf: inst.
If I'm reading this right, this is transforming the old object (of an old class type) into a new object (of a new class type). All references to the old object will now be referring to the new object. (This is a big deal!)
Java can't do this (and perhaps shouldn't, since it could be a security risk when running code received over the internet in one's browser - if anyone does that anymore). C++ can't even get close. The closest that Objective-C comes is to have a class "pose as" another class.
From what I've read, the message "become:" is not used much in everyday Smalltalk programming, but it required by the Smalltalk IDE for letting users modify existing classes -- classes are objects too, so you want to make the existing class object "become" the modified (new) class object.
James points out that his blog's files are stored via BOSS are in a variety of old formats, since he's added categories, trackbacks, and so one over the last year or so. He doesn't have to read those files and save them in the current format; he just lets their data get converted at run-time when (and if) they need to loaded into memory.
[/docs]
permanent link
Agile Project Management Paper and Statistics
Get a free copy of a Cutter Consortium report: "Agile Project
Management: Principles and Tools", by Jim Highsmith, at http://www.cutter.com/offers/APM.html. Forty pages, well worth reading (and a "$150 value!").
A few quotes from that report:
On agility: "We are no longer talking about 15%-20% scope creep on projects; we are talking about everything - scope, features, technology, architecture - changing within the span of six months.... The traditional project management maxim of 'conforming to plan' fails dramatically in these situations."
On traditional project management, he quotes someone in the construction industry saying "The ... PMBOK... is based on two underlying theories: management-as-planning, ... and the thermostat model... both theories can be shown to be heroically simplistic and insufficient from the point of view of project management reality."
Highsmith describes the "agile project management model" with a graphic that I'm trying to reproduce in text form here:
1. Envision
2. Speculate (create Feature List and Feature Plan)
3. Iteratively Deliver Features (from Feature Plan, create Tested Features)
4. Monitor and Adapt (from Tested Features, create Final Product, Adaptations jump back to Speculate)
5. Close
Traditional project management focuses on activities, while agile project management focuses on delivery. Highsmith writes "Teams that focus on activities get lost, and even worse, they often don't realize it. Earned value analysis ... has nothing to do with value but with cost accounting based on planned tasks versus actual tasks. The value of what those tasks actually deliver gets lost."
Cutter also has a survey paper here that I summarize below:
Survey of 200 IS/IT managers
Location
33% North America
20% Europe
10% Australia
8% India
8% Asia
Industry
39% software companies
11% financial services
9% consulting or like services
6% state or national governments
5% telecommunications
Heavy Methods in use...
51% RUP
27% CMM-compliant (!?)
26% ISO-9000 compliant (!?)
Agile Methods in use...
54% in-house developed agile method
38% Extreme Programming
23% Feature-Driven Development
22% Adaptive Software Development
19% Dynamic Systems Development
9% other
8% Crystal Clear
7% Lean Development
3% Scrum
This article predicts that 50% of companies will have some agile projects "by 2003".
The bit about CMM and ISO-9000 as heavy-weight methods is a bit confusing, since compliance with those standards doesn't necessarily require forgoing an agile process.
[/docs]
permanent link
Dinosaur Brains versus Survival Rules
Way back in 1989, there was a book I read called Dinosaur Brains by Bernstein and Rozen. I thought it was a good read at that time. Their thesis is that irrational behavior, including territoriality, fear, flight, and aggression, are remnants of our reptilian ancestry, and the book gives advice on appeasing and working around these behaviors. By the way, the book is still in print, in paperback.
The problem with this idea is that reptile behaviors are hard-wired... they can't be changed. A better idea is "survival rules" that we learn as children (or later) and apply in sometimes inappropriate situations. When we identify our survival rules, we can modify them.
Wayne Strider's book Powerful Project Leadership talks about survival rules, as does Jerry Weinberg in Becoming a Technical Leader: An Organic Problem-Solving Approach and More Secrets of Consulting: The Consultant's Tool Kit.
An example I read about on a mailing list recently was pair programming. Someone (I think it was Robert Martin, but it could have been Joshua Kerievsky, or someone else), described a programmer that had some difficulty adapting to pair programming.
To make her comfortable with it, she would study the task/problem for some time by herself before pairing. The writer observed that she wasn't comfortable with being asked questions that she didn't know the answer to. Eventually, she got comfortable with pair programming, and no longer needed to study before pairing. It seems to me that her survival rule was something like "I can't show anyone that I don't know the answers" and she successfully modified the rule.
[/docs]
permanent link
Waste Not
The Standish group, in their Chaos Report, reports that 85% of the features implemented in the average IT project are NOT not used by the customer.
If you knew which features the customers were really going to use, You could avoid wasting 85% of your budget, and you could ship 85% earlier than the average software project, getting revenue sooner. Sounds like a win-win for both customer and supplier.
This applies to shrink-wrap software as well as in-house projects. id software (if I recall correctly) released limited-features (free) early versions of their breakthrough game Doom to get feedback from their users and get them addicted to their software.
How do you find out which features the customer really need? Ask them. Get them involved in the product with early releases. If possible, get a representative customer involved in the planning and feature definition.
Eliminating waste (like that unnecessary 85%) is one part of Lean Manufacturing. Like myself, Kent Beck did not view "manufacturing" as an appropriate metaphor for software development until he started reading about Taiichi Ohno's Toyota Production Method. Here's a small write-up: by R.Balakrishnan.
Lean Manufacturing, like XP, often encounters what seems to be irrational rejection (even after demonstrating success). On the XP mailing list Kent Beck writes:
I'm reading Lean Transformation, which is full of stories of
dramatic improvements in manufacturing quality and productivity that
are immediately dismantled as soon as the consultants leave the
building, even at the eventual cost of the jobs of the people doing
the dismantling. Which is to say, you are not alone.
Harvard Business Review has an article this month about Bill
Bratton, who has turned around 5 police organizations, including the
whole of NYPD. You should read the article, but the sequence I took
away was:
Put the managers in direct contact with the problem
Focus you resources on the single worst problem
Enlist powerful allies
Marginalize or eliminate naysayers
Beck also points to a paper [a zip file containing a pdf] on adopting Lean Manufacturing which is titled "First, Do No Harm!" by Michel Baudin. The paper recommends converting to Lean with pilot projects that show rapid improvement and pay for themselves. At no time should converting to Lean cause a drop in revenue or delays in delivering product. Baudin also points out that you can't convert to Lean instantly, because it requires learning new skills. Not unlike the new skills needed for XP.
[/docs]
permanent link
Happy Mother's Day, Mom!
My mother is a very organized person, or at least, that's how I perceived her to be during my childhood. When we went on camping trips, we had everything we needed, and we knew we had everything because she made checklists. I think she prepared the lists long before the trip, was able to check off items as they got packed into the car, and kept the list to reference and update during the trip. (They may have even been laminated.) If anything was found to be needed or desired during the trip, I'm sure Mom added it to the list, so it would be packed on the next camping trip. I can't imagine the settlers in their Conestoga wagons being more organized.. or packing more stuff in a relatively small area. Mom not only had checklists, but she had customized trunks for food, cooking-gear, and other specialized containers for other stuff.
This organizational skill might reflect a preference to "J" in the Myers Briggs Type Indicator. I come up as a "J" in the MBTI as well, but not a strong "J". When my wife and I go on camping trips, our checklist, if we have one at all, is written at the last minute, and lost once we're on our way. We haven't forgotten the can opener, but on one occasion we forgot sleepwear. We can add items to our next camping-trip checklist only if we remember what we forgot last time. We are in fact, sometimes relying on checklists in a camping book, because the book doesn't get lost as easily as a scrap of paper does. To pack our stuff, we have to rely on commercial containers, or let stuff just pile up in the back of the station wagon. We do have, thanks to Mom, a very nice, portable, container filled with paper plates, paper napkins, salt and pepper, plastic cups and utensils -- picnic supplies, because she heard our need and responded. Thanks, Mom.
Now why do I and my wife (both J's according to MBTI) have so little organizing skills for our vacations? My wife says she works hard at organizing at the office, and prefers to be lazier at home. (Don't tell her I just published that.) Maybe it is because in my childhood, I was not part of that organizing - I didn't help develop the check-lists or build the specialized containers. Maybe its because I didn't take classes on office management, like my mother did in college. Or maybe we're really Myers Briggs type "P" and have been trained to act like "J"s.
David Smaltz in his book "The Blind Men and The Elephant" makes a point of saying that a team can produce a plan or an organization that seems self-evident to them, but which would not be understood by another team without explanation. In my workplace, I know of a lot of people who would like to know more about the manager's plans for projects, particularly to be able to cooperate better with other teams. One employee told me his manager only provided information on a "need to know" basis, which made working for that manager more difficult than it had to be. Quite often I don't know that a project at my company has chosen to use one of the components I'm responsible for, until I get bug-reports at the end of the project. I'd really like to know before they write the contract with the customer, so I can make sure that we have time and resources to support whatever changes they are planning, and at least get them to pick the right version of the component.
For more on Myers Briggs, see Naomi Karten's book on Communication Gaps.
Also check out Gerald Weinberg on MBTI and other preferences in his Quality Software Management series, particularly volumes 3 and 4: Quality Software Management: Congruent Action (vol. 3), Quality Software Management: Anticipating Change (vol. 4).
[/docs]
permanent link
Feedback, the Secret of Agile Development
Tomorrow... a special blog entry for Mom.
A paper of mine, about feedback in Agile / XP projects, has been published on the AYE Conference website: http://www.ayeconference.com/Articles/Secretofagile.html. That paper concentrated on testing and customer involvement, but there is more feedback possible: there is feedback from members of the developer team, management, QA, and other stake-holders associated with the project.
The Standish group, in their Chaos Report, reports that the top three project success factors, in order of most important to less important are:
User Involvement
Executive Management Support
Clear Statement of Requirements
Other success factors that also support my point are:
Realistic Expectations
Smaller Project Milestones
Competent Staff
Ownership
Clear Vision and Objectives
In typical waterfall projects, user involvement is only at the first and last stages: requirements gathering and final testing (and sometimes users are not involved even in those two stages!). This obviously isn't enough, since IT projects, according to the Standish group, are only successful an average of 12% of the time.
Agile methods aim for success by requiring more user involvement through the life of the project: the practices of On-Site Customer and Frequent Releases, among others. User involvement also helps with maintaining realistic expectations and getting those requirements clearly understood.
Even with user involvement, there are project failures from lack of management support. Most of the stories of unsuccessful projects I've heard at BayXP are due to lack of executive management support - failure to get buy-in from the rest of the company. In some cases, the project was on-time and on-budget, but the rest of the company rejected the process and/or the people involved.
Successfully adopting XP requires a company culture compatible with its values, and many companies just don't have that culture. To get to XP, the company would need a culture change, which requires skilled, dedicated, change artists and a company-wide perceived need for change. Thus, Industrial XP does a Readiness Assessment to see if there is a culture fit.
Agile methods have smaller project milestones, a proven success factor, as well as frequent releases. Getting the product out in front of real users not only enables more feedback, but can be financially rewarding as well, by reducing time-to-market or opening a new market. For internal projects, "small releases" to some portion of the end-users is a proof of concept, demonstrating to management the viability of the project.
Competent staff is a sticky point. No method can work well if the people don't know how to do it or don't understand it. Many XP project failures result from staff that had no training on the practices and didn't practice all of the recommended practices. I've already written that XP's test-driven-development requires testing skills and refactoring skills that both inexperienced and experienced programmers may be lacking. Training and practice, whether by intensive, disciplined, self-training, or training from good teachers, is necessary for those new to XP.
Lack of competence in test-driven-development shows up in unexpectedly-failing acceptance tests, bugs slipping through to users, and decreasing velocity (features done per iteration). Developers puzzling over the bug-reports, unhappy users and managers, and increasingly-unmaintainable code probably realize that something is going wrong, but without a coach or someone experienced in software development, may not know how to fix it. In the worst cases, they ignore this feedback and deny that anything is going wrong.
Industrial XP's additional practices - Project Chartering, Project Community, Test-Driven Management, and so on - address the factors of ownership and clear vision. If the project starts to drift off course, members of the project community can point to the Charter and Manager-Tests and ask "why are we moving in this direction?" IXP's practice of doing Retrospectives regularly (mini-retrospective each iteration, as well as larger ones at longer intervals) will also help with clear vision of the objectives and ownership of the process, providing feedback to the participating members of the project community.
The hardest kind of feedback to specify in a "process" is personal feedback from people in the team, whether in pair programming, retrospectives, or otherwise.
Naomi Karten's book on Communication Gaps can help.
Many people I respect recommend What Did You Say?: The Art of Giving and Receiving Feedback by Charles N. Seashore, Edith Whitfield Seashore and Gerald M. Weinberg.
Norman L. Kerth wrote the definitive book on Project Retrospectives, but you shouldn't try to do a large retrospective without a skilled facilitator. Read the book to see why.
The larger community is also a valuable source of feedback and learning. Go to your local Agile or XP group meetings, join or at least read the XP, IXP, and/or TDD mailing lists. Read the books. Read the web. Go to conferences if you can.
[/docs]
permanent link
Open, Collaborative, Project Planning
Mary Poppendieck on the Lean Development mailing list writes:
The difference between a planned and a market economy is rooted in two different management philosophies:
Management-as-planning/adhering focuses on creating a plan that becomes a blueprint for action, then managing implementation by measuring adherence to the plan.
Management-as-organizing/learning focuses on organizing work so that intelligent agents know what to do by looking at the work itself, and improve upon their implementation through a learning process.
and links to Laurie Koskela and Greg Howell's article at: http://www.cpgec.ufrgs.br/norie/iglc10/papers/47-Koskela&Howell.pdf.
I've recently read two books on project management:
David A. Schmaltz's book The Blind Men and the Elephant: Mastering Project Work
Eliyahu M. Goldratt's book The Goal: a Process of Ongoing Improvement (a business novel written with Jeff Cox).
David Schmaltz makes a point in his book that a plan or organization done by one person or group will not be self-evident to another person or group. With that in mind, The Goal was somewhat frustrating, because the main character, who is changing the way his factory works, isn't involving the people on the factory floor in designing his process changes (he is involving other managers). In fact, of the few factory-floor union workers depicted in the novel, all but one of them are depicted as stupidly getting in the way of the process changes. I suppose one man against the world makes for some drama in a novel, but doesn't work that well in real life.
Goldratt writes in the after-word of The Goal that major obstacles of process improvement discovered by his readers were:
Lack of ability to propagate the message throughout the company.
Lack of ability to translate what they learned from the book into workable procedures for their plant
Lack of ability to persuade decision makers to allow the change of some of the measurements
which certainly shows that involving others is necessary for plans to work.
I also found The Goal frustrating because he made no mention of Deming, whose collaborative techniques for process improvement were proven "long ago" in Japan, and predated Goldratt's techniques.
[/docs]
permanent link
Regressions
What's the difference in a bug in a new feature, and a bug that suddenly appears in an old feature? In a new feature, one is getting added value imperfectly. In an old feature, one that used to work bug-free, but is now broken, someone on your team is subtracting value.
For a very long time, experts like Jerry Weinberg have been recommending careful code reviews of maintenance changes, because a bug in a deployed system (like payroll or billing) can result in multiple millions of dollars in losses.
Someone inserting defects into working code is creating waste: not just the risk of printing bad checks or bills, but creating work for themselves and others to identify and fix the problem they created.
The danger in maintenance or incremental development is that an innocuous change breaks an existing feature. Extreme Programming deals with this danger in three ways: pair programming (continuous code review), extensive automated unit tests, and automated acceptance tests. Plus, most if not all XP teams have manual testing as well.
Many teams doing test-driven-development (a core practice of XP) report that their unit-test code coverage is nearly 100% statement/branch coverage without taking extra effort. This gives them the freedom to make an innocuous change (as part of a refactoring, for example), and see within minutes if it breaks anything. If it does, they can Undo their change, or evaluate the change more carefully.
[/docs]
permanent link
Appreciative Inquiry
Brad Appleton, on the XP mailing list, recommends "appreciative inquiry" http://www.appreciative-inquiry.org/ and http://www.thinbook.com/chap11fromle.html. This technique lets people feel they and their ideas are appreciated, and focus on what's right rather than on what's wrong.
On Hal Macomber's blog Reforming Project Management, he wrote on Tuesday, April 29, 2003:
My favorite management author is Ken Blanchard author of The One Minute Manager and dozens of other books. [...] Blanchard implores people to focus on positive feedback. In his book Whale Done! he goes into how trainers never use negative feedback when working with dangerous animals. If killer whales can be trained to do the spectacular things that they do with only positive feedback, then why would we want to use negative feedback with the even more dangerous human beings?
Apparently, "Whale Done!" is also on video, dvd, etc... http://www.rctm.com/app/Product/71727.html
[/docs]
permanent link
Extreme Planning - the Home Game
Extreme Programming has planning at several levels.
Release Planning, where the entire project is divided into small user-centered features (stories), written onto index cards, estimated by the developers, and prioritized by the story-writer. The story-writer tentatively assigns the stories to iterations (tentative, because the amount of work that can be done per iteration is only a guess when they do their first release plan), with an end-user release planned in three months or so, when enough features will have been implemented to make a release worth-while.
Iteration Planning, where a set of stories is selected by the story-writer (just enough to fit into one iteration as measured by the previous iteration). The developers flesh out the stories with the story-writer and (in some teams) break down the stories into tasks, writing the tasks onto index cards. Many teams put the cards and tasks are put on the wall.
When two developers get together to pair program, they may break down the task (or story) that they are working on into list of tests to do, and a design in UML or whatever notation they think best. This may be written on index cards or a white board. Then they implement one test at a time in test-driven-development.
I asked on the IXP mailing list if people had used the Extreme Programming's Planning techniques (sometimes called the Planning Game) for organizing home chores or other non-work things. Yes they have.
Jiva DeVoe planned a cross-country move on index cards, including estimates, posting them on the wall, etc.
Joshua Kerievsky tells us that Francesco Cirillo, who does XP training in Italy, uses XP-style planning to organize and execute a weekly dinner, with student volunteers doing most or all of the cooking.
Amy Schwab planned a wedding using her techniques of "project community" and "adaptive project methodology". She wasn't familiar with XP planning, but she also used "cards on the wall" (post-it notes instead of index cards). She let go of traditional project "control-oriented" planning, and let family and friends be in charge of "their own quality of experience."
Diana Larsen tells us that http://www.shesintouch.com/ does home chore planning similar to XP's planning, including using index cards, estimates, and measured velocity (and training workshops) [and this predates XP by 20 years].
It seems to work for lots of people, so I will give it a try with my wife. Guess who's be the "customer" in this planning session? Not me!
[/docs]
permanent link
Experience-based list of traps for those new to XP
Alex Chaffee has started a wiki page http://c2.com/cgi/wiki?XpPitfalls, making a list of pitfalls often encountered by teams new to XP. Erik Hanson made "major additions".
For example: "Problem: Refactoring is hard. Really hard. Solution: Practice, practice, practice."
This item is probably meant more for entertainment: "Problem: OAOO can lead to a nest of small objects. Writing new code or debugging you end up getting lost in a Smalltalky maze of pointers. Solution: Stop the madness. Trust your design instincts. Solution: Don't hire former Smalltalk programmers :-) "
Wyatt Sutherland reports a XP+Scrum success story for Blue Cross Blue Shield of Tennessee, on the XP Mailing List. A software project that supports BCBSoT's customer base of millions, managed via index cards and agile techniques.
[/docs]
permanent link
News Skills for Developers
Extreme Programming requires new skills for both Managers and Developers; in today's entry, I write about some of the new skills required for Developers.
In typical "traditional" development (which is often waterfall / code-n-fix), a developer needs the skill to design from scratch. To some extant, this skill is taught in school and in books. Some developers master it better than others. Unfortunately, it doesn't help too much with maintenance, and about 90% of developer work is maintenance. Debugging is a very valuable skill for this kind of work, but only learned from experience. Testing is done after development, if it is done at all, (typically just manual testing is done) and very few projects keep automated tests running in maintenance mode.
| Traditional Development |
State of Code |
|
|
|
|
| Design from scratch |
Good |
|
| "Patch" for new feature |
Less Good |
|
| "Patch" for bug fix |
Even Less Good |
|
| Repeat Patching for years |
Eventually Declared Unmaintainable |
In Extreme Programming, a developer doesn't have to make a good design from scratch. During the Test-Code-Refactor cycle, the developer's first stab at code doesn't have to have a really good design, it just has to pass the test. Then the developer "puts on his refactoring hat", and improves the code to good design. The project is in maintenance mode after the first week, and the discipline of refactoring keeps the design good throughout its life. Keeping the tests up-to-date is also required. It also turns out that pair programming and this test-first approach mostly removes the need for debugging.
| Extreme Programming |
State of Code |
|
|
| Write a Test |
No Code Yet |
| Code To Pass Test |
Minimal Code, Possibly Poor Design |
| Refactoring |
Good Design |
| Write another Test |
No Changes to Code Yet |
| Code To Pass Test |
"Patched" Code, Possibly Poor Design |
| Refactoring |
Good Design |
If you compare the two methods, you see that XP requires testing skills, which are not emphasized in traditional methods, and it requires refactoring skills, which isn't (or wasn't until recently) taught in school, and is only described in very few, recently-published books.
Experienced developers, particularly those who have spent time in maintenance, know that patching leads to unmaintainable code, but many of them haven't learned refactoring, the "cure" for patching. Younger developers, particularly those that got started in the dot-com boom, haven't even had time in maintenance, and of course they are still learning how to do design from scratch.
I've spent the last several days teaching a developer how to write code test-first. Writing the test for a nonexistent class or method is fairly easy, and writing the code to pass that test is fairly easy. It can even have a good design, since it isn't being patched (yet).
Writing a test to drive modifying the behavior of an existing class can be more tricky. In some cases (equality functions), we had to regard a "passing" test as a failure, in order to follow the XP rule of never modifying the code unless there is a failing test.
One of my exercises for teaching is to have the student write a "prime factors" function, where I supply each test, and the student writes the simplest code to pass the test. The hard part in that lesson is learning to refactor "if" statements away to keep the design good. Remember the XP rule for good design: "no duplicate logic".
Sometimes, at the end of the day, getting the tests passing is such hard work, that we get tired and don't do the refactoring. We check in working code, and then the next day arrives and we forget to do the refactoring, moving onto new tasks instead. Pair programming is tiring enough that the experts don't recommend pairing more than six hours a day. The XP practice of "sustainable pace" is meant to keep you from programming while tired, when your judgment is poor.
An XP team might want to have a practice where developers coming in the next morning review the code that was checked in the previous day, looking for opportunities for refactoring, and doing it first thing, while the energy is available to do it. The next-day perspective could help provide the distance needed to recognize that yesterday's wonderful code isn't as wonderful as we thought.
Refactoring is similar to rewriting, but more disciplined: you can only make small, behavior-preserving changes. This discipline is a new skill.
Brooks said "expect to throw one away", Clarifying later that he meant small modules not entire systems, because throwing away entire systems leads to waterfall.
Cockburn said says it is easier to modify a working system than to write a new system from scratch. I say that it is easier to modify a working system than a non-working system.
Ed Yourdon said that any piece of code needs to be rewritten three or four times to be constituted as an elegant, professional piece of work.
Mary and Tom Poppendieck said that for prose, we take this [rewriting] for granted, why not for code?
[/docs]
permanent link
Rewards, Teamwork, and Ropes Courses
Esther Derby, on her blog, mentions a few reward-structures that work against teamwork. She writes:
Many companies throw up organizational barriers to collaboration:
reward structures that focus on individual achievement
recognition of individuals for group efforts
disbanding groups that do work well together (the "seeding" principle)
promotion of individual stars
And most "team building" misses the mark. Ropes courses, pep talks, and inspirational posters are a crock.
Once upon a time, I and my coworkers were sent to a Ropes Course once. One thing being emphasized was the fact that old people, when asked what they would have done more of, never said they'd spend more time at the office. (Those who sent us on this course probably didn't know about this lesson ahead of time. Or maybe they did.) We also learned about providing "back up" to each other (support), not using joking put-downs on each other, and were given some time to think about our individual priorities.
Many of the employees were energized and tried to improve things at the office when they came back from the Ropes Course, but became frustrated and bitter because while many of the employees who came back did change (more teamwork and respect among coworkers), but the managers who came back from the course didn't change -- they continued a long history of backstabbing and turf-building.
Some employees quit to get better jobs and spend more time with their families. The company's president, who wanted this course to help turn the company into a focused team, did not achieve her goal: the managers under her did not change their behavior, even though the employees did change, for a short while, until they realized that the managers were not providing "back up" to their workers. They probably could have used Retrospectives, Charters, and all sorts of good things, but as long as the managers were rewarded for back-stabbing and turf-building, the situation would not have improved.
One of my priorities was/is "fun". (The IXP value of "Enjoyment".) The IXP mailing list has been discussing this, including other names like "Satisfaction". The most fun I have had in work comes from working in teams of respectful coworkers, with collaborative design (and since I've discovered XP, pair programming).
Pairing can be tiring, and with the some people it can be VERY tiring, but the fun comes from getting work done quickly, with someone to provide "back up" (catching my mistakes), and with me providing "back up" to the pair when he's keyboarding. Getting code to pass the latest test (or sometimes, getting the test to fail) is a shared triumph, repeated many times during the day. Getting our changes checked into source code control several times a day is also a shared triumph, particularly when you can announce that this check marks the completion of a story/feature.
Even formal code reviews can be a little bit fun, if the people in the review respect each other, and have a sense of humor about the mistakes we can all make.
Check out more about Pair Programming at http://www.pairprogramming.com
[/docs]
permanent link
Reward Structures
Is your company's reward structure counter-productive?
A recent issue of Inc. magazine had a article where a sales manager said, based on his experiences, that he'll never recommend using commissions to reward salesmen, because it damages the company that does it; specifically it works against team-work and causes the company owners to not trust their salesmen. Check it out: http://www.inc.com/magazine/20030501/25416.html.
Some managers complain that pair-programming prevents them from seeing clearly which programmers are accomplishing more than others, to be able to reward their individual accomplishments. Emphasizing individuals over teams rewards territoriality, rewards competition more than cooperation. Cooperation is more productive than competition at getting products developed and shipped. Do you really want to discourage cooperation?
When programmers are working solo, how do you know they are actually doing something useful? Could it be that someone is working alone because what he's doing is NOT useful to anyone else?
Software is a team effort. Even when its done by a bunch of soloists, they are still using each other's work by building on each other's libraries and code. Could it be that the guy who demos a flashy application has only done some of the GUI, and the functional parts of the application were done by his coworkers? Are you going to reward the flashy demo guy because he can show you something more visible than the other programmers who wrote the functionality?
Robert Martin wrote on the IXP mailing list:
In one case we transitioned a team that had technology project leads. There was a lead for the database, a lead for the middleware, and a lead for the UI. (I'm not kidding!) When we transitioned them to XP these folks rapidly realized that the practices of pairing and collective ownership were diluting their power base. Two of them made abortive attempts to seize power back, and wound either resigning or being fired. The team was much happier once they were gone.
Are you rewarding last-minute, late-night heroics? When you do XP well, you have measured progress every iteration, and you can predict how much scope can be accomplished a long time before the end of the project. Check out what happens when rewarding heroism meets XP...
In another case we had a cowboy. This fellow used to rescue the project at
the eleventh hour by pulling all nighters. His manager learned to depend
upon this behavior and just "knew" that the cowboy would save him at the
last minute. As we transitioned to XP the cowboy actively sabotaged the
planning meetings and the iterations. He did not want the team to make
progress. We went through three iterations of *zero* velocity. (Count
them, zero.) And then the manager dissolved the team and reformed it months
later in a different way. (I'll leave it to you to predict how it was
restructured.) -- Robert Martin.
Do you think that even before XP came along, that this cowboy might have been doing some sabotage to make sure his heroism would always come into play? I think XP just made it more visible.
Ken Auer, who runs a RoleModel Software, a consulting company that does XP, writes:
I've always had a reward structure here that was based on the concept
"share the risk share the reward" while still acknowledging that
"socialism doesn't work... Some people do provide more value than
others". At first, I could only come up with a "how much money did we
make due to your billable hours" measures, with a few other criteria to
make sure it wasn't abused. Worked fine while everyone was billable
most of the time. When it wasn't, it had people lobbying for billable
time against each other e.g. "I think I should be on this project
(instead of Joe) because...".
Finally, I came up with a formula for individual value to the company
that could be identified, peer-reviewed, and steps taken to move the
number up. That number was used to figure out shares in the pool of
money. It wasn't perfect, but it completely got rid of all of the bad
behavior (fighting against each other) and produced good behavior, i.e.
I got help figuring out how to divvy up resources for the best of our
company, the client, and the individuals.
Amy Shwab reminds us: In the January Harvard Business Review (all about motivation) there was a wonderful piece about the longer term effects of performance metrics and tying results to those metrics. The company, indeed, got what they were rewarding but it did not translate into what they
wanted or needed. It fragmented the organization and served the
customers very poorly. The most important things are often the most
difficult to measure -- like 'fun'.
Developing intellectual property like software is always a learning experience. External rewards can hinder learning. Kohn said "Rewards are most damaging to interest when the task is already intrinsically motivating." Check out "Punished by Rewards? A conversation with Alfie Kohn".
Rachel Davies and John Nolan will hold a workshop on this topic at the Agile Development Conference
.
Thanks go the people mentioned above, and Brad Appleton and Steve Berczuk on the XP mailing list.
[/docs]
permanent link
Diana Larsen on Changing Your Organization
Diana Larsen's article on change and learning (and XP) http://www.cutter.com/itjournal/change.html 12 pages (PDF).
She quotes Beckhard's formula for change (my paraphrasing): If dissatisfaction with status quo, plus desirability of change, plus clear definition of what/how to do, are greater than the resistance to change, then you can achieve the desired change.
She says to encourage change, market it by increasing awareness of the problems with the status quo (I see a risk of being called names like "negative" or "not a team player") and the communicating the desirability of getting to a better situation. "When you are implementing change, there is no such thing as too much communication."
Some of this runs counter to Jerry Weinberg and another (name forgotten) book. Jerry says "don't promise more than a 10% improvement." A manager doesn't want to admit that more improvement is possible, because then they would have to admit that they were not doing a "good job" before. The (name forgotten) book pointed out that too clear a picture of the future can be paralyzing because people can see the perceived drawbacks of that situation too visibly, while not appreciating the benefits.
She writes "XP has the advantage over many change efforts in that fast iterations build in the feedback loop for short-term success. While floundering through the chaos, nothing bolsters the participants in a change effort like the sense of progress from a quick 'win.'"
Larsen recommends Chartering to start a project, and agrees with Lindstrom and Beck on "Hold two-day professionally facilitated retrospectives each quarter." (And at project end.)
Change takes time. "Putnam points out the need for patience with change efforts as he maps out six months' worth of defect tracking and shows its consistency with Satir's [change] model. He notes that if you had an evaluation of success or failure after three months, you might have come to an erroneous conclusion."
Also check out Rick Brenner's "Fifteen Tips for Change Leaders" here: http://www.chacocanyon.com/essays/tipsforchange.shtml
[/docs]
permanent link
Relationships, Traditional vs Lean Training
Very funny web-page: "Things my girlfriend and I have argued about" http://homepage.ntlworld.com/mil.millington/things.html. This is one bit my wife and I found funny: "Just for reference; if Margret returns from having her hair cut and says, 'What do you think?' and you reply, 'I'd love you whatever your hair was like,' well, that's very much The Wrong Answer, OK?"
Rus Rufer, on the IXP mailing list, mentioned two lists comparing traditional and lean project manager training that were in a draft of Lean Software Development, but which did not make it to the final version:
Traditional Project Manager Training
Software Development Life Cycle (SDLC)
PMI Knowledge Areas
Schedule and Cost Estimating
Critical Path Analysis, PERT/Gantt Charts
Using Project Management Software
Project Scope and Change Control
Project Tracking and Schedule Control
Testing and Quality Assurance
Deployment and Support
Risk Management
Resource Management
Contract/Vendor Management
Lean Project Manager Training
Seeing Waste
Value Stream Mapping
Feedback
Iterations
Synchronization
Emergence
Options Thinking
Last Responsible Moment
Set-Based Development
Pull Systems
Queuing Theory
Cost of Delay
Self Determination
Motivation
Leadership
Expertise
Perceived Integrity
Conceptual Integrity
Testing
Refactoring
Contracts
On the XP mailing list, there has been some unhappiness at the name "Industrial XP", fearing that it will divide the XP community, and perhaps weaken attempts to "sell" XP into companies.
The IXP web page says "Industrial XP is tuned to handle the needs of large scale, mission critical and enterprise applications" which could be taken to imply that "Classic" XP (I might get some hate-mail for that name, which I didn't make up) hasn't had success in mission critical and enterprise applications (which would be wrong). I think the emphasis I heard at the BayXP presentation, that IXP is turned for "highly political organizations" is actually the correct differentiator between IXP and "Classic" XP, but that doesn't make the best advertising copy.
Ron Jeffries would like the IXP web page to say something like this:
IXP is Extreme Programming.
Extreme Programming, like any good software development method, is always
adapted to the context. As a project gets more connections into the
enterprise, it needs different practices, and for best results, these need
to be consistent both with the enterprise needs and the principles and
values of Extreme Programming.
XP and Agile software leaders, including Industrial Logic, have been
applying Extreme Programming to larger scale, mission-critical,
distributed, and highly-coordinated projects for some time now. We offer
here a summary of the approaches and practices that we have used, and
that our colleagues have used, in adapting XP to larger-scale situations.
And, Mark Simmonds wants us to know that DSDM 4.2 (not yet released), which blends DSDM and XP, is not the same as EnterpriseXP, which is supposed to be a web-portal to discuss ways to make XP more commercially appealing. Mark also says "One other point I'd like to clarify is that when using DSDM and XP
together we do not advocate getting rid of the planning game, far
from it. In fact I was delighted to see how closely the Planning Game
matched the Timebox planning process I have used in DSDM projects for
a number of years."
[/docs]
permanent link
Quotes and Evolutionary Design Practices of Industrial XP
David Schmaltz said on the IXP mailing list: "Change never rests on the permission of the willing, but in the hearts of the brave and foolhardy." Let's hope we have supporting practices to not be too foolhardy. On the XP mailing list, Joshua wrote: "...most people react to change as if they are losing something.
It's wired in to our human nature. I introduce XP into environments all the time. People think they're gonna lose something rather than gaining something with XP. I help them learn that they will be gaining a great deal."
On the IXP mailing list, Russ Rufer has provided the list of practices of IXP's Evolutionary Design:
Rapid Return on Investment
Risk Reduction
Backtracking
Selective Automation
Team Intelligence
Walkthrough
Spanning System
Small Iterations
Multiplicity & Selection
Dead Reckoning
I snipped quotations from this report http://www.sdmagazine.com/documents/s=7928/sdmsdw3d/sdmsdw3d.html, onto the IXP mailinsg list, and no one contradicted me, so here are some stabs at defining what some of the practices may be:
Rapid Return on Investment - Developing only what needs to be done at the moment, leaving the rest to be filled in later, allowing early releases that can prove themselves quickly.
Risk Reduction - Striving for design simplicity is a factor for reducing risk.
Backtracking - Stepping back to find a simpler solution to a problem. "Backtracking not only helps you to consider other alternatives, it allows you to rewrite, aggressively refactor and prune any dead code."
Selective Automation - "Quantity bows to quality: It's not about writing tests; it's about writing good tests"
Team Intelligence - "Developers should devote maximum attention to improving the code."
Walkthrough - "Studying, living and breathing code is at the heart of evolutionary design"
Spanning System - "Evolving the code from a rudimentary system that, though primitive, provides end-to-end functionality. This simple working application is a thin, vertical slice of the project that offers insight into both essential and unnecessary features. Illustrated with a simple blackjack problem. To span the system, they chose just one case with two known hands and incrementally built the system to accommodate the full deck. "
Small Iterations - "To implement a hotel reservation system, you might first implement a program that reserves just one room before developing the whole system. These small iterations can be viewed as embryonic versions of the system, and can be taken to the customer for feedback...this is the antithesis of RADinstead of throwing your code away, you evolve it."
Multiplicity & Selection - "Consider a multiplicity of design and selection, like the photographer who takes 10 rolls of film to find the perfect shot. Survival of the fittest."
Dead Reckoning - "Navigating without explicit instructions, by heading in roughly the right direction, and using feedback to make adjustments and to motivate backtracking."
[/docs]
permanent link
Project Currencies
On the Agile Modeling mailing list, Ken Hilving wrote in response to a thread on software Architects being labeled as "Ivory Tower" dwellers:
Time, money, knowledge, security, and prestige appears to be the five
currencies we all deal in. Understanding this explains why others take an
"ivory tower" position when an architect is brought into a project. The
architect offers little time or money to the others, has new knowledge that
they lack, and threatens their security. They maintain a little prestige
within their group by taking the negative attitude.
The trick is using these currencies to provide value to them. Time and
money may be outside your control, so deal with the other three. That
additional knowledge needs to be freely shared. If the others on the team
have a chance to bring their own knowledge into the sharing process, they
gain security and prestige at the same time. I believe that the prestige
aspect, the opportunity for recognition of their contribution, becomes the
most critical factor towards changing the ivory tower label. When it works,
the approach becomes theirs instead of yours and they defend it against any
challenge.
Maybe this is the key aspect of leadership.
[/docs]
permanent link
What is Industrial Extreme Programmging?
At the BayXP meeting last night, Joshua Kerievsky, Russ Rufer, Somik Raha, and Tracy Bialik of Industrial Logic gave a presentation on their version of XP that they have developed over the last several years. They named it "Industrial Extreme Programming" (IXP). What follows here are taken from my notes. Any errors are my own.
IXP is what Industrial Logic has been doing the past few years as they work with their clients in training and coaching XP projects. Joshua said he was concerned with recent "blendings" of XP and other methods (DSDM, FDD, Scrum, Crystal) because some of those blendings were throwing away XP's planning practices (one of the most valuable aspects of XP). Many of these blendings were for the most part untried and unproven, as well, though the unblended methods have records of success.
IXP doesn't remove any of the core practices of XP (except Metaphor, and few teams have really felt like they successfully used XP's Metaphor practice). IXP builds on XP, adapting it for survival in larger companies, highly political companies, and large teams.
Kent Beck defined four values of Extreme Programming, values he felt were essential... other values were good, but he wanted to emphasis four in particular. XP's values are Communication, Courage, Feedback, and Simplicity. Agile Modeling adopted those four and added Humility.
Joshua and his team have chosen five values, which they not only want to emphasize, but insist that the absence of these values in the project or company will cause failure and unhappiness. The IXP values are: Communication, Simplicity, Learning, Quality, and Enjoyment.
The value of Enjoyment is sometimes deemed controversial. Joshua considered Fun, and probably felt Enjoyment sounded better. People who enjoy their work are more likely to want to learn I've always said that XP requires a Learning Organization). People who enjoy their work and enjoy working together are more likely to have the teamwork that XP requires.
Quality is "we know it when we see it." Quality products, quality code, a quality process, quality people.
These are the original XP practices that IXP includes (more or less), sometimes with modified names and meanings: [names in brackets are the original XP names, or the names I prefer over Kent's names.]
Sustainable Pace
Planning Game [Release Planning, Iteration Planning]
Frequent Releases [Small Releases]
Refactoring [Merciless Refactoring]
Story Test-Driven Development [Programmer Tests, Acceptance Tests, TDD]
Continuous Integration
Pairing [Pair Programming]
Collective [Code] Ownership
Coding Standard
Domain-Driven Design [replaces Metaphor]
Evolutionary Design [replaces Simple Design?]
The name changes are for clarity and to expand things beyond just coding -- people can pair on other things besides code, collective ownership can extend beyond code.
The new practices are:
Readiness Assessment
Viability Assessment
Project Community
Project Chartering
Test-Driven Management
Storytelling
Storytesting
Small Teams
Sitting Together
Continuous Learning
Iterative Usability
Retrospectives
Readiness Assessment answers the question "Are they able to transition to IXP?" See http://www.industriallogic.com/xp/assessment.html.
Viability Assessment answers the question "Is the project idea viable? Profitable? Feasible? Does the project have the necessary resources?"
Project Community expands on Kent Beck's "Whole Team" concept. "People who are affected by the project and who effect it." (Hope I got that quote right.) This includes QA staff, middle and upper level managers, tech support staff, programmers, DBAs, customers, end-users, and probably marketing and sales. (Reference to David Schmaltz / True North Consulting's Project Community Forum.)
Project Chartering provides the Vision and Mission, as well as the definition of who is in the Project Community. A light-weight exercise that seems to be necessary for clarifying the project's goals.
Test-Driven Management requires objective measures be defined for the success of the project. External results like "support 100 users by December 2003." The Whole Team cooperates to achieve this goal. Also defines return on investment.
Sustainable Pace. They considered renaming this to "Slack" (see the book by Tom DeMarco). An example of the value of slack is that it can provide the time for someone to write the tool needed to increase development speed -- too much focus on getting stories implemented quickly can be sub-optimal.
Storytelling. I think Joshua separated this out from Planning Game in order to emphasize that story-telling is a natural way to get requirements (sometimes after a bit of coaxing). IXP stories are not necessarily "user-centered" stories, since they may address concerns of administrators, maintainers, etc. "A story is an excuse to have a conversation." Conversation is required to understand some stories -- a story that can't be understood can't be implemented. Five words for a story title was also mentioned.
Storytesting. One word, to parallel Storytelling. This is defining the acceptance tests, but not writing them. IXP coaches help their clients in both Storytelling and Storytesting. Ideally, you do want "executable documentation" and they talked up Fit by Ward Cunningham - a framework that allows anyone using any editor capable of creating HTML tables to be able to specify acceptance tests. (Programmer help is still required to plug an application into Fit's acceptance test framework.)
Planning Game. Joshua says that it is very weird that some of the hybrid methods are throwing away the planning game. This practice is so useful that many of Industrial Logic's clients, who did not adopt all of XP, did adopt the Planning Game. Still, the concept of "velocity" (work done per iteration) seems to elude some clients
Frequent Releases - frequent end-user releases -- same as XP's practice. Enables rapid return on investment. Releasing to end-users provides opportunity for feedback, to find issues in deployment, issues raised by real live users. "Without learning, feedback does no good".
Small Teams -- for large projects, set up networks of small teams, with their own code-bases and coding rooms. A 30-person project might consist of teams as large as ten people and as small as three. Sometimes there might be a testing team and/or refactoring team that join the each of other teams at various times and then move on. Industrial Logic practices Pair Coaching, which does not require that both coaches be together at all times. Pair Coaching does enable coaching larger projects than a single coach could cope with.
Sitting Together -- Joshua says that the term "Open Workspace" turns some people off, but it is the same concept. He has seen a 40-person XP team in one very large room, but that's unusual. He has also seen one or more people give up the office they worked hard to get, because pairing in the same room as other people let them focus better and learn more. Sitting together / pair-programming can be done via internet collaboration, so it isn't limited to open workspaces. The gave an example of a team split in two time-zones, who decided to synchronize their hours to allow more "virtual pairing".
Continuous Learning. I've always said that XP requires a Learning Organization, and this practice make it explicit. Examples... Study groups who are not just allowed, but encouraged to get together for three hours a week, during office hours, because they know this helps them advance in their careers. XP Coaches who assign practice drills to the programmers or QA testers. "Lunch Break" learning groups show that management doesn't care enough about their employees learning. An XP coach in Italy spends an hour a day teaching his junior programmers -- whose skills are rapidly advancing. I think an member of the audience said "If everybody isn't learning, then learning becomes a subversive activity." Joshua also said that "resume-driven-design" tends to happen because programmers are starving to learn, but not given opportunities to do so.
Iterative Usability. The UI must be usable and tested regularly. Management-Tests should be tied into Iterative Usability. Redesign the UI as soon as feedback shows its flaws. Paper-based GUI design was also mentioned.
Time was running out, so the remaining practices were discussed quickly...
Evolutionary Design. Drives all design. Their tutorial has ten practices for this. (http://www.sdmagazine.com/documents/s=7928/sdmsdw3d/sdmsdw3d.html.)
Coding Standard. Have one.
Pairing. As per XP, but not just programmers.
Collective Ownership. As per XP, supported by tests, pairing, etc.
Retrospectives are a critical practice. Some clients are reluctant to get 40 people together for 2 or 3 days for a full project retrospect, but they should do it for the unexpected learnings that come from it. Also do mini-retrospectives each iteration.
Refactoring. Early and often as per XP. Don't let "refactoring debt" accumulate.
Domain Driven Design. Even though never officially a part of XP, it has been done by every good XP programmer that Joshua knows. The Model objects are kept separate from the rest of the code (GUI, etc.) The acceptance tests normally operate on the model objects, skipping the GUI. See the book on this subject at http://domainlanguage.com/. See also Erik Evan's "Ubiquitous Language".
Story-Test-Driven-Development. First write a failing acceptance tests. Then use the TDD cycle (failing programmer test, code to make programmer test pass, refactor) until the acceptance test passes. This is "top-down" TDD, and it best avoids writing unnecessary code.
Continuous Integration. As per XP.
See http://www.industrialxp.org/ for more information. Check out these papers, too: http://industriallogic.com/papers/index.html
[/docs]
permanent link
Against Command And Control
Dale writes in "Dale Emery, Bureaucrat" that his department was being changed from serving others to ruling others.
I think this increase in command and control is a recent trend in the industry, a fear reaction to the current economic climate. But remember: "The more you tighten your grasp, the more star systems will slip through your fingers." -- Princess Leia, Star Wars.
Hmm. I suppose a quote from a fictional character isn't the most effective. How about this: "If you are distressed by anything external, the pain is not due to the thing itself but to your own estimate of it; and this you have the power to revoke at any moment." -- Marcus Aelius Aurelius (121-180 AD), Roman emperor. And this: "An intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction" -- Hoshang N. Akhtar
I'm going to have to read more about Deming. These are his "14 points":
1. Create constancy toward improvement
2. Adopt new philosophy
3. Cease dependence on inspection for quality
4. Minimize cost
5. Improve constantly
6. Institute job training
7. Institute leadership
8. Drive out fear
9. Break down barriers
10. Eliminate slogans
11. Eliminate management by objective
12. Right to pride of workmanship
13. Institute self improvement program
14. Accomplish transformation
[/docs]
permanent link
Update on Lean's "Do it Right the First Time"
One of the practices of Lean Manufacturing listed here http://www.poppendieck.com/lean.htm is "Do it Right the First Time".
When questioned about the appropriateness of that to software development. Mary Poppendieck wrote on the Lean Development mailing list:
I regret now the application of "Do It Right the First Time: from manufacturing to programming. I generally use the phrase "Test First" or "Build Integrity In".
"Do It Right the First Time" has been widely misinterpreted and I dont think it is a good way to look at a design process.
The impact of "Do It Right the First Time" in manufacturing is that every time a design is delivered to the plant to manufacture, it is delivered with a complete set of tests so that the manufacturing process can be checked every step of the process. Designs of manufactured products are changed repeatedly, even after a product goes into production. With every change, the tests are changed also.
The fact that we do not consider a test suite to be a part of a delivered software product is where we have a lot to learn from manufacturing.
Tom Poppendieck adds more on the "test-first" used by Toyota and in Lean software development:
Toyota's design process uses set-based design which employs check sheets to communicate gradually narrowing design options. These check sheets are equivalent to tests. Set based design basically suggests trying several ways of solving a problem in parallel to learn enough to make a fact based decision rather than speculative up-front decisions if you permit yourself only one shot.
The tests are the key mechanism for keeping options open. Without comprehensive tests, refactoring [software] is far too risky and rework would be expensive. The tests are a record of what you have learned their automation and very frequent execution guarantee that you will not accidentally forget what you have learned. Thats why the first step in fixing a bug is to write a test that fails as long as the bug is present.
To my mind, rework does not refer to recoding or recompiling. Code is pretty easy to generate via TDD. It is the learning that is expensive and forgetting and relearning is to be avoided.
I ... argue that an application that has been aggressively refactored throughout its evolution will have much more flexibility than one that is architected once....
[/docs]
permanent link
Mary and Tom Poppendieck on Lean Development
Peter Lindberg's Irrational Software blog has book reviews on the book Lean Development by Mary and Tom Poppendieck. It's available for pre-order on amazon.com.
A draft of the book is also on-line at http://www.poppendieck.com/ld.htm. I have pre-ordered the book, but haven't read the on-line version yet. I'll be quoting Peter Lindberg in what follows.
They cite a study by Raymonde Guindon, which "found that cycling between high level design and detailed solution was typical of good designers when dealing with ill-structured problems, that is, problems which do not have a single right answer or a best way to arrive at a solution...."
That sounds like what we do with Test Driven Development (TDD), doesn't it? Write a small test (define some part of the problem); write the simplest code to pass the test; when the test is passing, if refactoring could improve the design of the code, do it; repeat.
The Poppendiecks also quote Ed Yourdon as saying that any piece of code needs to be rewritten three or four times to be consistuted as an elegant, professional piece of work. For prose, we take this for granted, he said, why not for code?
Again, we do this in TDD... as more and more tests are written, the code is made more and more functional, with frequent refactoring to keep it clean. The difference between rewriting and refactoring is that rewriting isn't constrained to keep the same functionality.
Aside: Dale Emory, Michel Tsai, and I, recommend books by Joseph Williams whose titles start with "Style". Peter Lindberg reports that Dale called it "Refactoring for writers" and I have said that it is the perfect writing book for programmers. Check it out: Style: Ten Lessons in Clarity and Grace and Style: Toward Clarity and Grace.
Peter also makes a comparison to XP: Software development projects are often managed as push systems, where plans and schedules drive the process. Extreme Programming projects, could perhaps be said to be more akin to pull systems, [pulled by demand, like the Kanban systems described by the Poppendiecks] where features are represented by cards, preferably kept visible on a wall divided into three sections representing what's currently worked on, what's finished, and what still remains to be done. Testers, for instance, would pick cards from the section with completed features, and managers and customers could tell from looking at the wall how things are going - instead of calling to a meeting to update the schedule.
Peter describes the Kanban system as "a Kanban card is left on the shelf as a part is taken from inventory. The cards identify the parts that were taken, and these are collected and replaced by newly manufactured parts. A part might consist of subparts, for which Kanban cards are left, thus causing demand for new parts to ripple across the system."
Isn't that a delightfully low-tech system for updating inventories? Who says you have to have computers to do everything?
[/docs]
permanent link
More on Reset, Encapsulation, Value and Immutable Objects
(Sorry for the repost of yesterday's post -- I just had to correct a missing parenthesis, and this is what happens when you do that.)
A reader suggests that I could use reference counted smart pointers to avoid problems I described in my previous essay.
That would not fix the problem of violating encapsulation -- retaining one object's member data in multiple other objects. In fact, in this application, if we were using boost::shared_ptr or our own reference counted smart pointer, and did the 'delete'/'new' approach, the result would be multiple "platform independent document objects" in a program designed to have only one document object. The various distinct views of the document would get out of synch. (I do use boost::shared_ptr in my application, to enable passing around large image objects among image processing functions as if they were Value objects -- I don't have to worry about premature deallocation.)
The same reader suggests that a Reset method isn't that bad... He writes "Functional requirements for cleaning self up logically belong in the object, not in delete/new."
I would say that in C++, the requirement for an object cleaning self up belongs in the destructor, by definition of "destructor". Whether the coder does the same cleaning up in Reset is up to the coder.
Probably the real reason for my dislike of Reset is that some coders using it seem to have confused "variables" with "objects". You reset a variable. You create and delete objects. In the application I was talking about, the object has effectively become a global variable, with all the problems that globals have, even though only member variables are being used.
In some ways it is even worse, because these variables are actually pointers to a global object: those pointers can become dangling pointers if the object is deleted by what is supposed to be its sole owner. Using Reset hides the fact that this is a global... better to make it a real global variable, to avoid the dangling pointer problem, or not pass it around at all (which is what LoD recommends). The application I was describing is a single-document application, so the MFC document object is effectively a global variable/global object.
My other point about Reset is that Value objects don't need it, and Immutable objects can't have it.
Imagine a Dimension object. In Java or Smalltalk, you might want to make it immutable, so you can safely return Dimension member values without making copies. This assumes that you don't do lots of math on Dimension objects -- because that would require making copies. It is a choice of which is more efficient, and/or safer.
In C++, I would implement Dimension as a Value object - one that implements the copy constructor and the assignment operator (and default constructor for STL compatibility). Returning this kind of object "by value" automatically makes a copy. If you want to reset a Dimension variable, just assign Dimension(0,0) to that variable. You minimize the number of methods to write, and you make it very clear what you're doing.
[/docs]
permanent link
Law of Demeter and Encapsulation
The Law of Demeter (LoD) is a heuristic for good object encapsulation. Ignore the Law of Demeter (and other advice on encapsulation), and you'll find yourself in a debugging and refactoring hell. Applied too strictly, LoD forbids container objects and external iterators (there may be a loop-hole for that, which I'll get back to later).
Yesterday, I wanted to eliminate a "reset" function in one object, and instead have its owning object delete and re-create that object. That should be straightforward, but it didn't work because encapsulation and the Law of Demeter were being violated.
The problem here was that a pointer to member variable of this "reset-able" object was being passed around and retained by other objects, whose lifetimes are longer-lived than that member variable would be if I implemented the delete and re-create strategy.
I've trained myself to never give out a member variable's address, just like a TV network never gives out a TV star's address. It's dangerous. It causes the program to be more brittle. It violates encapsulation. You never know what those obsessive fans or programmers might do. Other objects become too dependent on the internal state of another object -- changing the internals of an object becomes difficult. Polymorphism is overly restricted because any "replacement" class must also give out a member variable's address, and that variable's type must be compatible. As I said, I trained myself, but sometimes I forget, and I'm working with other people who sometimes also forget about this danger.
In C++, an alternative to returning a pointer to a member object is returning a reference to a member object, but that turns out to be just as bad. I'll illustrate with some code.
Pointer* ptr = obj.GetMemberAddress();
delete obj;
// ptr is now "dangling" - pointing to deleted memory.
Reference& ref = obj.GetMemberReference();
delete obj;
// ref is now "dangling" - it also points to deleted memory.
No one would write code that obviously bad, but put in an event-loop, lots of intervening functions and other objects, and maybe some threading, and the same thing can happen without anyone realizing it until the crash occurs.
You could make a rule to never retain such a pointer or reference... that is an improvement (as long as no one breaks the rule), but it is awkward. It also requires that you never pass the pointer or reference into functions. It's too easy forget where the pointer came from, and create a persistent object holding that pointer. And that dangerous "persistence" include multi-threading as well as objects - a thread's lifetime is even less predictable than an object's, and it becomes much harder to diagnose dangling pointer problems in multi-threading programs. Unfortunately, I sometimes want "values" returned by my member functions to be polymorphic. In C++ that requires a pointer (which brings in memory management issues) or a "smart-pointer" (which I'm using more of lately, but is a bit cumbersome.)
So LoD forbids this:
memberPtr = obj.GetMemberAddress();
memberPtr->DoSomething(); // potentially changing obj's member state.
It also forbids this:
obj.GetMemberAddress()->DoSomething();
What you should do, is either return a copy of the member, and the copy's lifetime is no longer under the control of "obj", or incorporate DoSomething() into the API of "obj".
So we can write:
memberValue = obj.GetMemberValue(); // returns copy
memberValue.DoSomething(); // doesn't affect obj's original member state.
We can even write:
obj.GetMemberValue().DoSomething();
because DoSomething is operating on a copy. NOTE: if you write this sequence of calls more than once, XP requires that you remove this duplication, most likely by incorporating DoSomething into the API of "obj".
Returning a copy is particularly useful for 'basic' types like String, Date, and so on. The safe programmer will return a copy of a string or date member variable, so that callers can not change the state of the member variable "behind the owner's back'".
Some of the more rabid fans of the Law of Demeter say that even this operating on a copy is too fragile, and you really should do this:
obj.DoSomething();
The danger of over-applying this idea is that your object interfaces get really fat. You really don't want to re-implement all of the member functions of String for each of the String members in your EmployeeData class just because you think LoD tells you to. Because of this, I think of the "Law" as more of a "Recommendation".
I assert that immutable objects are an exception to the Law of Demeter.
Java's String class is immutable (once the object is created, it can't be changed), so Java programmers don't have to make copies of String member variables in their accessor functions.
Some people have recommended declaring mutable and immutable interfaces, declaring the mutable object to implement both of those interfaces, and declaring this "accessor" function's return type be just the immutable interface, so that you can return a mutable object through that immutable interface. Of course, a programmer could "down-cast" back to the mutable type, but then all sorts of bad things can be done if you work at it. Probably better to create a copy of the object to avoid the down-casting trick. And, in languages like Smalltalk and Python, you don't have variable and function type declarations to make this immutable interface idea work (though you could create and return an Immutable Adapter to enclose your mutable member).
And what about that loophole for containers and external iterators?
LoD says you can't return references or pointer to your object's own member data, but containers are given data to hold, and so they can return that data.
External Iterators are new objects, not member objects, created when you call the a function that returns the iterator.
So what am I going to do about my hard-to-modify program?
Well, changing it to conform to LoD is going to be at least a day's worth of work. And we violated LoD on purpose, though now I regret that decision. We have a MFC Document object that owns a platform-independent "document" object. We pass the MFC Document object to other MFC classes, and pass the platform-independent "document" object around to the rest of our code. But we're not consistent about that.
To make this conform to LoD, the platform-independent object must never be passed around to other objects at all -- everywhere we currently do this, we should be passing around that MFC Document object instead. That means that the complete interface of platform-independent "document" object must be implemented in the MFC Document object, delegating to the member object. However, the "type" we pass into various part of our program doesn't have to always be the MFC Document type, it can be a base-class type -- the platform-independent "document" interface -- we just have to declare the MFC Document type to subclass from that interface.
Then, and only then, could I have the MFC Document object have full control over the lifetime of its member objects (and even then, I have to be careful about threads - I can't delete an object if another thread is still using it.)
And why would I want to eliminate a "reset" member function and instead delete/re-create the object? Because it's too easy for a reset member function to forget to clean up all of its state. I object to "reset" functions generally, for both small objects and large objects like documents. For small objects, I prefer immutable objects that I can easily recreate on demand, because then copies don't have to made in accessor methods, and immutable objects are more easily made multi-thread safe.
For future thinking: how can LoD work with threads? Can we think of the thread as an object? Some platforms do.
Here's a "formal" version of LoD: A method "M" of an object "O" should invoke only the the methods of the following kinds of objects:
itself ("this" in Java and C++)
its direct member objects (this.member in Java, this->member in C++)
its parameters
any objects "M" or "O" creates/instantiates
[my extension] any objects created but not retained by a member or parameter method
Here's the informal version attributed to Peter Van Rooijen:
You can play with yourself.
You can play with your own toys (but you can't take them apart).
You can play with toys that were given to you.
And you can play with toys you've made yourself.
See http://c2.com/cgi/wiki?LawOfDemeter for more discussion on this topic.
See http://www.ccs.neu.edu/home/lieber/LoD.html for a list of LoD links.
[/docs]
permanent link
More Defects from MultiTasking?
Ron Jeffries posted his email conversation with Jon Eaves on XP mailing list in "Bug tracking vs user stories"
[ jon ]
"Projects that have developers working on multiple simultaneous projects
have a 30% higher defect rate than projects with developers assigned
specifically to it"
[ ron ]
Fascinating if true.
[ jon ]
I don't remember the actual number, this is again from a previous life, but
there was a higher defect incidence rate. We stopped this practice (or at
least attempted to minimise it) and life was better for everybody.
[/docs]
permanent link
Books in progress
Michael Feathers has a start on a book currently titled Working Effectively with Legacy Code, the mailing list to discuss the book is http://groups.yahoo.com/group/welc/ and drafts of the book are in that yahoo group's file section.
David J. Anderson has a yahoo message group at http://groups.yahoo.com/group/agilemanagement/ to discuss his book (almost final now), the book is in pdf form here: http://www.uidesign.net/
Here's the message group's description
Agile Management is a group to discuss the content and thesis of the forthcoming book, "Agile Management for Software Development: applying the Theory of Constraints for Business Results", by David J. Anderson, to be published by Prentice Hall in summer 2003.
Agile Management uses a combination of Eli Goldratt's Theory of Constraints, its management accounting method, Throughput Accounting, Lean Thinking and Systems Thinking ("The Fifth Discipline") to demonstrate how agile software development methods can be controlled, managed, cost justified and summarized for executive reporting.
The book postulates 4 agile management roles: development manager; program manager; project manager; and product manager. It then provides definitions for the areas of responsibility and describes the work of each manager. The topics of Agile Development Management, Agile Product Management, Agile Project Management and Software Resource Planning (the job of the Agile Program Manager) are explained in detail.
Discussion is invited on this list regarding the application of Theory of Constraints, Lean Thinking, Learning Organizations and Failure Tolerant Management, to the field of software development.
[/docs]
permanent link
Frequent Releases to End User
One of the best books on Extreme Programming is Planning Extreme Programming by Kent Beck and Martin Fowler. It doesn't tell the customer how to gather requirements, but it gives lots of advice on how to do XP from the customer side... particularly Release Planning and Iteration Planning, and why, of four variables (Time, Scope, Resources, and Quality), he suggests only letting Scope vary.
Kent Beck's prose is highly factored -- he tends to say things once and only once -- so you have to read carefully. He doesn't explicitly define what a "release" is, but there are clues that he really does mean releasing to the end-user... when he talks about releasing to internal testing, or to the Customer (standing in for the end-user), he uses the phrase "interim, internal release".
Here are few quotes from the book about how often to release:
Often the dates for a project come from outside the company:
* The date on the contract.
* COMDEX
* When the vc money runs out.
Even if the date is of the next release is internally generated, it will be set for business reasons. You want to release often to stay ahead of your competition, but if you release too often, you won't ever had enough new functionality to merit a press release, a new round of sales calls, or champagne for the programmers. (page 40)
Short Releases
Sometimes you can release much more often, maybe every iteration[....] However there is danger to never having "a release". The customer may lose strategic vision of where the software needs to go. (page 79)
Long Releases
What happens if you can only release once a year? [...] Another case is shrink-wrap software [...] look for a way to send intermediate releases to those customers that may be more interested in these versions. Call them service packs or something[....] Frequent releases are good, but if you can't release frequently you don't have to abandon XP completely. You may need to create interim releases that are only available internally. (page 80) [Bold emphasis is mine.]
[/docs]
permanent link
Proposal: an Information Radiator for Feature Requests
Consider tracking feature requests using a cork board... (one cork board per product) each time a feature request comes in, compare it to what's already on the cork board. If it's not there, find a place on the cork board
for it, write it on a sticky note or index card, and post it. If it's already there, add a hashmark to indicate multiple requests for that feature.
At some point, start grouping the feature requests that are on the cork board... this set of 9 feature requests can be grouped under
"scriptability", this set can be grouped under "import/export", this group
can be grouped under XX or YY.
Imagine this cork board visible to everyone at the company... other people
could add cards to the cork board, because they see a missing area. The VP
could add a comment to the XX grouping, saying that these features are not
valuable to the more profitable customer base they want to target, only
those laggards that haven't upgraded to the latest product version. Customer
Support representatives could add to the cork board those off-hand comments
said by end-users that they didn't think important enough to file as a
formal feature requests.
Imagine being able to see patterns and order emerge out of the chaos of
individual feature requests... someone sees this and says "I have an idea
for a new product line!"
[/docs]
permanent link
Bits and Pieces
Yesterday afternoon, the Bay Area weather was so nice that I dragged myself to work with some effort. I had previously signed up and worked on a story that I knew I could finish off by the end of the day, and I didn't want to not finish it and loose the three story points from my team's velocity. So I do the hard thing and get the work done. And today, Saturday, it is raining. Bleh.
I'm sure that the weekly traffic patterns affect the weather -- all that automobile pollution keeps the area warmer than normal, and then on Saturday the cold and rain comes in because there's little traffic. Or something like that. I've read that California gets some of the pollution generated by China, so maybe Beijing's weekly traffic/pollution patterns are at fault.
Another bit on agile requirements... XP doesn't say how to gather requirements. RUP does. I attended one of the presentations by Dan Rawsthorne of Net Objectives, a presentation called Comparing RUP, XP, and Scrum: Mixing a Process Cocktail for Your Team (Check that link for their slides in PDF form). Dan recommends combining RUP's Use Case creation techniques, with Net Objective's own "Ever Unfolding Story" technique, to create stories for XP's release plan/iteration plan. He says that a typical Use Case can create up to forty XP stories. Maybe ten of the stories are the "core" of the Use Case and can be delivered in one or two iterations. Another ten may be important for the final release but of lower priority. The other twenty stories may not need to be implemented at all -- but a typical heavyweight RUP project probably would have implemented them. If you have question about this or the "Ever Unfolding Story", please talk to Dan at www.netobjectives.com... I'm just reporting here.
I do want Dan to correct one of the slides... the one about XP and the "business levels". The slide about RUP shows RUP "touching" the business level at "kickoff", "delivery 1.0", "delivery 2.0", and so on... Dan asserted that XP doesn't "touch" the business level, and drew the slide on page 22 of the PDF file that way. That's WRONG. XP's "Small Releases" correspond exactly to the RUP process slide's "delivery 1.0" and "delivery 2.0". Those releases every three or six months are at the business level, to get feedback from actual users.
I also attended a one-day class on Project Management recently. The simulated project was waterfall, but the word "waterfall" was never mentioned. There was no mention of the possibilities for iteration, incremental development, or even feedback. I don't think any of those terms were in the vocabulary taught as part of class. The instructor had never even heard of Rational Unified Process ("Rational Who?"), much less Extreme Programming, Scrum, Feature Driven Development, etc. That's scary.
So what did I learn in this project management class? Well, the project process has Initiating, Planning, Executing, Controlling, and Closing. No mention of maintenance. Not much about people issues.
Planning included the "Work Breakdown Structure" (a rather unfortunately overly task-oriented breakdown of features that does have some resemblance to XP's "Release Plan", sorta.) We saw a "Responsibility Matrix" correlating tasks with "do, review, and approve" columns. We learned about finding the Critical Path on a Gantt Chart. A little bit of Risk Management and mitigation planning. And of course, "resource" allocation and management. [I'm having a vision ala Solyent Green: "Resources are people!"]
The "trade-off triangle" of Time, Cost, and Scope/Requirements was mentioned. No mention of the zeroth law of software engineering: "If you do not care about quality, you can meet any other requirement."
We learned a lot of vocabulary, with emphasis on "crashing" (adding resources to decrease the project schedule -- hmm -- like getting nine women to have have a baby in one month? No mention of Brook's law.) and "fast-tracking" (defined as "compressing the schedule by overlapping activities normally performed in sequence").
My hand-out from this one-day class says "the PMBOK is the standard knowledge source for project management," and lists a bunch of books. Some of the books I've heard of -- Critical Chain by Goldratt, some of them I've read -- The Deadline by DeMarco (I wish he could go back and write an "agile" second edition or sequel), some of them sound good Customer-Driven Project Management by Barkley & Saylor, and some of them are just scary -- The Complete Idiot's Guide to Project Management.
[/docs]
permanent link
More on Agile Requirements
Bryan Dollery's article The Buck Stops Here and Scott Ambler's Agile Requirements: The Real Message are two responses to an article by someone who'd never experienced an agile project, who wrote a rejection of the agile approach based on misunderstanding how it works.
My web-log entry Incremental Requirements was also a response to this article.
[/docs]
permanent link
Test Driven Dialog
This is a dialog I created in July 2002, from messages on the Test Driven Development mailing list -- an email conversation between Robert Blum and Roger Lipscombe. After my editing, they didn't recognize their words, so perhaps I did a little more writing than editing. Any similarity to my favorite comics characters is purely coincidence.
Calvin: I don't do test driven programming. I write some code, and test it
manually, walking through it in the debugger, checking that it works.
Hobbes: How do you know that it works? Could you express that as a test
before you run your code?
Calvin: I can't think about the test until I've thought about the code
Hobbes: Changing the habit of writing code before the test can be a bother.
Try this: Write the code on paper. Then write a test.
Calvin: Paper?!
Hobbes: What if you just outlined the code on a whiteboard and didn't write
any real code? Could you still write a test first?
Calvin: I'd feel silly doing that alone.
Hobbes: What if you explained it to your pair partner? Could you still
write a test first, or maybe have your pair partner write the test?
Calvin: That could work.
Hobbes: I notice you're refactoring without tests. What's that like?
Calvin: After I refactor, I have to test it again manually, in case I make
a mistake doing the refactoring.
Hobbes: Wouldn't it be easier to run some quick automated tests before and after you refactor?
Calvin: Well duh! If I had the tests.
Hobbes: If you do test-driven development, your tests drive the design of
your code, and as a side-benefit, you get a nice small set of automated
tests that make refactoring safe.
Calvin: Perhaps if I start by thinking about the interfaces that my class
or module would need to support, I would be able to write the unit test
first? Does this sound like the kind of thing I should be trying more of?
Hobbes: I think so. If I were given just the task of writing a class or
module, my first test would describe a very simple case of what I wanted
from that code. The interface of this not-yet-written code is evolving, of
course, during my test-driven development process. Since I'm calling the
functions that I need at each moment, without a care how (or if) they are
implemented, it tends to create a pretty useable interface.
Calvin: So you find out quickly if your interface functions are no good
when you're forced to use them as client, in the tests, before investing a
lot of work at writing them!
Hobbes: Now you're getting it.
Calvin: Tell me, when you think of a feature, is your next thought about
testing or implementation?
Hobbes: I just think about using that feature. Which leads me to an example
of how I would use it. Now I just write down the results I expect from that,
and voila, there's the test. I'm not even actively thinking 'I have to write
a test now. How can I test it?'. My main focus is how I can use it.
J. B. Rainsberger added a few more lines:
Hobbes: Have you written tests for that code yet?
Calvin: Tests?! TESTS?! I don't need tests! What do I need tests for?
Don't you think I can write something this simple without using tests
as a crutch?! I know it's right!
Hobbes: (rolling his eyes) Of course you do.
Calvin: Right. Now help me fix these last four bugs.
And Laurent Bossavit capped it off:
Hobbes: I thought I was doing that.
[/docs]
permanent link
Agile Writing
A writing collaboration is taking place in the Agile Modeling mailing list. Scott Ambler posted a draft of a paper he's writing, about the rights and responsibilities of stakeholders and developers.
Scott: So, I'd appreciate any feedback that you might have. Thanks in advance.
Ron Jeffries: Here it is. It was wise to thank me in advance, because in a few minutes
you may no longer feel that way.
Anne & Larry Brunelle's idea of no longer separating developers from the other stakeholders has resulted in a new paradigm. Ron's
combined-rights draft has phrases like:
You have the right and responsibility to show and to observe progress in
a running system, proven to work by repeatable tests specified by customers
and programmers alike.
You have the right and responsibility to know what is needed, with clear
declarations of priority. You have the right and responsibility to
contribute as much as you can to determining needs and priorities.
You have the right and responsibility to ask for and receive help from
everyone on the project, peers, superiors, subordinates, programmers,
or customers. You have the responsibility to give help when it is asked
for.
[/docs]
permanent link
Incremental Requirements
The great thing about agile projects, is that you don't have to have ALL the
requirements up-front, just enough to get started. Once you see the software
working (minimally), you can change your mind about the requirements that
are not yet implemented or have been implemented.
Consider a non-XP project, one that is not incrementally implementing features. If the customer decides in the middle of the project to change some requirements, the project may have to throw away lots of partially-completed code.
In the middle of an XP project, a requirement is either implemented or not -- the only time a requirement may be partially implemented is during the two-week iteration it was schedule for. Any requirements that haven't been implemented yet can be changed at zero cost. A change for requirements that have already been implemented is essentially the same as adding a new requirement -- it will cost something to be re-implement, and an equivalent amount of other non-implemented requirements should be dropped to keep the project on schedule.
Developers are the genie in the magic lamp - delivering any features that the customer wishes - so long as the customer is willing to pay the price (time and money). With this power comes rights and responsibilities.
In Extreme Programming, rights and responsibilities are divided between
"business" and "developers". The "business" side has the business analysts,
the QA testers, domain experts, users, stakeholders, and so on. All wrapped
up in the single word "Customer". They are all involved in defining,
specifying, and creating tests for the requirements. If you have business
analysts in your team, it is the job of business
analysts to help the stakeholder come up with requirements.
The "developer" side has the programmers, DBA, and so on. They translate requirements into code,
databases, web servers, and so on. User interface
experts may be either side, depending on whether they do programming as well
as user interface design.
The business side is responsible for the requirements, the wishes they make of the genie,
because they are responsible for running their business. To avoid this responsibility is to
let the developers run your business. Unless the business is making
tools for other software developers, it's unlikely that the developers have the expertise
to satisfy your customers and make a profit.
The responsibilities of the two sides are clearly divided to reduce risks: if
the business guys (who are not programmers) start telling the
developers how to do programming, they risk technical failure. If the
programmers tell the business guys what features should be implemented,
there is a risk that project will not meet business needs.
When talking about what to ask the genie in the magic lamp,
I've never seen anyone with a lack of ideas. They
may not know HOW to get what they want, but they always know enough of what
they want to start a conversation. Like the following:
"Wouldn't it be great if we could do x?"
"Could you make it so that y happens when I do z?"
"I want this..." (drawing on whiteboard).
"Our customers are doing this manually, and we want to sell them software
that does it for them."
"This is what I do all day, I want it simpler and faster."
"Our competitor has product x with feature y, we need something like that."
In XP a requirement is expressed as one or more stories. I've heard that one UML Use Case, RUP style, can translate into 40 XP stories, of which 20 stories could be optional. An XP story is a promise for future conversation about the details of that requirement. You don't have to think them up all at once, you don't have to have all the details up-front, you don't have to write up a thick document. You do talk with the developers, other stakeholders, and business analysts if you have them.
Recommended reading:
Exploring Requirements: Quality Before Design by Gause and Weinberg
Planning Extreme Programming by Beck and Fowler
[/docs]
permanent link
Leadership is not Herding.
I don't like hearing people refer to managing programmers as "herding cats". Probably because I am a programmer and I have cats (at one time, living in a really nice house in a suburb in Texas, my wife and I had five cats).
It is easy to lead cats... in fact, when I'm trying to take a picture of one, it's hard to keep him from following me around. Trying to make cats go somewhere, without leading them, can be very hard, if you don't consider what motivates them.
So when I hear someone comparing programmer management as "herding cats", it makes me think that they're trying to make them go somewhere, not leading them.
A particularly good book on project leadership is Powerful Project Leadership by Wayne Strider. (Order direct or via amazon). It's good enough that I just bought a second copy for lending to others. This book's first lessons in leadership are to help you become aware about yourself, others, and your shared context. In fact, the book is divided into three divisions: leading yourself, leading others, shaping your project's context.
Check out a sample of Wayne's writing here: Leading Projects in Stressful and Chaotic Situations.
[/docs]
permanent link
Training? We don't need no stinking training!
A manager told me the other day that his annual budget for training was $800. For him and the four or five people under him.
With most classes and conferences costing over $1200, there's no way that he or anyone working for him will get ANY training this year.
What's up with that?
[/docs]
permanent link
Reuse
TWELVE|71 wrote a bit about reuse and modularity. "Modularity is the idea of having a tire that can be swapped on and off without affecting the car. Reuse is the idea that we can take a tire from an old car and use it without thought on a new car."
Off the top of my head, I think software reuse projects often fail because (1) the needs of all the client projects are not considered when making the 'reusable' module, (2) the module is not documented well enough, (3) people on the client projects are motivated to not reuse modules, perhaps because they are rewarded for hours worked or lines of code written (or some other counter-productive measure), or (4) they are under time pressure, and don't have time to rewrite their app to use a module that they seem to be able to do without.
Take the reverse approach. Instead of creating a module and telling projects to use it, create a small "Extreme Reuse" team: one to four people who join projects to (1) help them get things done (2) look for code that could be extracted for use by other teams (3) refactor project code to create and reuse shared parts. The Extreme Reuse team needs to join several projects before extracting code from any of them, in order to know all of their needs. How can a few people join a team and be immediately helpful and productive? Pair programming.
Bryan Dollery has described this and other aspects of how to reuse parts here.
I don't know anyone trying a "Reuse Team"; please let me know if you are. My small team works on several projects. We have code common to these projects in some separate directories, and it is mostly unit-tested. (Yes, we're not 100% pure XP.) We make minor changes to this common code, and avoid breaking the clients by continuing to pass the unit tests, and by building and testing the client projects.
[/docs]
permanent link
April Fool Links
Top 100 April Fool Hoaxes Hoax number eight reveals the source of story about a state legislature passing a law to make pi = three.
How to write Unmaintainable Code: Roedy Green's version on multiple pages, and another version on a single page.
I used to have April fool issues of Byte magazine that described the black hole diode (useful for reading disks still in the shrinkwrap), the sliderule emulator, and my favorite: the solution to the vexing problem of how many buttons should be on a computer mouse - the 'Megamaus', which had a full ascii keyboard on the back of what appeared to be a large rubber rat.
[/docs]
permanent link
Speaking of Objects as cooperating, independent, agents...
Chris Uppal, on the Dolphin Smalltalk newsgroup, writes about his "Great Leap Forward from Java to Dolphin Smalltalk." He describes the big difference...
If you are like me, then you are currently thinking of a big difference
between Smalltalk and Java being that Java stores code in files, whereas
Smalltalk keeps it in the image. That's sort of true, and I'll get back to it,
but, for a minute, just forget about code, it's not important (really!). What
matters is objects.
The image is the place where the objects live. Technically, the image is a
garbage-collected heap that can be saved to file, and later restored, thus
saving and resuming the state of a computation. Technically that's true,
but it isn't at all a helpful way to think about it. A more organic metaphor
works much better. I think of the image as a deep, murky, pond where objects move
around in the depths like fish. It's an important part of the metaphor that
the objects are independent of me. Even if I designed and wrote the classes,
once an object has been created it has an independent existence. I can talk to
it, I can ask it to perform operations, but it is separate from me. In a sense it
is "my" object, but it is only "mine" in the same way that a pet, or a rose
bush, or a table, could be "mine".
The image is where the objects live. Not the code, the objects. We'll get
back to the code in due course, but not yet. The Smalltalk environment is just a
place where you can talk to objects; no more, no less. Oh, sure its got
class browsers, debuggers, editors, etc, but that's all tinsel. What matters is
that it is a place where you can interact with the objects.
I'll get back to the "tinsel" later too, but for now, I want to talk about
the one part of the environment that isn't just a productivity aid: the
workspaces. Workspaces are the medium through which you talk to objects. You can
describe workspaces as "containing snippets of code" which you execute, but IMO
that's exactly the wrong way to think of it. A better picture (slightly
tongue-in-cheek) is as a kind of singles bar, where you can meet objects,
talk to them, check them out, get to know them. Each workspace has a number of
objects that are (temporarily) living there; they are the values of the
variables in the workspace. In most cases they'll die when you close the
workspace, but until you do they'll survive and you can talk to them. I keep
some workspaces hanging around for days if they contain objects that are
important for what I'm doing. The way you "talk" is by sending messages
written in the Smalltalk programming language, but that's almost incidental. The
important thing is that you are communicating with them using an interactive
text-based medium, like using an IRC [chat] channel.
[...]
Another way of interacting with objects is to use the Inspector(s). They
give you a much more nuts-and-bolts, low-level, view of the object -- a more
intimate view, if you like. I, personally, don't think that the Smalltalk
world has yet woken up to what inspectors could be, but the current
implementations (like "flipper" in Dolphin) do at least allow you to see
inside the objects.
I wish C++ had inspectors... but C++ throws away a lot of information
when you compile the code. In the crappy debuggers that C++ programmers
have to live with, we often can't view the run-time contents of an object
properly and easily. The VC++ debugger for example, should be able to know that the
object pointed to by a base-class pointer is actually an instance of a derived
class, but it doesn't display the member variables that belong to the
derived class -- just the member variables of the base class.
An image will contain many objects, some long lived (living, perhaps, for
decades), most very short lived indeed. Some will be simple or trivial, like
Strings and Points. Others will have complicated internal structures, and/or
complicated behaviour. But they are all objects, and they all live in the
image, and you talk to them in workspaces.
A Squeak Smalltalk image contains objects that have been "alive" since 1984 or earlier, because Squeak was derived from a Xerox/Apple implementation of Smalltalk-80. The objects in the image "sleep" when saved to disk, and awaken when restored from disk. This means that some objects in Squeak have been alive longer than some programmers have been.
Classes are one particularly interesting kind of object. Remember I'm
still not talking about code (that comes later), I'm talking about the objects
called classes. Just like any other objects, you can invite them to join you in a
workspace:
[I modified the code slightly here...]
aclass := String.
and then you can use the magical Smalltalk object-oriented IRC to talk to
them:
aclass name. "--> #String"
aclass allSubclasses size. "--> 3"
and so on. So classes are objects, and they live in the image.
[...]
Code is how we tell objects how to behave. It's text in the Smalltalk
programming language. We're programmers so we care about code; when we wrote
the tools for looking at objects, we naturally designed the tools so that we
could also see the associated source code. For instance our special tool for
looking at classes (the class hierarchy browser) allows us to see the source
of the methods, to change the source and recompile, etc. That's natural for us
as programmers. If we weren't programmers then we'd want different tools, and
we'd be interested in talking to different objects. Such systems, built for
non-programmers, are called "applications", but they are still just
Smalltalk -- tools for talking to objects that live in an image. (A big
difference is that the "image" of an application is typically not
persistent, unlike the image of the IDE).
Back to code. Granted that the most important thing is the objects and how
they behave, we still do care about the code. We want to organise it, back it up,
put it under source code control, etc. A class is an object that lives in
the image, but the source code for that class is something else. For all sorts
of reasons, we want to keep that outside the image. The way that Dolphin
organises source-code is via Packages. A package is a collection of the source code
for classes and methods (and a few other things too, which don't matter here)
that is kept outside the image in one or more files. You can load the package
into the image, which will create an actual Package object, and class objects
corresponding to the source-code. Or you can "uninstall" the package, which
really means killing the Package object and the Class objects.
So a package is just a way of collecting related source-code together. [...]
The package mechanism is relatively simple; it could be improved, but I find
it adequate for my needs. Package files are text files, you can edit them with
vi, or notepad, or whatever. Occasionally I do that if I want to make
particularly sweeping changes to the source. Of course, if you do that then you have to
install the changed version into the image before it'll do anything useful.
Notice how very different this way of thinking is from the way that even the
best Java IDEs encourage you to think. When I started out in Smalltalk I was
thinking of the IDE as if it was a Java IDE. I though of it as a tool that
allowed me to write code, and had features to allow me to browse and test
the code. After a year or so I realised that I'd turned the picture upside down
completely, and in the process had revised my conception of what
Object-Oriented programming is all about. As a Java (or C++) programmer I
had pretty much thought my .java (and .cpp) files were the classes, and I
thought that creating classes was what programming was about. I now think of the
objects as being the important thing, and the classes as very secondary,
hardly more than an implementation detail.
I feel that that has made me a better programmer. Of course it's not
possible to know for sure, but if it has, then it all comes down to Smalltalk's
workspaces...
The original message can be found here
[/docs]
permanent link
Lean Development
Hal Macomber reminds us that Lean Development not only gets things done on time, but on budget and safer. Check it out
[/docs]
permanent link
Chaos, Order, and Software Development
Kevin Kelly published Out Of Control: The New Biology of Machines, Social Systems, and the Economic World in 1994.
Jim Highsmith (James A. Highsmith III), wrote Adaptive Software Development: A Collaborative Approach to Managing Complex Systems in published in 2000, before he read Extreme Programming Explained: Embrace Change by Kent Beck, published in 1999.
The book on Scrum was published in 2001, and Highsmith's
Agile Software Development Ecosystems was published in 2002.
What do these books have in common? Order (or the semblance of purpose) emerging from independent agents in situation that one might expected to be purely chaotic.
Kevin Kelly's book covers the most ground, of course, from bee hives and ant colonies, boot-strapping ecosystems, competing/cooperating agents within our brains, distributed control within robots, evolution and genetics, genetic algorithms, and so on. The theme is that order can arise "by itself" (it emerges, rather being designed up-front.)
The agile software authors are saying that a good software product can arise with a minimum of planning up-front. However, creating this order is not 'random', it arises from the constant thinking and re-thinking of the people involved through the life of the project.
Some people have objected to a lack of up-front planning or designing, making the analogy to a "hill-climbing" algorithm that gets stuck on a local maxima (getting stuck on a small hill, when the goal is a larger hill, a valley away). The difference of course, is that the hill-climbing algorithm is stupid, whereas many people are smart. People can see the big picture, and can do a little planning of refactoring to get from the current design to the desired design, even though the refactorings may temporarily go through a poor design along the way (but with all tests still passing!)
In a recent web-search, I came upon a paper written by a member of a group researching independent software agents. The paper was about how Extreme Programming is helping them write software successfully, allowing new programmers to become productive members of the team quickly, and how the process allows them to increase software re-use. That paper is here: Using Extreme Programming for Knowledge Transfer. Using XP to continue research like those described by Kevin Kelly... I don't have my copy of XPExplained or Adaptive Software Development handy, but I would expect Kelly's book, or books he references, to be referenced in the bibliography of Kent's and Highsmith's books. I enjoy feedback loops like that.
[/docs]
permanent link
Daily Standup Meetings.
Laurent Bossavit writes: I regularly hear from people who have experimented with daily meetings such as Scrum ("Daily Scrum") or XP "Stand-up meeting") recommend. With no exceptions, everyone says that such meetings are incredibly effective in getting issues solved quickly, gathering momentum within the team, etc. My experience is about the same, although I prefer brief, informal "huddles" to formal meetings.
With a three person team, I tried daily standup meetings, but didn't find them that useful, since we were co-located anyway. An attempt at doing combined standup meetings with two unrelated teams was even less useful. It seems that having a common goal and related work makes daily meetings productive. That's probably why weekly "status meetings" of unrelated teams reporting to one manager are very unproductive. Like Laurent, I prefer brief huddles whenever information needs to be shared.
[/docs]
permanent link
Do the Hard Thing
Watching the TV show Boston Public, Principal Harper was a telling a student something like "when you have a choice, pick the hard choice. Nine times out of ten, it will be the right one." That rings true.
In developing software, writing tests is hard, so XP does it all the time. Design is hard to get right, so XP does it all the time. Communicating requirements is hard, so XP does it all the time (by talking to the person playing the role of Customer.) By doing these things all the time, we make them easy.
In corporations, telling someone the truth can be hard; standing up against peer and management pressure to avoid reality can be hard. Doing the right thing, tactfully, is hard, but more rewarding than living in the hell caused by ignoring reality.
[/docs]
permanent link
Please Ignore the Elephant in Your Living Room
The subject of legacy code appears on the Test Driven Development mailing list periodically. Our advice is to use test driven development for writing new code or bug fixes, and leave the rest of the legacy code alone, writing tests for old code only when you need the support for refactoring.
David Brady, on that mailing list, writes: "being behind schedule with 250,000 lines of monolithic, untested, difficult-to-test code is the PERFECT time to start learning how to test. You just have to ease into it one step at a time and be prepared for a long journey." My emphasis on the "one step at a time".
[/docs]
permanent link
Technical Reviews, More on Test Driven Design
Scott's essay on TDD is up here and Ron Jeffries's critique is there. I'll have more to say about it after reading it a couple of times.
That recent issue of STQE Magazine also has a great short essay by Jerry Weinberg on technical reviews being a learning accelerator. One thing I want to point out is that junior programmers should be reviewing the work of master programmers, not necessarily to find errors, but to learn from the master - and of course, master programmers can make mistakes too, which are often visible to junior programmers as well as other master programmers. If the master programmer is humble, he/she can learn from a junior programmer, too.
I've been reading Weinberg and Freedman's book on the subject of technical reviews Handbook of Walkthroughs, Inspections and Technical Reviews (which was written in FAQ style - question/answer), and was a bit surprised by their recommendation that when people are being trained on how to technical (code) reviews, they should have some practice at conducting a review in the presence of hidden agendas.
Some examples of hidden agendas in code reviews: person A wants to impress person B. Person B wants to make person C look bad. Person C needs to go to the restroom, but doesn't want to say so. Person D is distracted by illness of his/her spouse.
Only Weinberg would write about hidden agendas in code reviews - too many writers and books on software development practices seem to assume that people act like machines.
On Weinberg's SHAPE forum, Charlie Adams wrote: "When people are getting tense about their software being reviewed, use Jerry's phrase, 'Yes, I trust your honesty, but I don't trust your
infallibility. I don't trust anyone's infallibility.' (QSM 4: page 220) In
my experience this has always calmed the atmosphere and allowed us to
examine the code rather than the developer."
While I have done code reviews, both informal and formal, I prefer pair programming. It combines reviews with collaborative design, testing, and coding. Rather than go into all the reasons why pair programming is good, I'll point you to www.pairprogramming.com and Pair Programming Illuminated.
[/docs]
permanent link
Test Driven Development is about Designing, Not Testing
In a recent issue of STQE Magazine, Joel Spolsky wrote that Test Driven Development (TDD) doesn't substitute for "normal" testing. It seems like he doesn't understand that test driven development is about low-level design, not testing. Programmer Tests are a happy (and intentional) side-effect of the design and refactoring process. It is to avoid this misunderstanding that I prefer to call TDD "Test Driven Design".
Ron Jeffries and Scott Ambler had a little spat on the Agile Modeling Mailing List about TDD,
not about whether it constitutes "design", but on how much design "up-front" it entails. Scott
started it by writing here "An important observation is that both TDD and AMDD [Agile Model-Driven Development]
are based on the idea that you should think through your design before you code. With TDD you
do so by writing tests whereas with AMDD you do so by creating diagrams or
other types of models such as Class Responsibility Collaborator (CRC) cards."
Ron replied "Does TDD suggest that you "think through your design before you code"? I
see no such thing in TDD. In TDD we write ONE test, then make it work, then
write another." [He's leaving out the refactoring step here, which is another area of design in TDD.]
Maybe Ron doesn't think writing each test is "thinking" or "designing", but I do. At the risk of being snide, I assert that each test represents more thinking than a lot of programmers do when they write code without tests. Perhaps Ron's extensive experience has made his designing unconscious.
When writing the test, you think about the API, the goal of the API, and how to verify the goal is met. That's design. Before you start writing the tests, you think about whether to extend an existing class (and its tests) or to start a new class and new tests. That's higher level design. After you write a test and make it pass, then you look to see if there is duplication or other design smells to be refactored away. Still more design. Perhaps Ron thinks this refactoring step is the only design step in TDD.
Check out Kent Beck's book: Test-Driven Development: By Example for an introduction to TDD. Unfortunately, only a very experienced (zen-master-level) programmer like Kent Beck can take the refactoring step of TDD (remove duplication) and derive all the other good design principles from that. So read Robert Martin's book Agile Software Development: Principles, Patterns, and Practices, which not only uses TDD extensively in its copious examples, but also documents design principles that every programmer should know.
[/docs]
permanent link
What a Tangled Web We Weave, When Don't Have Effective Tracking
Steve Norrie points to a recent online article by Jerry Weinberg published on CrossTalk, the Journal of Defense Software Engineering here: Destroying Communication and Control in Software Development.
I'd like to mention a few of the Extreme Programming (XP) solutions to some of the problems mentioned in this article. Be aware that XP is a light-weight process, relying on people rather than technology to do the right thing. (A savvy person can undermine technology anyway.)
Requirements. One of the first areas that communication can be destroyed is by not doing requirements well... not involving the customer, thinking that requirements are a waste of time, and so on. Extreme Programming recommends involving the customer, or a qualified representative of the customer, throughout the entire project. And in addition to talking about the requirements often and in detail, XP requires writing the requirements down in an executable form - automated acceptance tests.
The configuration management system (CMS). The CMS tracks requirements, design, code, test data, test results, user documentation, etc. Jerry notes that information in the CMS can be undermined by failing to keep it up to date, restricting read-access from people who should have access, removing data or failing to put data into it. Extreme Programming doesn't require any specific CMS system (software or otherwise) for this tracking, but does suggest using the simplest thing that actually works. For code, tests, and test data, I recommend using CVS or some other source-code-management system. For acceptance test results, many XP teams record those on a white board or poster board, updated them weekly or daily, charting them over the course of the project. XP does strongly recommend using index cards (story cards) for tracking requirements during initial and weekly planning, and also strongly recommends documenting the relationship between the automatic acceptance tests and the story cards. The person playing the Customer role, as well as the whole team, is responsible for keeping track of the stories. Many XP teams also record the stories in web-accessible ways, such as a wiki.
In regards to a bug-tracking database, some XP teams track bugs the same way as stories - index cards and acceptance tests. You might think that this won't work, but consider that several XP teams have reported that their bug rate after implementing XP dropped from hundreds per six months to around one bug per month. It helps that bugs are not usually recorded until after a story is finished, and in XP, a story is not finished until it is passing its acceptance tests - this requires conversation between the tester and coder as soon as problems are noticed during the implementation and testing of the story. When a bug is recorded, it probably indicates that an acceptance test that was passing has started failing.
Weinberg recommends that you "set and enforce a policy of complete and open information at all times." Agile processes like XP need accurate information daily. Many projects keep tracking information on poster boards and white boards, visible not only to all team members, but anyone in management who walks by. This is the "Project Progress Poster" concept that Weinberg recommends in Quality Software Management: Anticipating Change. Since in my company, few people in management walk by, we keep tracking information in our wiki web pages.
Quality Assurance. Weinberg recommends "Prevent these abuses by having quality assurance report to the highest levels of management, and not to project management." In XP, QA testers are delegates of the person playing the Customer role -- the same person who defines the requirements. QA testers should not only be implementing and running the automated acceptance tests, but also running stress tests and manual testing of the product's user interface.
Weinberg reports that testing often comes too late in the project to be useful in effective risk management. (There's a phrase in XP circles: "Doctor, it hurts when I do this..."). Don't wait until it is too late. XP requires testing to start in the first iteration of the project -- the first week. This and other XP practices enables effective risk management.
The XP solutions noted here require that project management be willing to face reality at all times. One of the quickest routes to failing with XP is to not do XP. If project management destroys information, hides it, degrades it, or inserts misleading inforation, intentionally or not, it is going to be very difficult to have a successful project, no matter what the methodology used.
[/docs]
permanent link
Writer Ferrets by Richard Bach
The Ferret Chronicles : Writer Ferrets: Chasing The Muse, by Richard Bach. Quite a delightful little book about writing, publishing and writer's block. Satisfying while reading, but less satisfying in retrospect. I'll be reading the other Ferrets books as I find them. It makes me wonder how much of the book is autobiographical... but not enough to ask the author and possibly get a disappointing answer. Does anyone have a translation of the runes before and after the title page?
[/docs]
permanent link
Fun in the Workplace
I read some years ago in the book A Great Place to Work that a good company allows people to not "be a part of the family" -- it's ok if the workplace is "just a job" -- though I hope it's a job done well.
I don't play pool or foosball at my office; I'm not in the company softball team; and while I wanted to get together with the radio-control-car guys, I was too busy and didn't want my rc-car to get muddy. My wife is still recovering from playing in a softball game for her office a week or more ago.
My preference for "fun" at the office would be people getting together to learn about software methods, design, and so on (topics I plan to write about in this blog). Getting a group of coworkers together to ride go-carts is not my idea of fun.
It appears that some people in Germany are blaming their dot-com collapse on "fun" in the workplace. Noted in Laurent Bossavit's blog pointing to article on Mair's End The Fun.
Mair's office rules seem to have gone too far in the other direction - uniforms required, no calendars or pictures on the walls, half-hour lunches. And this is in an advertising agency?!
I fail to see how uniforms get creative work done better or faster. Doesn't anyone blame to dot-com crash on bad business plans, profit-mongering brokers, and credulous investors?
A Great Place to Work says that the core truth of what makes a company successful, is mutual trust between employees and management. Quoting the preface: [a great place to work] requires the direct involvement of senior management who must insist that fostering an exceptional work environment is an explicit goal of the organization - one that is on a par with other explicit goals like making a profit or providing high-quality products or services. Being a great place to work cannot be a fad of the month or it will rightfully appear to employees as another version of management by manipulation.
[/docs]
permanent link
Nothing like a little bit of insomnia for allowing me some time to write.
This is a test of the Blosxom blogging system. If this had been an actual emergency, I would not be sitting here at a computer running a test.
A few weeks ago, around 5 am, I wrote a short essay on the "secret of agile software development", mentioned it on the AYE wiki, got feedback on it from two people and did two more drafts within the next few hours. By the time a third person reviewed it, it was pretty much in final form. It's great having "instant collaboration" like that.
I sent that to a magazine to hopefully be published, but so far I haven't heard back on it. In this day of email, I would hope to get an semi-automatic acknowledgement, if not an actual response, within a few days... but I guess computer-related magazines are not necessarily all that automated. If month goes by, and I still don't hear back, I'll accept Esther Derby's invitaton to publish the essay on the AYE wiki.
[/docs]
permanent link