Writing is an exercise in many frustrations and rewards. Even after spending a year and a half on this book (off and on--I had several spots of three months or so of inactivity), it's nowhere near as clean as I'd like. But at some point you learn what is "good enough," and you learn how to let it go. Much like software. Ship it!
Once your material is shipped, the reality of "good enough" sets in. Inevitably there are defects. One of my wonderful reviewers already spotted two such problems in the exercises (which were specified by Jeff Bay of ThoughtWorks, who did a great job) that I hastily coded.
You learn to build a thick skin. Tempering the excitement of waiting to see something published is the trepidation about things like savage Amazon and Slashdot reviews. Recommendation: don't publish unless you can handle it. "This is the stupidest thing I've ever read," "don't waste your money," and so on. It only takes one bad review out of 20 to ruin your day and make you wish you had Amazon censorship privileges.
But ultimately it's an extremely satisfying and exciting adventure: from opening the box of copies sent to you and smelling the fresh ink, to watching Amazon ranks go up (and down!) and getting a 5-star review. Now if I could only make a true living of it.
I'm not overly fond of metaphors. They're never perfect and are usually abused.
One metaphor for refactoring is dirty dishes. The person who chooses not to clean his dishes as he goes finds himself with a growing, dirty pile of dishes. At some point, presumably, the developer runs out of dishes and can no longer eat.
It's an adequate metaphor. Refactoring is something you should do constantly, a little bit each time you touch code. Do a meal, wash the dishes for the meal. Your likelihood to throw up your arms in disgust at a huge stack of dishes diminishes.
There are problems, however, with the metaphor. If you don't refactor your code, it becomes exponentially more difficult to introduce new changes without the possibility of causing problems. Also, companies know they can get away with buying cheap dishes, perhaps even paper or plastic, instead of wasting their time cleaning them. Some companies will throw away expensive china if it's gotten too dirty. And all companies know that there are a lot of places to leave the dirty dishes lying around.
A Jiffy Lube mechanic, on the other hand, works in a pit of fairly limited size. He changes oil frequently (let's imagine that a car represents a task on a project). The mechanic can choose to ignore the oil oozings that drip onto the floor. Or, he can take the extra time to clean it up with each oil change.
If the mechanic chooses to ignore the dirty liquid, it begins to build up on the floor. At first, things are a little slippery and a bit of a nuisance. In a short amount of time, perhaps a day or two, the mechanic begins to fall down on the job, taking a bit longer to complete each oil change.
You know where this is going, of course. It gets exponentially worse and worse; soon the mechanic swims against the black filthy tide, and can do one oil change a day if he works hard enough. Finally, the mechanic just drowns, never to change a filter again.
XP or no XP, test-driven development or no test-driven development, programming or something else, all systems have entropy. All systems turn crufty and ultimately become useless. The promise of XP is to allow you to sustain that system for a longer period of time before the costs become too high. This is the hope for any system. Constant, hardcore refactoring at the micro level is essential for this to happen. Don't let the code drown you!
In posting messages about the new for-each loop syntax in Java 5.0, many developers have complained about its crypticism. A for-each loop might look like:
for (Employee employee: department) terminate(employee);You would read this for-each loop as, "for each employee (of type Employee) in department)." Many developers would have preferred something like:
for (Employee employee in department) terminate(employee);But alas, Sun resists new Java keywords like "in" because they have the potential to break gobs of existing code.
It's not that big a deal to me, since I view the loop construct as idiomatic. Once I saw it and it was explained to me, or perhaps twice, it became ingrained. Subsequent encounters required no such explanation or even translation time.
Nonetheless, the new for-each loop is a slightly cryptic construct. Not quite as bad as the ternary operator (conditional ? true-value : false-value), but still not obvious the first time. Some developers can't stand it.
My take is that Java is a fairly cryptic language to start with, particularly if you have no background in C-based languages (C, C++, Objective C, C#, and whatever else). The old C-style for loop isn't obvious either. Typical C code is rife with odd characters such as *, %, &, {, }, and |.
This obvious observation led me to create Jeff's hypothesis of cryptics:
Jeff's Hypothesis of Cryptics: The crypticism of a language is directly proportional to the mean number of shift keystrokes required.
It's a pretty useless hypothesis, granted. But taking a look at a couple languages that appear on opposite ends of the spectrum shows that there is some validity. Curly braces in C-based languages { use the shift key, as does * (pointer dereference). The new generics stuff in 1.5 uses angle brackets < and >, both requiring use of shift. The tertiary operator uses both : and ?. Strings are set off by use of the " character. And C uses lots of parentheses.
Smalltalk, in contrast, uses brackets ([ and ]) to set off blocks. No shift-combination necessary! Boolean operators are spelled out instead of using & and |. Strings are set off by use of the ' character. The major exception to the rule is the use of the colon to designate a selector (but this also suggests that perhaps you should pass fewer parameters to your methods).
Of course, crypticism is related to how easy it is to read text, not write it. But it's no coincidence that the cryptics require shift-combinations on a standard keyboard or typewriter. These are the characters that make things difficult to read when used to excess.
I was curious enough to pose the idea to Dan Ingalls, who had a lot to do with the design of early Smalltalk implementations. He indicated that indeed there was a conscious effort to reduce the number of shift keystrokes required. This was due to the fact that one goal for Smalltalk was that children would be able to program in it.
Lots of shift-key combinations = lots of crypticism. I'm still amazed at the fact that modern languages retain so much of the unnecessary constructs and ugliness of a language that is 30 years old.
February 2004 March 2004 May 2004 September 2004 October 2004 January 2005 February 2005 September 2005 October 2005 November 2005 December 2005 January 2006 February 2006 March 2006 June 2006 August 2006 January 2007 February 2007 March 2007 April 2007 September 2007 October 2007 November 2007 December 2007 January 2008