<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Object Mentor Blog: Category Software Craftsmanship</title>
    <link>http://blog.objectmentor.com/articles/category/software-craftsmanship</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Sufficient Design means Damned Good Design.</title>
      <description>&lt;p&gt;@JoshuaKerievsky wrote a &lt;a href="https://elearning.industriallogic.com/gh/submit?Action=PageAction&amp;#38;album=blog2009&amp;#38;path=blog2009/2010/sufficientDesign&amp;#38;devLanguage=Java"&gt;blog&lt;/a&gt; entitled &amp;#8220;Sufficient Design&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;Josh makes this point:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;&amp;#8216;Yet some programmers argue that the software design quality of every last piece of code ought to be as high as possible. &amp;#8220;Produce clean code or you are not a software craftsman!&amp;#8221;&amp;#8217;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;He goes on to say:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;&amp;#8220;Yet ultimately the craftsmanship advice fails to consider simple economics: If you take the time to craft code of little or moderate value to users, you&amp;#8217;re wasting time and money.&amp;#8221;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Now this sounds like heresy, and I can imagine that software craftsmanship supporters (like me) are ready to storm the halls of Industrial Logic and string the blighter up by his toenails!&lt;/p&gt;


	&lt;p&gt;But hold on there craftsmen, don&amp;#8217;t get the pitchforks out yet. Look at the scenario that Josh describes.  It&amp;#8217;s quite revealing.&lt;/p&gt;


	&lt;p&gt;Josh&amp;#8217;s example of &amp;#8220;not being a craftsman&amp;#8221; is his niggling worry over a function that returns a string but in one derivative case ought to return a void.&lt;/p&gt;


	&lt;p&gt;Horrors!  Horrors!  He left a bit of evolved cruft in the design!  Revoke his craftsman license and sick the dogs on him!&lt;/p&gt;


	&lt;p&gt;Ah, but wait.  He also says that he spent a half-day trying to refactor this into a better shape but eventually had to give up.&lt;/p&gt;


	&lt;p&gt;The fool!  The nincompoop!  The anti-craftsman!  A pox on him and all his ilk!&lt;/p&gt;


&lt;hr&gt;

	&lt;p&gt;OK, enough hyperbole.  It seems to me that Josh was behaving exactly as a craftsman should.  He was worrying about exactly the kinds of things a craftsman ought to worry about.  He was making the kinds of pragmatic decisions a craftsman ought to make.  He was not leaving a huge mess in the system and rushing on to the next feature to implement.  Instead he was taking care of his code.  The fact that he put so much energy, time, and thought into such a small issue as an inconsistent return type speaks volumes for Josh&amp;#8217;s integrity as a software craftsman.&lt;/p&gt;


	&lt;p&gt;So, as far as Josh Kerievsky is concerned &amp;#8220;Sufficient Design&amp;#8221; is &amp;#8220;Pretty Damned Good Design&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;Look, all our software will have little tiny warts.  There&amp;#8217;s no such thing as a perfect system.  Craftsmen like Josh work hard to keep those warts as small as possible, and to sequester them into parts of the system where they can do the least harm.&lt;/p&gt;


	&lt;p&gt;So the only aspect of Josh&amp;#8217;s post that I disagree with is his contention that the &amp;#8220;craftsman&amp;#8221; message is one of unrelenting perfection.  Craftsmen are first and foremost pragmatists.  They seek very high quality code; but they are not so consumed with perfection that they make foolish economic tradeoffs.&lt;/p&gt;</description>
      <pubDate>Wed, 28 Apr 2010 18:02:10 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:7af1f4ce-c8d6-40c7-aa72-57d9c40f32be</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2010/04/28/sufficient-design-means-damned-good-design</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
    </item>
    <item>
      <title>Sapient Testing: The &amp;quot;Professionalism&amp;quot; meme.</title>
      <description>&lt;p&gt;James Bach gave a stirring keynote today at &lt;span class="caps"&gt;ACCU 2010&lt;/span&gt;.  He described a vision of testing that our industry sorely needs.  Towit: Testing requires sapience.&lt;/p&gt;


	&lt;p&gt;Testing, according to Bach, is not about assuring conformance to requirements; rather it is about &lt;em&gt;understanding&lt;/em&gt; the requirements.  Even that&amp;#8217;s not quite right.  It is not sufficient to simply understand and verify the requirements.  A good tester uses the behavior of the system and the descriptions in the requirements, (and face-to-face interaction with the authors of both) to &lt;em&gt;understand the motivation behind the system&lt;/em&gt;.  Ultimately it is the tester&amp;#8217;s job to divine the system that the customer &lt;em&gt;imagined&lt;/em&gt;; and then to illuminate those parts of the system that are not consistent with that imagination.&lt;/p&gt;


	&lt;p&gt;It seems to me that James is attempting to define &amp;#8220;professionalism&amp;#8221; as it applies to testing.  A professional tester does not blindly follow a test plan.  A professional tester does not simply write test plans that reflect the stated requirements.  Rather a professional tester takes responsibility for &lt;em&gt;interpreting&lt;/em&gt; the requirements with intelligence.  He tests, not only the system, but also (and more importantly) the assumptions of the programmers, and specifiers.&lt;/p&gt;


	&lt;p&gt;I like this view.  I like it a lot.  I like the fact that testers are seeking professionalism in the same way that developer are.  I like the fact that testing is becoming a &lt;em&gt;craft&lt;/em&gt;, and that people like James are passionate about that craft.  There may yet be hope for our industry!&lt;/p&gt;


	&lt;p&gt;There has been a long standing frission between James&amp;#8217; view of testing and the Agile emphasis on &lt;span class="caps"&gt;TDD&lt;/span&gt; and automated tests.  Agilists have been very focussed on creating suites of automated tests, and exposing the insanity (and inanity) of huge manual testing suites.  This focus can be (and has been) misinterpreted as an &lt;em&gt;anti-tester&lt;/em&gt; bias.&lt;/p&gt;


	&lt;p&gt;It seems to me that professional testers are completely compatible with agile development.  No, that&amp;#8217;s wrong.  I think professional testers are &lt;em&gt;utterly essential&lt;/em&gt; to agile development. I don&amp;#8217;t want testers who rotely execute brain-dead manual test plans.  I want testers &lt;em&gt;using their brains&lt;/em&gt;!  I want testers to be partners in the effort to create world-class, high-quality software.  As a professional developer I want &amp;#8211; I need &amp;#8211; professional testers helping me find my blind spots, illuminating the naivete of my assumptions, and partnering with me to satisfy the needs of our customers.&lt;/p&gt;</description>
      <pubDate>Thu, 15 Apr 2010 06:18:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:b9343975-d80a-4e70-86ef-41a3c95ec5fd</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2010/04/15/sapient-testing-the-professionalism-meme</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Agile Methods</category>
    </item>
    <item>
      <title>Saying &amp;quot;NO&amp;quot;.</title>
      <description>&lt;p&gt;I saw &lt;a href="http://theoatmeal.com/comics/design_hell"&gt;this cartoon&lt;/a&gt; in a tweet today. It&amp;#8217;s the story of how a boss corrupts the work of a professional.  It&amp;#8217;s a funny cartoon, and a sad story that happens all too often in our profession.  But who, exactly, was at fault?...&lt;/p&gt;


	&lt;p&gt;The difference between a laborer and a professional is that a laborer takes orders from his boss, and a professional provides input to his superiors.  Laborers are hired to take direction.  Professionals are hired to ensure that the direction chosen makes sense.&lt;/p&gt;


	&lt;p&gt;Imagine this conversation between a patient and a doctor:&lt;/p&gt;


	&lt;p&gt;Patient: &lt;em&gt;&amp;#8220;My arm hurts.&amp;#8221;&lt;/em&gt;
Doctor:  &lt;em&gt;&amp;#8220;What would you like me to do about it?&amp;#8221;&lt;/em&gt;
Patient: &lt;em&gt;&amp;#8220;Make my arm stop hurting.&amp;#8221;&lt;/em&gt;
Doctor:  &lt;em&gt;&amp;#8220;Do you want me to cut it off?, I can do that.&amp;#8221;&lt;/em&gt;
Patient: &lt;em&gt;&amp;#8220;No, I just want it to stop hurting.&amp;#8221;&lt;/em&gt;
Doctor:  &lt;em&gt;&amp;#8220;I could cut all the nerves to your arm.  That&amp;#8217;ll stop it.&amp;#8221;&lt;/em&gt;
Patient: &lt;em&gt;&amp;#8220;Isn&amp;#8217;t there something less drastic you could do?&amp;#8221;&lt;/em&gt;
Doctor:  &lt;em&gt;&amp;#8220;Ooops, sorry, time for my break.&amp;#8221;&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;Clearly we don&amp;#8217;t expect doctors to behave this way.  Even though the patient is the boss, the patient expects the doctor to have the answers and help set the direction.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s another version of the conversation:&lt;/p&gt;


	&lt;p&gt;Patient:  &lt;em&gt;&amp;#8220;I want you to cut my arm off.&amp;#8221;&lt;/em&gt;
Doctor:   &lt;em&gt;&amp;#8220;What&amp;#8217;s wrong with your arm?&amp;#8221;&lt;/em&gt;
Patient:  &lt;em&gt;&amp;#8220;It hurts.  I&amp;#8217;m tired of it.  Just cut it off.&amp;#8221;&lt;/em&gt;
Doctor:   &lt;em&gt;&amp;#8220;Let me see your arm.  Hmmm.  Looks like you&amp;#8217;ve got a sprain or perhaps a hairline fracture.  We should take some X-Rays.&amp;#8221;&lt;/em&gt;
Patient:  &lt;em&gt;&amp;#8220;No, just cut it off.&amp;#8221;&lt;/em&gt;
Doctor:   &lt;em&gt;&amp;#8220;Sir, I do not cut off healthy arms.&amp;#8221;&lt;/em&gt;
Patient:  &lt;em&gt;&amp;#8220;But I&amp;#8217;m paying you.  You have to do what I say!&amp;#8221;&lt;/em&gt;
Doctor:   &lt;em&gt;&amp;#8220;No, sir, I don&amp;#8217;t.  Cutting off your arm would violate my oath.&amp;#8221;&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;Which of these two doctors would you rather be?  Now project these two doctors into your own profession, and which would you rather be?&lt;/p&gt;


	&lt;p&gt;Programmers are professionals.  They know more about designing and implementing software systems than their bosses do.  Indeed, they are hired for this knowledge and expertise.  And they have a solemn duty to prevent their managers from doing things that would be harmful.&lt;/p&gt;


	&lt;p&gt;All this boils down to one simple thing.  Professionals are willing to say &amp;#8220;No&amp;#8221;.   When their managers come to them with direction that makes no sense, a professional programmer will refuse the direction.&lt;/p&gt;


	&lt;p&gt;Is this risky?  Sure.  But part of being a professional is the willingness to stand on principle.  There are lines that a professional will not cross.&lt;/p&gt;


	&lt;p&gt;Of course saying &amp;#8220;No.&amp;#8221; is only one side of the coin.  Professionals are also expected to explain their positions, and come up with viable alternatives.  Professionals &lt;em&gt;negotiate&lt;/em&gt; with their superiors until both parties are satisfied with the chosen direction.&lt;/p&gt;


	&lt;p&gt;The poor web-designer schmuck in that cartoon was not behaving as a professional.  He was behaving as a laborer.  The fiasco at the end was &lt;em&gt;his&lt;/em&gt; fault.  He should have said &amp;#8220;No.&amp;#8221; and started a &lt;em&gt;negotiation&lt;/em&gt; with his customer instead of just doing everything the customer said.&lt;/p&gt;


	&lt;p&gt;The cartoonist painted the web-designer as a wise but impotent victim, and the boss as the overbearing dufus.  The reality is that the web-designer took the role of the victim voluntarily and shirked his responsibility to refuse direction that he considered harmful.&lt;/p&gt;


	&lt;p&gt;If you are a professional, you &lt;em&gt;never&lt;/em&gt; allow yourself to be put in the role of the victim.&lt;/p&gt;</description>
      <pubDate>Fri, 04 Dec 2009 08:35:55 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:1c488f0e-912e-47c9-86b9-8333cfa3e7a1</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/12/04/saying-no</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
    </item>
    <item>
      <title>What's all this nonsense about Katas?</title>
      <description>&lt;p&gt;There has been an increase in interest in Software Katas of late.  What is all this buzz about, and why might it be important?&lt;/p&gt;


	&lt;p&gt;Several years ago (Pragmatic) Dave Thomas started a special &lt;a href="http://codekata.pragprog.com/"&gt;blog&lt;/a&gt; about coding katas.  The idea was simple: Professionals practice.&lt;/p&gt;


	&lt;p&gt;This thought might not have occurred to you before; but it&amp;#8217;s self-evidently true.  Professional musicians practice.  Professional dancers practice.  Doctors practice.  Soldiers practice.  Indeed, any kind of professional craftsman or artisan must practice their adopted trade in order to execute it well when it counts.&lt;/p&gt;


	&lt;p&gt;Dave&amp;#8217;s point was that professional programmers need to practice like any other professional.  He set forth a number of simple exercises and problems that programmers could solve during their practice time.  He also suggested that practice time needs to be scheduled and protected as part of the normal routine of a software developer.&lt;/p&gt;


	&lt;p&gt;At &lt;span class="caps"&gt;XP2005&lt;/span&gt; in Shefield, UK,  I attended Laurent Bossavit&amp;#8217;s and Emmanuel Gaillot&amp;#8217;s &lt;em&gt;Coding Dojo&lt;/em&gt; session.  I &lt;a href="http://butunclebob.com/ArticleS.UncleBob.TheProgrammingDojo"&gt;blogged&lt;/a&gt; about it at the time.  I left that session with a different view of what a Kata might be. In Dave Thomas&amp;#8217; view a kata is an exercise to solve.  Each time you solve it you try a different approach.  Dave&amp;#8217;s notion is that a kata is a way to explore the solution space of a problem. But in Martial arts a kata is something different; it is a set of motions that one memorizes in minute detail.  A martial arts kata is a &lt;em&gt;precisely executed dance&lt;/em&gt;.  I left Sheffield with the idea that a coding kata could be more like a martial arts kata.&lt;/p&gt;


	&lt;p&gt;About a year ago, &lt;a href="http://www.coreyhaines.com/"&gt;Corey Haines&lt;/a&gt; (our wandering minstrel of code) stopped by and told me about some mini-conferences that had adopted the notion of coding kata.  What he described sounded more like a group dance than a bunch of people independently solving a given problem.  This got me thinking.  So at the next Software Craftsmanship meeting at &lt;a href="http://www.8thlight.com/"&gt;8th Light&lt;/a&gt; (Which, not coincidentally, takes it&amp;#8217;s name from a martial arts philosophy) I conducted &lt;a href="http://www.vimeo.com/2499161"&gt;a simple kata session in dojo style&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;I, acting as the Sen Sei, had everyone file in to the room as they would to a dojo.  I had them put their &lt;a href="http://cleancodeproject.com"&gt;green bands&lt;/a&gt; on their wrists (mine was black!).  I bade them to sit, and then gestured for silence.  For the next 15 minutes I led them through the &lt;a href="http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata"&gt;Prime Factors Kata in Java&lt;/a&gt; without uttering a word (well, almost).  I would write a simple test case, then gesture for them to do the same.  Then I would make the test pass, and again gesture for them to repeat my moves.&lt;/p&gt;


	&lt;p&gt;Then, this Fall, I attended &lt;a href="http://agile2009.agilealliance.org/programmingwiththestars"&gt;Programming with the Stars&lt;/a&gt; at Agile 2009.  As I watched the contestants perform their programming sessions, I realized that they were not simply demonstrating programming prowess; indeed they were competing in how well they &lt;em&gt;performed&lt;/em&gt; their session.  That&amp;#8217;s when it struck me.  This was a &lt;em&gt;performance art!&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;It seems absurd to think of programming as a performance art.  And yet watching those people up on stage working through routines that they had clearly practiced over and over again, was &lt;em&gt;delightfully entertaining&lt;/em&gt; to me, and to the crowd.  There were cheers and applause when a performing pair did something especially well.  There was laughter when a pair executed a clever joke in code, or in behavior.  For programmers, watching other programmers perform well practiced routines was &lt;em&gt;fun!&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;Now I had seen martial arts katas executed as performance art during competitions.  Indeed, it is a beautiful thing to watch a skilled and well practiced martial artist peform a kata.  And that started me thinking.  Why would a martial artist practice these forms so intensely that they could be performed as an art?&lt;/p&gt;


	&lt;p&gt;The goal of martial arts is not to perform on stage.  The goal of martial arts is self defense!  And yet, when a martial artist is at the peak of his skill, his practice takes on the quality of a performance art.  When you watch a skilled martial artist perform, you &lt;em&gt;know&lt;/em&gt; you don&amp;#8217;t want to fight him.  The performance is a demonstration, and a realization, of mastery.&lt;/p&gt;


	&lt;p&gt;And yet the performance is not the goal.  No martial artist practices his art so that they can perform on stage.  A martial artist practices to achieve personal perfection in the art of self defense.  The fact that the practice can be performed is a (pleasant) side effect.&lt;/p&gt;


	&lt;p&gt;Could it be that these coding kata that we&amp;#8217;ve been dabbling with for the last few years could be &lt;em&gt;performed&lt;/em&gt;?  Is there a benefit to practicing them so much that performance is an option?  Is there really any reason for a programmer to create and then memorize a routine down to the level of individual keystrokes?  Is there profit to be gained from practicing that routine so thoroughly that you can do it at high speed with virtually no errors?  This August I decided to find out.&lt;/p&gt;


	&lt;p&gt;I started with the Prime Factors Kata in Java, and set it to music inspired by &lt;a href="http://www.youtube.com/watch?v=SV6ScA9rc1E"&gt;this video of dancing kites&lt;/a&gt;.  The piece is about 4 minutes long, and I figured I&amp;#8217;d need about twice that, so I found two different version of the music and played them back to back.  But working in Java is ponderous, and I could not complete the kata before the two pieces had finished.  So I switched to Ruby.  Using Ruby and Rspec I was able to finish the Kata with plenty of time to spare.&lt;/p&gt;


	&lt;p&gt;Thereupon began an evolution.  Since I had time, I added more features to the kata.  As I improved in my practice I found I had even more time, so I added even more features.  I refined and polished.  I refactored my refactorings.  I trimmed keystrokes, and learned many new keyboard shortcuts in the process. I completely abandoned the mouse; and then later reacquired it for flourishes and highlights (but never for actual coding).&lt;/p&gt;


	&lt;p&gt;Week after week, I set aside 30 minutes or so every day to practice, and practice, and practice&amp;#8212;just the way I used to practice my Jiu Jitsu Katas.  I would practice on airplanes while flying to clients.  I would practice in bed with my laptop in my lap.  I would practice late at night in hotel rooms after a long day consulting for clients.  I would practice early in the morning before shower and breakfast.  And the practice started to pay off.&lt;/p&gt;


	&lt;p&gt;Ten weeks later I finally decided I was ready to create a screencast.  I reduced my screen resolution to 1024X768.  I configured &lt;a href="http://www.ambrosiasw.com/utilities/snapzprox"&gt;SnapZ ProX&lt;/a&gt; to record the whole screen at 80% size.  And I began to record.&lt;/p&gt;


	&lt;p&gt;Performing a coding kata in time to music is a &lt;em&gt;very difficult thing to do&lt;/em&gt;.  Maintaining the timeline is &lt;em&gt;critical&lt;/em&gt;.  There are very few errors that you can effectively recover from.  If you miss a stroke, the whole sequence melts down.  And melt down it did.  Over and over and over again.  I spent weeks trying to record a reasonably good session.  I must have done hundreds of takes.  It was &lt;em&gt;very&lt;/em&gt; frustrating.&lt;/p&gt;


	&lt;p&gt;But day by day I got better and better at it.  Finally, after weeks of trying, I got what I consider to be a recording that, though not perfect, is good enough to present.  You can watch that recording &lt;a href="http://katas.softwarecraftsmanship.org/?p=71"&gt;here&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Has this paid off in the regular programming I do?  I think it has.  My mouse usage is much less than it used to be.  I know a much larger number of keyboard shortcuts than I used to, and I can use them almost instinctively.  My typing and accuracy have improved quite a bit, and I now type more punctuation and number keys without looking.  So, yes, I think the effort has paid off; though I&amp;#8217;m not at all sure the payoff compensates for the effort.&lt;/p&gt;


	&lt;p&gt;But something else compensates for the effort.  Making this recording was &lt;em&gt;fun&lt;/em&gt;&amp;#8212;it was a &lt;em&gt;lot of fun&lt;/em&gt;.  And that&amp;#8217;s probably the real answer to the question posed in the title of this blog.&lt;/p&gt;</description>
      <pubDate>Sat, 21 Nov 2009 04:32:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:b1c40077-fac6-4dd9-bc7f-0f988f020569</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/11/21/whats-all-this-nonsense-about-katas</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
    </item>
    <item>
      <title>Archeological Dig</title>
      <description>&lt;p&gt;I was going through some old files today, and I stumbled upon some acetate slides from 1995.  They were entitled: &amp;#8220;Managing OO Projects&amp;#8221;.  Wow!  What a difference fifteen years makes!   (Or does it?) ...&lt;/p&gt;


	&lt;p&gt;In 1995-99 I was frequently asked to speak to managers about what a transition to OO (usually from C to C++) would do for (or to) them.  I would spend a half day to a day going over the issues, costs, and benefits.&lt;/p&gt;


	&lt;p&gt;One part of that talk (usually about 90 min) was a discussion about software process.  It was the process part of the talk that those acetate slides that I found described.&lt;/p&gt;


	&lt;p&gt;1995 was during the ascendency of Waterfall.  Waterfall thinking was king. &lt;span class="caps"&gt;RUP&lt;/span&gt; had not yet been conceived as an acronym.  And though Booch was beating the drum for incrementalism, most people (even many within Rational) were thinking in terms of six to eighteen month waterfalls.&lt;/p&gt;


	&lt;p&gt;So, &lt;a href="http://butunclebob.com/files/unclebob/Managing%20OO%20Projects.pdf"&gt;here&lt;/a&gt; are the slides that I uncovered deep within an old filing cabinet.  I scanned them in.  They were produced on a Macintosh using the old &amp;#8220;More&amp;#8221; program.  (Where is that program now?  It was &lt;em&gt;so&lt;/em&gt; good.)&lt;/p&gt;


Go ahead and read them now.  Then come back here and continue&amp;#8230;
&lt;hr&gt;
What struck me about those slides was the consistency of the message with today.  It was all about iterative development.  Small iterations (though I never deigned to define the length in the slides, I frequently told people 2 weeks), measured results, etc. etc.  Any Agile evangelist could use those slides today.  He or she would have to dance quickly around a few statements, but overall the message has not shifted very much.

	&lt;p&gt;What&amp;#8217;s even more interesting is the coupling between the process, and OO.  The slides talk a lot about dependency management and dependency structure.  There are hints of the &lt;span class="caps"&gt;SOLID&lt;/span&gt; principles contained in those slides.  (Indeed several of the principles had already been identified by that time.)  This coupling between process and software structure was a harbinger of the current craftsmanship/clean-code movement.&lt;/p&gt;


	&lt;p&gt;Of course the one glaring omission from these slides is &lt;span class="caps"&gt;TDD&lt;/span&gt;.  That makes me think that &lt;span class="caps"&gt;TDD&lt;/span&gt; was the true catalyst of change, and the bridge that conveyed our industry from then to now.&lt;/p&gt;


	&lt;p&gt;Anyway, I guess the more things change, the more they stay the same.&lt;/p&gt;


	&lt;p&gt;Comments please!&lt;/p&gt;</description>
      <pubDate>Wed, 11 Nov 2009 10:39:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:2719dd93-f02d-4cbb-9850-265f68fbfb65</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/11/11/archeological-dig</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Agile Methods</category>
      <category>Design Principles</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>We must ship now and deal with consequences</title>
      <description>&lt;p&gt;Martin Fowler has written a good &lt;a href="http://martinfowler.com/bliki/TechnicalDebtQuadrant.html"&gt;blog&lt;/a&gt; about technical debt.  He suggests that there are two axes of debt: &lt;em&gt;deliberate&lt;/em&gt; and &lt;em&gt;prudent&lt;/em&gt;.  This creates four quadrants: &lt;em&gt;deliberate-prudent&lt;/em&gt;, &lt;em&gt;deliberate-imprudent&lt;/em&gt;, &lt;em&gt;inadvertent-prudent&lt;/em&gt;, and &lt;em&gt;inadvertent-imprudent&lt;/em&gt;.  I agree with just about everything in his blog except for one particular caption&amp;#8230;&lt;/p&gt;


	&lt;h2&gt;Inadvertent-Imprudent Debt.&lt;/h2&gt;


	&lt;p&gt;There is more of this debt than any other kind.  It is all too common that software developers create a mess and don&amp;#8217;t know they are doing it.  They have not developed a nose that identifies code smells.  They don&amp;#8217;t know design principles, or design patterns.  They think that the reek of rotten code is normal, and don&amp;#8217;t even identify it as smelling bad.  They think that their slow pace through the thick morass of tangled code is the norm, and have no idea they could move faster.  These people destroy projects and bring whole companies to their knees.  Their name is &lt;em&gt;Doom&lt;/em&gt;.&lt;/p&gt;


	&lt;h2&gt;Deliberate-Imprudent Debt.&lt;/h2&gt;


	&lt;p&gt;There is a meme in our industry (call it the DI meme) that tells young software developers that rushing to the finish line at all costs is the right thing to do.  This is far worse than the ignorance of the first group because these folks &lt;em&gt;willfully&lt;/em&gt; create debt without counting the cost.  Worse, this meme is contagious.  People who are infected with it tend to infect others, causing an epidemic of deliberately imprudent debtors (sound familiar?) The end result, as we are now all know, is economic catastrophe, inflation (of estimates) and crushing interest (maintenance) payments.  They have become death, the destroyer of worlds.&lt;/p&gt;


	&lt;h2&gt;Inadvertent-Prudent Debt.&lt;/h2&gt;


	&lt;p&gt;This is something of an oxymoron.  Ironically, it is also the best of all possible states.  The fact is that no matter how careful we are, there is always a better solution that we will stumble upon later.  How many times have you finished a system only to realize that if you wrote it again, you&amp;#8217;d do it very differently, and much better?&lt;/p&gt;


	&lt;p&gt;The result is that we are always creating a debt, because our hindsight will always show us a better option after it is too late.  So even the best outcome still leaves us owing.  (Mother Earth will eventually collect that debt!)&lt;/p&gt;


	&lt;h2&gt;Deliberate-Prudent Debt.&lt;/h2&gt;


	&lt;p&gt;This is the quadrant that I have the biggest problem with.  And it is this quadrant in which Martin uses the caption I don&amp;#8217;t like.  The Caption is: &lt;em&gt;&amp;#8220;We must ship now and deal with consequences.&amp;#8221;&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;Does this happen?  Yes.  &lt;em&gt;Should&lt;/em&gt; it happen?  Rarely, yes.  But it damned well better not happen very often, and it damned well better not happen out of some misplaced urge to get done without counting the cost.&lt;/p&gt;


	&lt;p&gt;The problem I have with this quadrant (DP) is that people who are really in quadrant DI &lt;em&gt;think&lt;/em&gt; they are in DP, and use words such as those that appear in the caption as an excuse to rack up a huge imprudent debt.&lt;/p&gt;


	&lt;p&gt;The real issue is the definition of the word: &lt;em&gt;Imprudent&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;So let me ask you a question.  How prudent is debt?  There is a very simple formula for determining whether debt is prudent or imprudent.  You can use this formula in real life, in business, and in programming.  The formula is:  Does the debt increase your net worth, and can you make the payments?&lt;/p&gt;


	&lt;p&gt;People often focus on the first criterion, without properly considering the second.  Buying a house is almost certain to increase your net worth despite the debt (though lately&amp;#8230;).  On the other hand, if you cannot make the payments, you won&amp;#8217;t keep that house for long.  The reason for our current economic woes has a lot to do with people trying to increase their net worth despite the fact that they couldn&amp;#8217;t afford the payments.  (indeed, they were encouraged by a meme very similar to the DI meme!)&lt;/p&gt;


	&lt;h2&gt;Bad code is &lt;em&gt;always&lt;/em&gt; imprudent.&lt;/h2&gt;


	&lt;p&gt;Writing bad code &lt;em&gt;never&lt;/em&gt; increases your net worth; and the interest rate is really high.  People who write bad code are like those twenty-somethings who max out all their credit cards.  Every transaction &lt;em&gt;decreases&lt;/em&gt; net worth, and has horrendous consequences for cash flow.  In the end, the vast bulk of your effort goes to paying the interest (the inevitable slow down of the team as they push the messes around).  Paying down the principle becomes infeasible. (Just the way credit card companies like it.)&lt;/p&gt;


	&lt;h2&gt;Some Suboptimal Design Decision are Prudent Debt.&lt;/h2&gt;


	&lt;p&gt;But most are not.  Every once in awhile there is a suboptimal design decision that will increase the net worth of the project by getting that project into customer&amp;#8217;s hand&amp;#8217;s early.&lt;/p&gt;


	&lt;p&gt;This is not the same as delivering software that is under-featured.  It is often prudent to increase the net worth of a project by giving customers early access to a system without a full and rich feature set.  This is not debt.  This is more like a savings account that &lt;em&gt;earns&lt;/em&gt; interest.&lt;/p&gt;


	&lt;p&gt;Indeed, this is one reason that most technical debt is imprudent.  If you are truly concerned about getting to market early, it is almost always better to do it with &lt;em&gt;fewer features&lt;/em&gt;, than with suboptimal design.  Missing features are a promise that can be kept.  Paying back suboptimal designs creates interest payments that often submerge any attempts at payback and can slow the team to the breaking point.&lt;/p&gt;


	&lt;p&gt;But there &lt;em&gt;are&lt;/em&gt; some cases where a sub-optimal design can increase your net worth by allowing you to deliver early. However, the interest rate needs to be very low, and the principle payments need to be affordable, and big enough to pay back the debt in short order.&lt;/p&gt;


	&lt;p&gt;What does a low interest rate mean?  It means that the sub-optimal design does not infiltrate every part of your system.  It means that you can put the sub-optimal design off in a corner where it doesn&amp;#8217;t impact your daily development life.&lt;/p&gt;


	&lt;p&gt;For example, I recently implemented a feature in FitNesse using &lt;span class="caps"&gt;HTML&lt;/span&gt; Frames.  This is sub-optimal.  On the other hand, the feature is constrained to one small part of the system, and it simply doesn&amp;#8217;t impact any other part of the system.  It does not impede my progress.  There is no mess for me to move around.  The interest rate is almost zero!  (nice deal if you can get it!)&lt;/p&gt;


	&lt;p&gt;Implementing that feature with ajax is a much larger project. I would have had to invest a great deal of time and effort, and would have had to restructure massive amounts of the internal code.  So the choice was a good one.&lt;/p&gt;


	&lt;p&gt;Better yet, the customer experience has pretty much been a big yawn.  I thought people would really like the feature and would drive me to expand upon it.  Instead, the customer base has virtually ignored it.&lt;/p&gt;


	&lt;p&gt;So my solution will be to pay back this debt by eliminating the feature.  It was a cheap experiment, that resulted in my &lt;em&gt;not&lt;/em&gt; having to spend a lot of time and effort on a new architecture!  Net worth indeed!&lt;/p&gt;


	&lt;p&gt;But it might have gone the other way.  My customers may have said: &amp;#8220;Wow, Great! We want more!&amp;#8221;  At that point it would have been &lt;em&gt;terrible&lt;/em&gt; to expand on the &lt;span class="caps"&gt;HTML&lt;/span&gt; Frames!  That decision would have been in the DI quadrant.  Deliberate imprudence!  Rather, my strategy would have been to replace the suboptimal Frames design of the feature with an isolated ajax implementation, and then to gradually migrate the ajax solution throughout the project.  That would have been annoying, but loan payments always are.&lt;/p&gt;


	&lt;h2&gt;Summary&lt;/h2&gt;


	&lt;p&gt;So, don&amp;#8217;t let the caption in the DP quadrant be an excuse.  Don&amp;#8217;t fall for the DI meme that says &amp;#8220;We just gotta bite the bullet&amp;#8221;.  Tread &lt;em&gt;very&lt;/em&gt; carefully when you enter the DP quadrant.  Look around at all your options, because it&amp;#8217;s easy to &lt;em&gt;think&lt;/em&gt; you are in the DP quadrant when you are really in the DI quadrant.&lt;/p&gt;


	&lt;p&gt;Remember: &lt;em&gt;Murphy shall send you strong delusion, that you should believe you are in DP; so that you will be damned in DI.&lt;/em&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 15 Oct 2009 06:17:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:169be751-1a4f-45b8-8429-9eb3820be4a3</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/10/15/we-must-ship-now-and-deal-with-consequences</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Agile Methods</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>TDD Derangement Syndrome</title>
      <description>&lt;p&gt;My recent blog about &lt;span class="caps"&gt;TDD&lt;/span&gt;, Design Patterns, Concurrency, and Sudoku seemed to draw the ire of a few vocal &lt;span class="caps"&gt;TDD&lt;/span&gt; detractors.  Some of these people were rude, insulting, derisive, dismissive, and immature.  Well, Halloween is not too far away.&lt;/p&gt;


	&lt;p&gt;In spite of their self-righteous snickering they did ask a few reasonable questions.  To be fair I thought it would be appropriate for me to answer them.&lt;/p&gt;


	&lt;h2&gt;Is there any research on &lt;span class="caps"&gt;TDD&lt;/span&gt;?&lt;/h2&gt;


	&lt;p&gt;It turns out that there is a fair bit.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;One simple google search led me to &lt;a href="http://haacked.com/archive/2008/01/22/research-supports-the-effectiveness-of-tdd.aspx"&gt;this blog&lt;/a&gt; by Phil Haack in which he reviewed a &lt;span class="caps"&gt;TDD&lt;/span&gt; research paper.  Quoting from the paper:&lt;/li&gt;
	&lt;/ul&gt;


	&lt;blockquote&gt;
		&lt;p&gt;We found that test-first students on average wrote more tests and, in turn, students who wrote more tests tended to be more productive. We also observed that the minimum quality increased linearly with the number of programmer tests, independent of the development strategy employed.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;ul&gt;
	&lt;li&gt;The same google search led me to &lt;a href="http://weblogs.asp.net/mhawley/archive/2004/04/15/114005.aspx"&gt;this blog&lt;/a&gt; by Matt Hawley, in which he reviewed several other research papers.  Part of his summary:&lt;/li&gt;
	&lt;/ul&gt;


	&lt;blockquote&gt;
		&lt;p&gt;* 87.5% of developers reported better requirements understanding.
    * 95.8% of developers reported reduced debugging efforts.
    * 78% of developers reported &lt;span class="caps"&gt;TDD&lt;/span&gt; improved overall productivity.
    * 50% of developers found that it decreased overall development time.
    * 92% of developers felt that &lt;span class="caps"&gt;TDD&lt;/span&gt; yielded high-quality code.
    * 79% of developers believed &lt;span class="caps"&gt;TDD&lt;/span&gt; promoted simpler design.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Actually, I recognize some of Matt&amp;#8217;s results as coming from a &lt;a href="http://www.google.com/url?sa=t&amp;#38;source=web&amp;#38;ct=res&amp;#38;cd=1&amp;#38;url=http%3A%2F%2Fcollaboration.csc.ncsu.edu%2Flaurie%2FPapers%2FTDDpaperv8.pdf&amp;#38;ei=WoTMSvSXMYSqtgfDnMjrAQ&amp;#38;usg=AFQjCNHk6TJnNC32UGD8cN65EWGjoQkTBA&amp;#38;sig2=pbzOxiSB7_HAOoBTyDqetQ"&gt;rather famous 2003 study&lt;/a&gt; (also in the list of google results) by Laurie Wiliams and Boby George. This study describes a controlled experiment that they conducted in three different companies.  Though Matt&amp;#8217;s summary above is based (in part) on that study, there is more to say.&lt;/p&gt;


	&lt;p&gt;In the George-William study teams that practiced &lt;span class="caps"&gt;TDD&lt;/span&gt; took 16% &lt;em&gt;longer&lt;/em&gt; to &lt;em&gt;claim that they were done&lt;/em&gt; than the teams that did not practice &lt;span class="caps"&gt;TDD&lt;/span&gt;. Apparently tests are more accurate than claims since the non-TDD teams failed to pass one third of the researcher&amp;#8217;s hidden acceptance tests, whereas the &lt;span class="caps"&gt;TDD&lt;/span&gt; teams passed about 6 out of 7.  To paraphrase Kent Beck: &amp;#8220;If it doesn&amp;#8217;t have to work, I can get it done a &lt;em&gt;lot&lt;/em&gt; faster!&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Another point of interest in this study is that the &lt;span class="caps"&gt;TDD&lt;/span&gt; teams produced a suite of automated tests with &lt;em&gt;very&lt;/em&gt; high test coverage (close to 100% in most cases) whereas most of the non-TDD teams did not produce such a suite; even though they had been instructed to.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Jim Shore wrote a review of &lt;a href="http://jamesshore.com/Blog/AoA-Correction-Test-Driven-Development.html"&gt;yet another research summary&lt;/a&gt; which I found in the same google search.  This one combines 7 different studies (including George-Williams).  Here the results range from dramatically improved quality and productivity to no observed effect.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Finally, there is &lt;a href="http://www.google.com/url?sa=t&amp;#38;source=web&amp;#38;ct=res&amp;#38;cd=4&amp;#38;url=http%3A%2F%2Fresearch.microsoft.com%2Fen-us%2Fprojects%2Fesm%2Fnagappan_tdd.pdf&amp;#38;ei=y4rMSryKDeWltgf6rOXgAQ&amp;#38;usg=AFQjCNGO5ql_sCI2dG5oR6mN8EFBa2OZNA&amp;#38;sig2=U8nr4HFFE6Ezog93OIhRTw"&gt;this&lt;/a&gt; 2008 case Study of &lt;span class="caps"&gt;TDD&lt;/span&gt; at &lt;span class="caps"&gt;IBM&lt;/span&gt; and Microsoft which shows that TDDers enjoy a defect density reduction ranging from 30% to 90% (as measured by defect tracking tools) and a productivity cost of between 15% and 35% (the subjective opinion of the managers).  I refer you back to Kent Beck&amp;#8217;s comment above.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;I&amp;#8217;m sure there is more research out there.  After all this was just one google search.  I think it&amp;#8217;s odd that the &lt;span class="caps"&gt;TDD&lt;/span&gt; detractors didn&amp;#8217;t find anything when they did &lt;em&gt;their&lt;/em&gt; google searches.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Oh yeah, and then there was that &lt;a href="http://www2.computer.org/portal/web/csdl/magazines/software#4"&gt;whole issue of &lt;span class="caps"&gt;IEEE&lt;/span&gt; Software&lt;/a&gt; that was dedicated to papers and research on &lt;span class="caps"&gt;TDD&lt;/span&gt;.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;What projects have been written with &lt;span class="caps"&gt;TDD&lt;/span&gt;, hmmm?&lt;/h2&gt;


	&lt;p&gt;Quite a few, actually.  The following is a list of projects that have an automated suite of unit tests with very high coverage.  Those that I know for a fact use &lt;span class="caps"&gt;TDD&lt;/span&gt;, I have noted as such.  The others, I can only surmise.  If you know of any others, please post a comment here.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;JUnit.  This one is kind of obvious.  JUnit was written by Kent Beck and Erich Gamma using &lt;span class="caps"&gt;TDD&lt;/span&gt; throughout.  If you measure software success by sheer distribution, this particular program is &lt;em&gt;wildly&lt;/em&gt; successful.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Fit.  Written by Ward Cunningham.  The progenitor of most current acceptance testing frameworks.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;FitNesse.  This testing framework has tens of thousands of users.  It is 70,000 lines of java code, with 90%+ code coverage.  &lt;span class="caps"&gt;TDD&lt;/span&gt; throughout.  Very small bug-list.  Again, if you measure by distribution, another raving success.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Cucumber, &lt;/li&gt;
		&lt;li&gt;Rspec.  These two are Testing frameworks in Ruby.  Of course you&amp;#8217;d expect a testing framework to be written with &lt;span class="caps"&gt;TDD&lt;/span&gt;, wouldn&amp;#8217;t you? I know these were. &lt;span class="caps"&gt;TDD&lt;/span&gt; throughout.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Limelight.  A gui framework in JRUby.  &lt;span class="caps"&gt;TDD&lt;/span&gt; throughout.&lt;/li&gt;
		&lt;li&gt;jfreechart. &lt;/li&gt;
		&lt;li&gt;Spring&lt;/li&gt;
		&lt;li&gt;JRuby&lt;/li&gt;
		&lt;li&gt;Smallsql&lt;/li&gt;
		&lt;li&gt;Ant&lt;/li&gt;
		&lt;li&gt;MarsProject&lt;/li&gt;
		&lt;li&gt;Log4J&lt;/li&gt;
		&lt;li&gt;Jmock&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Are there others?  I&amp;#8217;m sure there are.  This was just a quick web search.  
Again, if you know of more, please add a comment.&lt;/p&gt;</description>
      <pubDate>Wed, 07 Oct 2009 08:32:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:31f3a32e-467c-4c54-9ec8-3b63fe961ff1</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/10/07/tdd-derangement-syndrome</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Agile Methods</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>Echoes from the Stone Age</title>
      <description>&lt;p&gt;The echoes from Joel Spolsky&amp;#8217;s &lt;a href="http://www.joelonsoftware.com/items/2009/09/23.html"&gt;Duct Tape blog&lt;/a&gt; continue to bounce off the blogosphere and twitterverse.  &lt;a href="http://www.tbray.org/ongoing/When/200x/2009/09/25/On-Duct-Tape"&gt;Tim Bray&lt;/a&gt; and &lt;a href="http://gigamonkeys.com/blog/2009/10/05/coders-unit-testing.html"&gt;Peter Seibel&lt;/a&gt; have both written responses to Joel, me, and each other.&lt;/p&gt;


	&lt;p&gt;Here are some stray thoughts&amp;#8230;&lt;/p&gt;


	&lt;h2&gt;&lt;span class="caps"&gt;TDD&lt;/span&gt;&lt;/h2&gt;


	&lt;p&gt;Anyone who continues to think that &lt;span class="caps"&gt;TDD&lt;/span&gt; slows you down is living in the stone age.  Sorry, that&amp;#8217;s just the truth.  &lt;span class="caps"&gt;TDD&lt;/span&gt; does not slow you down, it speeds you up.&lt;/p&gt;


	&lt;p&gt;Look, &lt;span class="caps"&gt;TDD&lt;/span&gt; is not my religion, it is one of my &lt;em&gt;disciplines&lt;/em&gt;.  It&amp;#8217;s like &lt;em&gt;dual entry bookkeeping&lt;/em&gt; for accountants, or &lt;em&gt;sterile procedure&lt;/em&gt; for surgeons.  Professionals adopt such disciplines because they understand the theory behind them, and have directly experienced the benefits of using them.&lt;/p&gt;


	&lt;p&gt;I have experienced the tremendous benefit that &lt;span class="caps"&gt;TDD&lt;/span&gt; has had in my work, and I have observed it in others.  I have seen and experienced the way that &lt;span class="caps"&gt;TDD&lt;/span&gt; helps programmers conceive their designs.  I have seen and experienced the way it documents their decisions.  I have seen and experienced the decouplings imposed by the tests, and I have seen and experienced the fearlessness with which TDDers can change and clean their code.&lt;/p&gt;


	&lt;p&gt;To be fair, I don&amp;#8217;t think &lt;span class="caps"&gt;TDD&lt;/span&gt; is &lt;em&gt;always&lt;/em&gt; appropriate.  There are situations when I break the discipline and write code before tests.  I&amp;#8217;ll write about these situations in another blog.  However, these situations are few and far between.  In general, for me and many others, &lt;span class="caps"&gt;TDD&lt;/span&gt; is a way to go fast, well, and sure.&lt;/p&gt;


	&lt;p&gt;The upshot of all this is simple.  &lt;span class="caps"&gt;TDD&lt;/span&gt; is a professional discipline.  &lt;span class="caps"&gt;TDD&lt;/span&gt; works.  &lt;span class="caps"&gt;TDD&lt;/span&gt; makes you faster.  &lt;span class="caps"&gt;TDD&lt;/span&gt; is not going away.  And anyone who has not &lt;em&gt;really&lt;/em&gt; tried it, and yet claims that it would slow them down, is simply being willfully ignorant.  I don&amp;#8217;t care if your name is Don Knuth, Jamie Zawinski, Peter Seibel, or Peter Pan.  Give it a &lt;em&gt;real&lt;/em&gt; try, and &lt;em&gt;then&lt;/em&gt; you have the right to comment.&lt;/p&gt;


	&lt;p&gt;Let me put this another way.  And now I&amp;#8217;m talking directly to those who make the claim that &lt;span class="caps"&gt;TDD&lt;/span&gt; would slow them down.  Are you really such a good programmer that you don&amp;#8217;t need to thoroughly check your work?  Can you conceive of a better way to check your work than to express your intent in terms of an executable test?  And can you think of a better way to ensure that you can write that test other than to write it first?&lt;/p&gt;


	&lt;p&gt;If you can, then I want to hear all about it.  but I don&amp;#8217;t want to hear that you write a few unit tests after the fact.  I don&amp;#8217;t want to hear that you manually check your code.  I don&amp;#8217;t want to hear that you &lt;em&gt;do design&lt;/em&gt; and therefore don&amp;#8217;t need to write tests.  Those are all stone-age concepts.  I know.  I&amp;#8217;ve been there.&lt;/p&gt;


	&lt;p&gt;So there. &amp;lt;grin&amp;gt;&lt;/p&gt;


	&lt;h2&gt;The Design Pattern Religion&lt;/h2&gt;


	&lt;p&gt;Tim Bray said:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;My experience suggests that there are few surer ways to doom a big software project than via the Design Patterns religion.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;He&amp;#8217;s right of course.  The Design Patterns &lt;em&gt;religion&lt;/em&gt; is a foul bird that ravages teams and cuts down young projects in their prime.  But let&amp;#8217;s be clear about what that religion is.  The Design Patterns religion is the ardent belief that the use of design patterns is &lt;em&gt;good&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s a clue.  Design Patterns aren&amp;#8217;t good.  They also aren&amp;#8217;t bad.  They just are.  Given a particular software design situation, there may be a pattern that fits and is beneficial.  There may also be patterns that would be detrimental.  It&amp;#8217;s quite possible that none of the currently documented patterns are appropriate and that you should close the book and just solve the problem.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s another clue.  You don&amp;#8217;t &lt;em&gt;use&lt;/em&gt; patterns.  You don&amp;#8217;t &lt;em&gt;apply&lt;/em&gt; patterns.  Patterns just are.  If a particular pattern is appropriate to solve a given problem, then it will be &lt;em&gt;obvious&lt;/em&gt;.  Indeed it is often &lt;em&gt;so&lt;/em&gt; obvious that you don&amp;#8217;t realize that the pattern is in place until you are done.  You look &lt;em&gt;back&lt;/em&gt; at your code and realize: &amp;#8220;Oh, that&amp;#8217;s a Decorator!&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;So am I saying that Design Patterns are useless?&lt;/p&gt;


	&lt;p&gt;NO!  I want you to read the patterns books.  I want you to know those patterns inside and out.  If I point at you and say &amp;#8220;Visitor&amp;#8221; I want you at the board drawing all the different variants of the pattern without hesitation.  I want you to get all the names and roles right.  I want you to &lt;em&gt;know&lt;/em&gt; patterns.&lt;/p&gt;


	&lt;p&gt;But I don&amp;#8217;t want you to &lt;em&gt;use&lt;/em&gt; patterns.  I don&amp;#8217;t want you to &lt;em&gt;believe&lt;/em&gt; in patterns.  I don&amp;#8217;t want you to make patterns into a religion.  Rather I want you to be able to recognize them when they appear, and to &lt;em&gt;regularize&lt;/em&gt; them in your code so that others can recognize them too.&lt;/p&gt;


	&lt;p&gt;Design Patterns have a &lt;em&gt;huge&lt;/em&gt; benefit.  They have &lt;em&gt;names&lt;/em&gt;.  If you are reading code, and you see the word &amp;#8220;Composite&amp;#8221;, and if the author took care to regularize the code to the accepted names and roles of the &amp;#8220;Composite&amp;#8221; pattern, then you will &lt;em&gt;know&lt;/em&gt; what that part of the code is doing instantly.  And &lt;em&gt;that&lt;/em&gt; is powerful!&lt;/p&gt;


	&lt;h2&gt;Minimizing Concurrency.&lt;/h2&gt;


	&lt;p&gt;In my first &lt;a href="http://blog.objectmentor.com/articles/2009/09/24/the-duct-tape-programmer"&gt;Duct Tape blog&lt;/a&gt; I made the statement:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;I found myself annoyed at Joel&amp;rsquo;s notion that most programmers aren&amp;rsquo;t smart enough to use templates, design patterns, multi-threading, &lt;span class="caps"&gt;COM&lt;/span&gt;, etc. I don&amp;rsquo;t think that&amp;rsquo;s the case. I think that any programmer that&amp;rsquo;s not smart enough to use tools like that is probably not smart enough to be a programmer period.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Tim responds with:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;...multi-threading is part of the problem, not part of the solution; that essentially no application programmer understands threads well enough to avoid deadlocks and races and horrible non-repeatable bugs. And that &lt;span class="caps"&gt;COM&lt;/span&gt; was one of the most colossal piles of crap my profession ever foisted on itself.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Is concurrency really part of the problem?  Yes!  Concurrency is a &lt;em&gt;really big&lt;/em&gt; part of the problem.  Indeed, the first rule of concurrency is: &lt;em&gt;&lt;span class="caps"&gt;DON&lt;/span&gt;&amp;#8217;T&lt;/em&gt;.  The second rule is: &lt;em&gt;&lt;span class="caps"&gt;REALLY&lt;/span&gt;, DON&amp;#8217;T&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;The problem is that some times you have no choice.  And in those situations, where you absolutely must use concurrency, &lt;em&gt;you should know it inside and out!&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;I completely and utterly reject the notion that &lt;em&gt;ignorance&lt;/em&gt; is the best defense.  I reject that &lt;em&gt;lack of skill&lt;/em&gt; can &lt;em&gt;ever&lt;/em&gt; be an advantage.  So I want you to &lt;em&gt;know&lt;/em&gt; concurrency.  I want to shout &amp;#8220;Dining Philosophers&amp;#8221; and have you run to the board without hesitation and show me all the different solutions.  If I holler &amp;#8220;Deadlock&amp;#8221;, I want you to quickly identify the causes and solutions.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s a clue.  If you want to avoid using something, &lt;em&gt;know&lt;/em&gt; that something &lt;em&gt;cold&lt;/em&gt;.&lt;/p&gt;


	&lt;h2&gt;Sudoku&lt;/h2&gt;


	&lt;p&gt;At the end of his blog, Peter jumps on the pile of bodies already crushing Ron Jeffries regarding the Sudoku problem from July of 2006.&lt;/p&gt;


	&lt;p&gt;I find the pile-up disturbing.  Ron had the courage to fail in public.  Indeed he announced up front that he might &amp;#8220;crash and burn&amp;#8221;.  And yet he got lambasted for it by people who hid behind someone else&amp;#8217;s work.  The responses to Ron&amp;#8217;s tutorial blogs were completely unfair because the authors of those blogs had everything worked out for them by Dr. Peter Norvig before they published their screeds.  They were comparing apples to oranges because their responses were about the &lt;em&gt;solution&lt;/em&gt; whereas Ron&amp;#8217;s blogs were about the &lt;em&gt;process&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Which one of us has not gone down a rat-hole when hunting for a solution to a complex problem?  Let &lt;em&gt;that&lt;/em&gt; person write the first blog.  Everyone else ought to be a bit more humble.&lt;/p&gt;


	&lt;p&gt;Do the people on the pile think that Ron is unable to solve the Sudoku problem?  (Some have said as much.)  Then they don&amp;#8217;t know Ron very well.  Ron could code them all under the table with one hand tied behind his back.&lt;/p&gt;


	&lt;p&gt;Personal issues aside, I find the discussion fascinating in it&amp;#8217;s own right.  Ron had attempted to solve the Sudoku problem by gaining insight into that problem through the process of coding intermediate solutions.  This is a common enough &lt;span class="caps"&gt;TDD&lt;/span&gt; approach.  Indeed, the &lt;a href="http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata"&gt;Bowling Game&lt;/a&gt; and the &lt;a href="http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata"&gt;Prime Factors Kata&lt;/a&gt; are both examples where this approach can work reasonably well.&lt;/p&gt;


	&lt;p&gt;This approach follows the advice of no less than Grady Booch who (quoting Heinlein) said:  &amp;#8220;&lt;em&gt;when faced with a problem you do not understand, do any part of it you do understand, then look at it again.&lt;/em&gt;&amp;#8220;&lt;/p&gt;


	&lt;p&gt;Ron was attempting to use &lt;span class="caps"&gt;TDD&lt;/span&gt; to &lt;em&gt;probe&lt;/em&gt; into the problem to see if he could gain any insight.  This technique often bears fruit.  Sometimes it does not.&lt;/p&gt;


	&lt;p&gt;Here is a classic example.  Imagine you were going to write a sort algorithm test first:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Test 1: Sort an empty array.
Solution: Return the input array.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Test 2: Sort an array with one element.
Solution: Return the input array.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Test 3: Sort an array with two elements.
Solution: Compare the two elements and swap if out of order.  Return the result.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Test 4: Sort an array with three elements.
Solution: Compare the first two and swap if out of order.  Compare the second two and swap if out of order.  Compare the first two again and swap if out of order.  Return the result.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Test 5: Sort an array with four elements.
Solution: Put the compare and swap operations into a nested loop.  Return the result.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;The end result is a bubble sort.  The algorithm virtually self assembles.  If you had never heard of a bubble sort before, this simple set of tests would have driven you to implement it naturally.&lt;/p&gt;


	&lt;p&gt;Problems like Bowling, Prime Factors, and Bubble Sort hold out the interesting promise that &lt;span class="caps"&gt;TDD&lt;/span&gt; may be a way to &lt;em&gt;derive&lt;/em&gt; algorithmms from first principles!&lt;/p&gt;


	&lt;p&gt;On the other hand, what set of tests would drive you to implement a QuickSort?  There are none that I know of.  QuickSort and Sudoku may require a serious amount of introspection and concentrated thought before the solution is apparent.  They may belong to a class of algorithms that do not self-assemble like Bowling, Prime Factors, and Bubble Sort.&lt;/p&gt;


	&lt;p&gt;This &lt;a href="http://www.infoq.com/news/2007/05/tdd-sudoku"&gt;blog&lt;/a&gt; by Kurt Christensen provides all the links to the various Sudoku articles, and sums it up this way.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;&lt;span class="caps"&gt;TDD&lt;/span&gt; may not be the best tool for inventing new algorithms, it may very well be the best tool for applying those algorithms to the problem at hand.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Actually I think &lt;span class="caps"&gt;TDD&lt;/span&gt; is a good way to find out if an algorithm will self-assemble or not.  It usually doesn&amp;#8217;t take a lot of time to figure out which it&amp;#8217;s going to be.&lt;/p&gt;</description>
      <pubDate>Tue, 06 Oct 2009 11:07:29 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:1624b718-36a6-4521-aa4e-14d5b9623dc0</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/10/06/echoes-from-the-stone-age</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>One Thing: Extract till you Drop.</title>
      <description>&lt;p&gt;For years authors and consultants (like me) have been telling us that functions should do &lt;em&gt;one thing&lt;/em&gt;.  They should do it well.  They should do it only.&lt;/p&gt;


	&lt;p&gt;The question is: What the hell does &amp;#8220;one thing&amp;#8221; mean?&lt;/p&gt;


	&lt;p&gt;After all, one man&amp;#8217;s &amp;#8220;one thing&amp;#8221; might be someone else&amp;#8217;s &amp;#8220;two things&amp;#8221;.&lt;/p&gt;


Consider this class:
&lt;pre&gt;
  class SymbolReplacer {
    protected String stringToReplace;
    protected List&amp;lt;String&amp;gt; alreadyReplaced = new ArrayList&amp;lt;String&amp;gt;();

    SymbolReplacer(String s) {
      this.stringToReplace = s;
    }

    String replace() {
      Pattern symbolPattern = Pattern.compile("\\$([a-zA-Z]\\w*)");
      Matcher symbolMatcher = symbolPattern.matcher(stringToReplace);
      while (symbolMatcher.find()) {
        String symbolName = symbolMatcher.group(1);
        if (getSymbol(symbolName) != null &amp;#38;&amp;#38; !alreadyReplaced.contains(symbolName)) {
          alreadyReplaced.add(symbolName);
          stringToReplace = stringToReplace.replace("$" + symbolName, translate(symbolName));
        }
      }
      return stringToReplace;
    }

    protected String translate(String symbolName) {
      return getSymbol(symbolName);
    }
  }
&lt;/pre&gt;

	&lt;p&gt;It&amp;#8217;s not too hard to understand.  The &lt;span style="font-family:courier;"&gt;replace()&lt;/span&gt; function searches through a string looking for &lt;em&gt;$NAME&lt;/em&gt; and replaces each instance with the appropriate translation of &lt;em&gt;&lt;span class="caps"&gt;NAME&lt;/span&gt;&lt;/em&gt;.  It also makes sure that it doesn&amp;#8217;t replace a name more than once.  Simple.&lt;/p&gt;


	&lt;p&gt;Of course the words &amp;#8220;It also&amp;#8230;&amp;#8221; pretty much proves that this function does more than one thing.  So we can probably split the function up into two functions as follows:&lt;/p&gt;


&lt;pre&gt;
    String replace() {
      Pattern symbolPattern = Pattern.compile("\\$([a-zA-Z]\\w*)");
      Matcher symbolMatcher = symbolPattern.matcher(stringToReplace);
      while (symbolMatcher.find()) {
        String symbolName = symbolMatcher.group(1);
        replaceAllInstances(symbolName);
      }
      return stringToReplace;
    }

    private void replaceAllInstances(String symbolName) {
      if (getSymbol(symbolName) != null &amp;#38;&amp;#38; !alreadyReplaced.contains(symbolName)) {
        alreadyReplaced.add(symbolName);
        stringToReplace = stringToReplace.replace("$" + symbolName, translate(symbolName));
      }
    }
&lt;/pre&gt;

	&lt;p&gt;OK, so now the &lt;span style="font-family:courier;"&gt;replace()&lt;/span&gt; function simply finds all the symbols that need replacing, and the &lt;span style="font-family:courier;"&gt;replaceAllInstances()&lt;/span&gt; function replaces them if they haven&amp;#8217;t already been replaced.  So do these function do one thing each?&lt;/p&gt;


	&lt;p&gt;Well, the &lt;span style="font-family:courier;"&gt;replace()&lt;/span&gt; compiles the pattern and build the &lt;span style="font-family:courier;"&gt;Matcher()&lt;/span&gt;  Maybe those actions should be moved into the constructor?&lt;/p&gt;


&lt;pre&gt;
  class SymbolReplacer {
    protected String stringToReplace;
    protected List&amp;lt;String&amp;gt; alreadyReplaced = new ArrayList&amp;lt;String&amp;gt;();
    private Matcher symbolMatcher;
    private final Pattern symbolPattern = Pattern.compile("\\$([a-zA-Z]\\w*)");

    SymbolReplacer(String s) {
      this.stringToReplace = s;
      symbolMatcher = symbolPattern.matcher(s);
    }

    String replace() {
      while (symbolMatcher.find()) {
        String symbolName = symbolMatcher.group(1);
        replaceAllInstances(symbolName);
      }
      return stringToReplace;
    }

    private void replaceAllInstances(String symbolName) {
      if (getSymbol(symbolName) != null &amp;#38;&amp;#38; !alreadyReplaced.contains(symbolName)) {
        alreadyReplaced.add(symbolName);
        stringToReplace = stringToReplace.replace("$" + symbolName, translate(symbolName));
      }
    }

    protected String translate(String symbolName) {
      return getSymbol(symbolName);
    }
  }
&lt;/pre&gt;

	&lt;p&gt;OK, so &lt;em&gt;now&lt;/em&gt; certainly the &lt;span style="font-family:courier;"&gt;replace()&lt;/span&gt; function is doing &lt;em&gt;one thing&lt;/em&gt;?  Ah, but I see at least two.  It loops, extracts the &lt;span style="font-family:courier;"&gt;symbolName&lt;/span&gt; and then does the replace.  OK, so how about this?&lt;/p&gt;


&lt;pre&gt;
    String replace() {
      for (String symbolName = nextSymbol(); symbolName != null; symbolName = nextSymbol())
        replaceAllInstances(symbolName);

      return stringToReplace;
    }

    private String nextSymbol() {
      return symbolMatcher.find() ? symbolMatcher.group(1) : null;
    }
&lt;/pre&gt;

	&lt;p&gt;I had to restructure things a little bit.  The loop is a bit ugly.  I wish I could have said &lt;span style="font-family:courier;"&gt;for (String symbolName : symbolMatcher)&lt;/span&gt; but I guess &lt;span style="font-family:courier;"&gt;Matchers&lt;/span&gt; don&amp;#8217;t work that way.&lt;/p&gt;


	&lt;p&gt;I kind of like the &lt;span style="font-family:courier;"&gt;nextSymbol()&lt;/span&gt; function.  It gets the &lt;span style="font-family:courier;"&gt;Matcher&lt;/span&gt; nicely out of the way.&lt;/p&gt;


	&lt;p&gt;So now the &lt;span style="font-family:courier;"&gt;replace()&lt;/span&gt; and &lt;span style="font-family:courier;"&gt;nextSymbol()&lt;/span&gt; functions are &lt;em&gt;certainly&lt;/em&gt; doing one thing.  Aren&amp;#8217;t they?&lt;/p&gt;


	&lt;p&gt;Well, I suppose I could separate the loop from the return in &lt;span style="font-family:courier;"&gt;replace()&lt;/span&gt;.&lt;/p&gt;


&lt;pre&gt;
    String replace() {
      replaceAllSymbols();
      return stringToReplace;
    }

    private void replaceAllSymbols() {
      for (String symbolName = nextSymbol(); symbolName != null; symbolName = nextSymbol())
        replaceAllInstances(symbolName);
    }
&lt;/pre&gt;

	&lt;p&gt;I don&amp;#8217;t see how I could make these functions smaller.  They &lt;em&gt;must&lt;/em&gt; be doing &lt;em&gt;one thing&lt;/em&gt;.  There&amp;#8217;s no way to extract any other functions from them!&lt;/p&gt;


	&lt;p&gt;Uh&amp;#8230;  Wait.  Is &lt;em&gt;that&lt;/em&gt; the definition of &lt;em&gt;one thing&lt;/em&gt;?  Is a function doing &lt;em&gt;one thing&lt;/em&gt; if, and only if, you simply cannot extract any other functions from it?  What else &lt;em&gt;could&lt;/em&gt; &amp;#8220;one thing&amp;#8221; mean?  After all, If I can extract one function out of another, the original function must have been doing more than one thing.&lt;/p&gt;


	&lt;p&gt;So does that mean that for all these years the authors and consultants (like me) have been telling us to extract until you can&amp;#8217;t extract anymore?&lt;/p&gt;


Let&amp;#8217;s try that with the rest of this class and see what it looks like&amp;#8230;
&lt;pre&gt;
  class SymbolReplacer {
    protected String stringToReplace;
    protected List&amp;lt;String&amp;gt; alreadyReplaced = new ArrayList&amp;lt;String&amp;gt;();
    private Matcher symbolMatcher;
    private final Pattern symbolPattern = Pattern.compile("\\$([a-zA-Z]\\w*)");

    SymbolReplacer(String s) {
      this.stringToReplace = s;
      symbolMatcher = symbolPattern.matcher(s);
    }

    String replace() {
      replaceAllSymbols();
      return stringToReplace;
    }

    private void replaceAllSymbols() {
      for (String symbolName = nextSymbol(); symbolName != null; symbolName = nextSymbol())
        replaceAllInstances(symbolName);
    }

    private String nextSymbol() {
      return symbolMatcher.find() ? symbolMatcher.group(1) : null;
    }

    private void replaceAllInstances(String symbolName) {
      if (shouldReplaceSymbol(symbolName))
        replaceSymbol(symbolName);
    }

    private boolean shouldReplaceSymbol(String symbolName) {
      return getSymbol(symbolName) != null &amp;#38;&amp;#38; !alreadyReplaced.contains(symbolName);
    }

    private void replaceSymbol(String symbolName) {
      alreadyReplaced.add(symbolName);
      stringToReplace = stringToReplace.replace(
        symbolExpression(symbolName), 
        translate(symbolName));
    }

    private String symbolExpression(String symbolName) {
      return "$" + symbolName;
    }

    protected String translate(String symbolName) {
      return getSymbol(symbolName);
    }
  }
&lt;/pre&gt;

	&lt;p&gt;Well, I think it&amp;#8217;s pretty clear that each of these functions is doing &lt;em&gt;one thing&lt;/em&gt;.  I&amp;#8217;m not sure how I&amp;#8217;d extract anything further from any of them.&lt;/p&gt;


	&lt;p&gt;Perhaps you think this is taking things too far.  I used to think so too.  But after programming for over 40+ years, I&amp;#8217;m beginning to come to the conclusion that this level of extraction is not taking things too far at all.  In fact, to me, it looks just about right.&lt;/p&gt;


	&lt;p&gt;So, my advice: Extract till you just can&amp;#8217;t extract any more.  Extract till you drop.&lt;/p&gt;


	&lt;p&gt;After all, with modern tools it takes &lt;em&gt;very&lt;/em&gt; little time.  It makes each function almost trivial.  The code reads very nicely.  It forces you to put little snippets of code into nicely named functions.  And, well gosh, extracting till you drop is kind of fun!&lt;/p&gt;</description>
      <pubDate>Fri, 11 Sep 2009 13:33:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:fa921995-cdc4-4867-8541-9bfa9a2834e4</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/09/11/one-thing-extract-till-you-drop</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Design Principles</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>The Rush</title>
      <description>&lt;p&gt;There&amp;#8217;s nothing like the feeling of achievement when you get a complex software system working.  It&amp;#8217;s the feeling of the hunter making a hard fought kill.  By the sheer power of your intellect you have imposed your will upon inanimate nature, and forced it to do your bidding.  You feel the &lt;em&gt;rush&lt;/em&gt; of power, the satisfaction of victory.  You are the master!&lt;/p&gt;


	&lt;p&gt;That&amp;#8217;s the good news.&lt;/p&gt;


	&lt;p&gt;The bad news is that you&amp;#8217;ve made a mess of things along the way.&lt;/p&gt;


	&lt;p&gt;This is inevitable.  It takes a great deal of focus and endurance to get a system working just right.  While you are consumed by that focus, you have little room for niceties like small functions, nice names, decoupling, and cleanliness.&lt;/p&gt;


	&lt;p&gt;My apprentice and I just finished achieving a major milestone in FitNesse.  It used to be that each new release of FitNesse was contained in a zip file that had all the files and directories laid out just perfectly.  This is great for a brand new installation, but doesn&amp;#8217;t work so well when you are upgrading.  What we managed to get working last night was the ability for FitNesse to self-install from it&amp;#8217;s jar file.  Now, whether you are installing for the first time, or just upgrading, FitNesse will install itself into your environment appropriately.&lt;/p&gt;


	&lt;p&gt;If you&amp;#8217;ve ever written a self-install like this, you know there are lots of niggling little details to attend to.  While the problem is conceptually simple, the realization is a maze of complexity.&lt;/p&gt;


	&lt;p&gt;Last night, with dinner waiting on the table and getting cold, we got the last little problem licked, and saw the whole self-installation work as we wanted.  We congratulated each other with a high-five, and then went upstairs to eat a well-deserved meal.  Later that evening I went down to the office and checked in the code.&lt;/p&gt;


	&lt;p&gt;This morning I woke up, and while in the shower, I realized that we had a lot of work left to do.  We need to go back over all that code and clean it up.  I&amp;#8217;m sure we left a swath of detritus while on the hunt.&lt;/p&gt;


	&lt;p&gt;The rush of victory should never be confused with the cold and crystalline concept of &lt;em&gt;done&lt;/em&gt;.  Once you get your systems to work, you still have to go back and clean up the wreckage left behind by the victorious battle.  You are not &lt;em&gt;done&lt;/em&gt; until the victorious code has been cleaned, polished, and oiled.&lt;/p&gt;</description>
      <pubDate>Fri, 26 Jun 2009 08:40:13 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:ff86f7eb-465c-43d7-8584-e9f35b3dc900</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/06/26/the-rush</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>Rich Hickey on Testing</title>
      <description>&lt;p&gt;It was an interesting week at JavaOne, with lots of talks and hallway discussions about new languages on the &lt;span class="caps"&gt;JVM&lt;/span&gt;. One of those languages is Clojure.&lt;/p&gt;


	&lt;p&gt;Rich Hickey, the creator of Clojure, gave a talk at the Bay Area Clojure User Group Wednesday evening. During the Q&amp;#38;A part, he said that he&amp;#8217;s not big on writing tests, although he always runs the tests that other people have written before he commits changes.&lt;/p&gt;


	&lt;p&gt;Of course, there are many people, including us Object Mentors, who consider &lt;span class="caps"&gt;TDD&lt;/span&gt; to be an essential part of professional software development. Obviously not everyone agrees. James Coplien has been another critic of this view.&lt;/p&gt;


	&lt;p&gt;We should never accept any dogma. Why is &lt;span class="caps"&gt;TDD&lt;/span&gt; considered important? What does it purport to do? &lt;span class="caps"&gt;TDD&lt;/span&gt; provides two important benefits.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Driving the design.&lt;/li&gt;
		&lt;li&gt;Building a suite of automated regression tests.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;So, if you can satisfy both requirements without &lt;span class="caps"&gt;TDD&lt;/span&gt;, then technically you don&amp;#8217;t need it. In Rich&amp;#8217;s case, he said he spends a lot of time thinking about what he&amp;#8217;s going to do before he does it. In this way, he satisfies the first requirement, driving the design. I had a spirited discussion with some Thoughtworkers afterwards and Ola Bini said what a lot of us think, &amp;#8220;I do that thinking by writing tests.&amp;#8221; I&amp;#8217;ll freely admit that when I am really experimenting with ideas, I might just write code, but once I know how to proceed, I return to the beginning and test drive the &amp;#8220;production&amp;#8221; code.&lt;/p&gt;


	&lt;p&gt;Rich also made an off-hand comment that if he screws something up, he&amp;#8217;s got thousands of users who will let him know! That &lt;em&gt;ex post facto&lt;/em&gt; testing, along with the Rich&amp;#8217;s own devotion to doing high-quality work, does a good job of handling regressions.&lt;/p&gt;


	&lt;p&gt;But Rich mentioned something else that is also very important. In a functional language, where values are immutability and mutable state is handled in specific, principled ways, regressions don&amp;#8217;t happen nearly as often. Clojure has one of the most deeply thought out approaches for handling state, which is the genius of Clojure.&lt;/p&gt;


	&lt;p&gt;I asked Rich how long he worked on Clojure before releasing it to the world. He spent about 2 1/2 years, much of that time working exclusively on Clojure (and eating through his savings). When he finally &amp;#8220;announced&amp;#8221; it, his &amp;#8220;marketing&amp;#8221; consisted of one email to some friends in the Common Lisp community. The rest was viral, a testament to the justified excitement Clojure has generated.&lt;/p&gt;


	&lt;p&gt;For me, I&amp;#8217;ll probably always do my design thinking through tests, especially when I&amp;#8217;m writing code in imperative languages, like Java and Ruby. I&amp;#8217;ll continue to encourage my clients to use &lt;span class="caps"&gt;TDD&lt;/span&gt;, because I find that &lt;span class="caps"&gt;TDD&lt;/span&gt; is the most productive way to achieve high quality. I want the safety net of a good test suite. I&amp;#8217;m also writing more and more of my code in a functional style, with minimal side effects and mutable data. You should, too.&lt;/p&gt;</description>
      <pubDate>Fri, 05 Jun 2009 12:40:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:1af0ef13-e2af-4bbe-aa1a-158f3813eeaa</guid>
      <author>Dean Wampler</author>
      <link>http://blog.objectmentor.com/articles/2009/06/05/rich-hickey-on-testing</link>
      <category>Dean's Deprecations</category>
      <category>Software Craftsmanship</category>
      <category>Design Principles</category>
      <category>clojure</category>
      <category>TDD</category>
      <category>testing</category>
    </item>
    <item>
      <title>Why the sea is boiling hot</title>
      <description>&lt;p&gt;In my &lt;a href="http://blip.tv/file/2089545"&gt;keynote&lt;/a&gt; at the &lt;a href="http://en.oreilly.com/rails2009/"&gt;Rails Conference&lt;/a&gt; last Wednesday, I spoke about &lt;em&gt;What Killed Smalltalk and could it Kill Ruby Too?&lt;/em&gt;.  In this keynote, as is my wont, I spoke about the need for our industry to define itself as a profession, and for us to define ourselves as professionals.  I closed the keynote with this statement: &amp;#8220;Professionalism does not mean rigid formalism.  Professionalism does not mean adhering to beaurocrasy.  Professionalism is &lt;em&gt;honor&lt;/em&gt;.  Professionalism is being honest with yourself and disciplined in the way you work.  Professionalism is not letting fear take over.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;David Heinemeier Hansson, inventor of Rails, and affectionately referred to as @dhh has posted a &lt;a href="http://www.loudthinking.com/posts/42-we-need-both-engineers-and-artists-in-programming"&gt;blog&lt;/a&gt; in response in which he asserts that we need &lt;em&gt;artists&lt;/em&gt; as well as &lt;em&gt;professionals&lt;/em&gt;, and draws a dichotomy between the two.  The dichotomy is a false one&amp;#8230;&lt;/p&gt;


	&lt;p&gt;We are a community of artisans.  &lt;em&gt;We make things with our hands!&lt;/em&gt;  We all strive, like @dhh, to make things of great beauty and utility.  In no way, and by no means, do I wish to assail that artistry.  Indeed, my hope is to free it.  I want to convince all programmers that the desire for, and the pursuit of beauty is &lt;em&gt;the way you satisfy your customers&lt;/em&gt;.  The only way to go fast, &lt;em&gt;is to go well.&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;I want developers to take pride in their work.  I also want them to take pride in &lt;em&gt;the way&lt;/em&gt; that they work.  I want them to be able to look back on the last few days, weeks, and months, and be able to say to themselves, &amp;#8220;I made something beautiful, and I made it well.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;We are a quirky lot.  Some of us wear faded jeans with yesterday&amp;#8217;s spaghetti on them.  Others wear T-shirts that have PI wrapped around them.  There are beards, tatoos, tongue-studs and hair in all shapes and colors. There are hawaiian shirts and sandals.  There are jackets and ties and sometimes even suits. Some of us speak carefully.  Some of us drop F-bombs at a whim.  Some of us are liberal, and some are conservative.  Some of us relish in being seen, and some of us are glad to be overlooked.  In short, we are a group of diverse people who are drawn together by our common passion for code.&lt;/p&gt;


	&lt;p&gt;There is nothing wrong with this diversity.  Indeed it&amp;#8217;s healthy.  The fact that we all think differently about styles, language, appearance, and values means that there are a zillion different ways that we can learn from each other.  And in that learning grows the seed of our profession.&lt;/p&gt;


	&lt;p&gt;So @dhh is right, at least about the diversity.  We should all relish the opportunity to share ideas with people who think differently than we do.  But @dhh is wrong when he draws the dichotomy between artists and engineers.  Every engineer is an artist, and every artist is an engineer.   Every engineer strives for elegance and beauty.  Every artist has the need to make their art actually work.  The two are inextricably tied.  You cannot be one without also being the other.&lt;/p&gt;


	&lt;p&gt;Now, certainly there are environments where the engineering side of things is emphasized over the artistry side.  In extreme cases the artistry is repressed into near non-existence.  Such places are soul-searing hell-holes that every programmer should strive to escape (or for the brave: change from within!)  Indeed, @dhh implies that he worked in such places and found he was &amp;#8220;faking [his] way along in this world.&amp;#8221;  I completely understand that.&lt;/p&gt;


	&lt;p&gt;But then @dhh makes his biggest mistake.  He equates the professionalism I was talking about in my keynote with those repressive environments.  He seems to think that professionalism and artistry are mutually exclusive.  That wearing a green band means you give up on beauty.  That discipline somehow saps programmer happiness.&lt;/p&gt;


	&lt;p&gt;But remember what I said when I closed my keynote: &amp;#8220;Professionalism does not mean rigid formalism.  Professionalism does not mean adhering to beaurocrasy.  Professionalism is &lt;em&gt;honor&lt;/em&gt;.  Professionalism is being honest with yourself and disciplined in the way you work.  Professionalism is not letting fear take over.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;This is not a complete definition; but it will serve for my current purposes.  Because, you see, I made a big mistake during that keynote. And it is in how we deal with our own errors that the claim of professionalism is most frequently, and most thoroughly tested.&lt;/p&gt;


	&lt;p&gt;In my keynote I used a metaphor to link hormones and languages.  I said that C++ was a testosterone language, but Java was an estrogen language.  And then I used the word &amp;#8220;insipid&amp;#8221; to describe Java.&lt;/p&gt;


	&lt;p&gt;Now clearly C++ and testosterone have very little in common.  My use of this metaphor was an oratory device &amp;#8211; a joke.  As far as the operation of that device is concerned, it was a success.  The vast majority of the audience laughed, demonstrating to me that they were a) listening and b) understanding and c) open.&lt;/p&gt;


	&lt;p&gt;There is a kind of &lt;em&gt;artistry&lt;/em&gt; in making oratory devices like this, and I take a certain amount pride in it.  Such devices need to be timed appropriately, delivered skillfully, and used to gauge the audience.  They can help to turn virtually any dry topic into a compelling speech.&lt;/p&gt;


	&lt;p&gt;On the other hand, the construction of &lt;em&gt;this&lt;/em&gt; device had a significant flaw.  I had equated women with weakness.  This was not intentional.  I do not think of women as weak.  But there it was: Estrogen === Insipid. If you were a woman in that audience, how could you come to any conclusion other than &amp;#8220;Uncle Bob thinks women are weak.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;How did I make this error?  Lack of discipline.  I did not &lt;em&gt;test&lt;/em&gt; this keynote adequately.  I should at least have run it past my wife!  I mis-engineered my art!  (Or perhaps my engineering was artless &amp;lt;grin&amp;gt;).&lt;/p&gt;


	&lt;p&gt;Within minutes of concluding my talk, the complaints appeared on twitter.   Women who had been offended and hurt by the remark were tweeting their dissatisfaction.  Some men were joining them.&lt;/p&gt;


	&lt;p&gt;There were two ways I could have responded to this.  I could have asserted that these people were just being too sensitive; that they should have realized that this was just an oratory device and that I didn&amp;#8217;t mean any harm; that they should just recognize me for who I am and not get so hung up in their own fears and values.&lt;/p&gt;


	&lt;p&gt;But I think that reaction would have been unprofessional.  Why?  Because it would have been dishonest.  The truth was that this was just a stupid mistake.  I built the device badly.  I executed the device without testing it properly.  I screwed up; and I needed to own up that.  So I immediately tweeted apologies to those concerned and ate an appropriate amount of humble pie.&lt;/p&gt;


	&lt;p&gt;The reason I told you this story (at the risk of sounding somewhat self-aggrandizing) is so that I could use it to help define professionalism.  The construction of my oratory device was unprofessional.  I should have tested it better.  I should have realized the danger of using gender comparisons and taken greater care with their use.  &lt;em&gt;I could have done better&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;We professionals aren&amp;#8217;t prefect.  We all make mistakes.  We recover from those mistakes by owning up to them &lt;em&gt;as&lt;/em&gt; mistakes.  We do not cover those mistakes by claiming that everyone else is wrong.&lt;/p&gt;


	&lt;p&gt;Confronting your mistakes and taking appropriate action is a &lt;em&gt;discipline&lt;/em&gt;. It is a &lt;em&gt;discipline&lt;/em&gt; of honor and self-honesty.  It is a demonstration that we do not let the fear of our own errors take us over.&lt;/p&gt;</description>
      <pubDate>Mon, 11 May 2009 11:09:57 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:0740eb61-d264-4e84-8d93-142a484e6943</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/05/11/why-the-sea-is-boiling-hot</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
    </item>
    <item>
      <title>Crap Code Inevitable?  Rumblings from ACCU.</title>
      <description>&lt;p&gt;I gave the opening Keynote at &lt;a href="http://accu.org/index.php/conferences/accu_conference_2009"&gt;&lt;span class="caps"&gt;ACCU 2009&lt;/span&gt;&lt;/a&gt; on Wednesday.  It was entitled: &lt;em&gt;The Birth of Craftsmanship&lt;/em&gt;.  Nicolai Josuttis finshed the day with the closing keynote: &lt;em&gt;Welcome Crappy Code &amp;#8211; The Death of Code Quality&lt;/em&gt;.  It was like a blow to the gut.&lt;/p&gt;


	&lt;p&gt;In my keynote I attempted to show the historical trajectory that has led to the emergence of the &lt;a href="http://manifesto.softwarecraftsmanship.org/"&gt;software craftsmanship&lt;/a&gt; movement.  My argument was that since the business practices of &lt;span class="caps"&gt;SCRUM&lt;/span&gt; have been widely adopted, and since teams who follow those practices but do not follow the technical practices of XP experience a relentless decrease in velocity, and since that decrease in velocity is &lt;em&gt;exposed&lt;/em&gt; by the transparency of scrum, then if follows that the eventual adoption of those technical XP practices is virtually assured.  My conclusion was that Craftsmanship was the &amp;#8220;next big thing&amp;#8221; (tm) that would capture the attention of our industry for the next few years, driven by the business need to increase velocity.  (See Martin Fowler&amp;#8217;s blog on &lt;a href="http://martinfowler.com/bliki/FlaccidScrum.html"&gt;Flaccid Scrum&lt;/a&gt;)  In short, we are on a trajectory towards a higher degree of professionalism and craftsmanship.&lt;/p&gt;


	&lt;p&gt;Nicolai&amp;#8217;s thesis was the exact opposite of mine.  His argument was that we are all ruled by marketing and that businesses will do whatever it takes to cut costs and increase revenue, and therefore businesses will drive software quality inexorably downward.  He stipulated that this will necessarily create a crisis as the defect rates and deadline slips increased, but that all attempts to improve quality would be short lived and followed by a larger drive to decrease quality even further.&lt;/p&gt;


	&lt;p&gt;Josuttis&amp;#8217; talk was an hour of highly depressing rhetoric couched in articulate delivery and brilliant humor.  One of the more memorable moments came when he playacted how a manger would respond to a developer&amp;#8217;s plea to let them write clean code like Uncle Bob says.  The manager replies: &amp;#8220;I don&amp;#8217;t care what Uncle Bob says, and if you don&amp;#8217;t like it you can leave and take Uncle Bob with you.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;One of the funnier moments came when Josuttis came up with his rules for crap code, one of which was &amp;#8220;Praise Copy and Paste&amp;#8221;.  Here he showed the evolution of a module from the viewpoint of clean code, and then from the viewpoint of copy-paste.  His conclusion, delivered with a lovely irony, was the the copy-paste solution was more maintainable because it was clear which code belonged to which version.&lt;/p&gt;


	&lt;p&gt;It was at this point that I thought that this whole talk was a ribald joke, an elaborate spoof.  I predicted that he was about to turn the tables on everyone and ringingly endorse the craftsmanship movement.&lt;/p&gt;


	&lt;p&gt;Alas, it was not so. In the end he said that he was serious about his claims, and that he was convinced that crap code would dominate our future.  And then he gave his closing plea which went like this:&lt;/p&gt;


	&lt;p&gt;We finally accepted that requirements change, and so we invented Agile.&lt;/p&gt;


	&lt;p&gt;We must finally accept that code will be crap and so we must ???&lt;/p&gt;


	&lt;p&gt;He left the question marks on the screen and closed the talk.&lt;/p&gt;


	&lt;p&gt;This was like a blow to the gut.  The mood of the conference changed, at least for me, from a high of enthralled geekery, to depths of hoplessness and feelings of futile striving against the inevitable. Our cause was lost.  Defeat was imminent.  There was no hope.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Bulls Bollocks!&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;To his credit, there are a few things that Josuttis got right.  There &lt;em&gt;is&lt;/em&gt; a lot of crap code out there.  And there &lt;em&gt;is&lt;/em&gt; a growing cohort of crappy coders writing that crap code.&lt;/p&gt;


	&lt;p&gt;But the solution to that is not to give up and become one of them.  The solution to that is to design our systems so that they don&amp;#8217;t require an army of maintainers slinging code.  Instead we need to design our systems such that the vast majority of changes can be implemented in DSLs that are tuned to business needs, and do not require &amp;#8220;programmers&amp;#8221; to maintain.&lt;/p&gt;


	&lt;p&gt;The thing that Josuttis got completely wrong, in my mildly arrogant opinion, is the notion that low quality code is cheaper than high quality code.  Low quality code is &lt;em&gt;not&lt;/em&gt; cheaper; it is &lt;em&gt;vastly&lt;/em&gt; more expensive, even in the short term.  Bad code slows everyone down from the minute that it is written.  It creates a continuous and copious drag on further progress. It requires armies of coders to overcome that drag; and those armies must grow exponentially to maintain constant velocity against that drag.&lt;/p&gt;


	&lt;p&gt;This strikes at the very heart of Josuttis&amp;#8217; argument.  His claim that crappy code is inevitable is based on the notion that crappy code is cheaper than clean code, and that therefore businesses will demand the crap every time.  But it has generally not been &lt;em&gt;business&lt;/em&gt; that has demanded crappy code.  Rather it has been &lt;em&gt;developers&lt;/em&gt; who mistakenly thought that the business&amp;#8217; need for speed meant that they had to produce crappy code.  Once &lt;em&gt;we&lt;/em&gt;, as &lt;em&gt;professional developers&lt;/em&gt;, realize that the only way to go fast is to create clean and well designed code, then we will see the business&amp;#8217; need for speed as a demand for high quality code.&lt;/p&gt;


	&lt;p&gt;My vision of the future is quite different from Josuttis&amp;#8217;.  I see software developers working together to create a discipline of craftsmanship, professionalism, and quality similar to the way that doctors, lawyers, architects, and many other professionals and artisans have done.  I see a future where team velocities increase while development costs decrease because of the steadily increasing skill of the teams.    I see a future where large software systems are engineered by relatively small teams of craftsmen, and are configured and customized by business people using DSLs tuned to their needs.&lt;/p&gt;


	&lt;p&gt;I see a future of &lt;em&gt;Clean Code&lt;/em&gt;, Craftsmanship, Professionalism, and an overriding imperative for Code Quality.&lt;/p&gt;</description>
      <pubDate>Thu, 23 Apr 2009 04:56:22 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:3032f508-8860-43f1-a16b-5b26b563999d</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/04/23/crap-code-inevitable-rumblings-from-accu</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>Master Craftsman Teams.</title>
      <description>&lt;p&gt;In the early &amp;#8216;70s F. T. Baker, and Fred Brooks wrote about the notion of Chief Programmer teams.  The idea was that a highly skilled chief programer would be assisted by a team of helpers.  The chief would write most of the code, delegating simpler tasks to the helpers.&lt;/p&gt;


	&lt;p&gt;Though the idea was tried at &lt;span class="caps"&gt;IBM&lt;/span&gt; and shown to work well, the idea has never really caught on.  One reason may be that the economics don&amp;#8217;t appear to be all that good.  A team of four juniors making $50K supporting a senior making $100K costs $300K. That just seems like a lot of money for one well supported chief programmer writing most of the code.&lt;/p&gt;


	&lt;p&gt;But in light of the movement towards software craftsmanship, perhaps it&amp;#8217;s time to dust off this old idea and look at it from a different perspective.  Consider the following thought experiment&amp;#8230;&lt;/p&gt;


	&lt;p&gt;We are in the throes of a recession that is challenging us to think differently about things.  At the same time our universities are &lt;em&gt;raising&lt;/em&gt; tuitions and &lt;em&gt;increasing&lt;/em&gt; faculty salaries, while requiring ever less from both the faculty and the students.  Today&amp;#8217;s professors spend about 9 hours per week in the classroom.  And the quality of the CS majors graduating from these institutions is, to put it bluntly, &lt;em&gt;wretched&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Why should a young aspiring software professional spend four years and $200K+ to attend an institution that will teach them less about their chosen profession than 3 months of working on a real project with talented mentors?  Indeed, why should employers pay $50K for undertrained programmers who are sure to make horrific messes for the next three years of their career?&lt;/p&gt;


	&lt;p&gt;Consider instead a team of craftspeople.  At the center of this team is a master programmer.  This is someone who has been programming for two decades or more.  This person understand systems at a gut level, and can quickly make technical judgements without agonizing over them.  Such a person can direct a team with the kind of calm confidence that only comes with years of experience and seasoning.&lt;/p&gt;


	&lt;p&gt;Our master has three lieutenant journeymen who themselves each have three apprentices.  Our journeymen have at least five years of experience, and are capable both of taking and giving direction.  They can make short term tactical decisions, and direct their apprentices accordingly.  At the same time they take technical and architectural direction from the master.&lt;/p&gt;


	&lt;p&gt;The journeymen write a &lt;em&gt;lot&lt;/em&gt; of code &amp;#8211; almost as much as the master.  They also throw away two thirds of the code written by the apprentices, and drive them to redo it better &amp;#8211; always better.  They teach the apprentices how to refactor, and often pair with them and sit with them while reviewing their code.&lt;/p&gt;


	&lt;p&gt;The master probably writes more code than any of the team members.  This code is often architectural in nature, and helps to establish the seed about which the system will crystalize.  The master also sets technical direction and overall architecture, and makes all critical technical decisions.  However, the chief job of the master is to relentlessly drive the journeymen towards higher quality and productivity by establishing and enforcing the appropriate disciplines and practices.  From the master&amp;#8217;s point of view, it&amp;#8217;s &amp;#8220;my way or the highway.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Yes, I know this is very &lt;em&gt;anti-scrum&lt;/em&gt;.  But this is a case where I think scrum in particular, and agile in general just got it wrong.  No battle was won by gaining the consensus of the soldiers.  And if you don&amp;#8217;t think developing a system is a &lt;em&gt;battle&lt;/em&gt; against time, resources, and attitudes, then you&amp;#8217;ve never built a system.  No great team has ever succeeded without a strong coach who imposed discipline, set the vision, and had the final authority over who played and who sat on the bench.  Consensus and team rule may be useful tools &lt;em&gt;some of the time&lt;/em&gt;, but only in the context of effective leadership.&lt;/p&gt;


	&lt;p&gt;The apprentices write a significant amount of code&amp;#8212;most of which is discarded by the journeymen.  The journeymen act as committers.  When an apprentice delivers code that the journeyman finds acceptable, the journeyman will commit that code to their main line.  Otherwise he sends it back to the apprentice to do over.  By the same token the master accepts subsystems from the journeymen and, if acceptable, commits it to the master main line.&lt;/p&gt;


	&lt;p&gt;The master sees every line of code in the system. The Journeymen see every line of code written by their apprentices, and they write a significant amount themselves.  Pairing is prevalent though not universal.  Anyone on the team can pair with anyone else.  It should not be uncommon for the master to pair with the apprentices from time to time.&lt;/p&gt;


	&lt;p&gt;Apprentices begin at a young age&amp;#8212;perhaps 18 or 19.  After all, the idea is that they aren&amp;#8217;t going to a university.  Rather, the brightest would start as apprentices right out of high school, while others might opt for two years of community college first.&lt;/p&gt;


	&lt;p&gt;Apprenticeship would last 2-4 years, depending on how quickly the apprentice learns.  Apprentices earn no more than minimum wage.  After all, they are young, barely productive, and are deriving great benefit from working with experienced journeyman under the guidance of a master.&lt;/p&gt;


	&lt;p&gt;Attaining journeyman status is something for the master to decide, with advice from the journeymen.  The decision is bittersweet because it is a decision to eject the apprentice from the team so that he or she can start the &lt;em&gt;journey&lt;/em&gt;.  Usually the new journeyman would join the team of a different master.&lt;/p&gt;


	&lt;p&gt;Some apprentices simply won&amp;#8217;t attain journeyman status.  In the end, if they fail to make progress, they must be removed from the team.  No one should stay an apprentice year after year.  It is the responsibility of the journeymen and master to decide if an apprentice should be removed from the team.&lt;/p&gt;


	&lt;p&gt;The skills of new journeymen will gradually increase.  At first they should have only one apprentice.  Over the months and years their increasing leadership skills will allow them to take two or three at a time.  The most experienced Journeymen might play the role of master in smaller projects.&lt;/p&gt;


	&lt;p&gt;Attaining master status is no small feat.  It requires the consensus of other masters, and must be demonstrated through several successful accomplishments.&lt;/p&gt;


	&lt;p&gt;I expect a journeyman would make $50-100K depending on their experience.  I expect a master would make $150-$250K or more.&lt;/p&gt;


	&lt;p&gt;Now imagine a team of 13.  One master, three journeymen, and nine apprentices.  This is a powerful unit.  Its size is right at the sweet spot for hyper productive teams.  It has the right balance of experience.  And&amp;#8230; it&amp;#8217;s pretty cheap.  This team costs ~$600K per year, or about $50K per person.  Or (consulting companies take notice) about $23/person/hour.&lt;/p&gt;


	&lt;p&gt;It seems to me that such a team could do much more, much better, than a team of 12 graduates lead by a tech-lead with five years experience.  The productivity and efficiency (and efficiencies of scale!) of this approach should be obvious.  Moreover, I think that being an apprentice on a team like this would provide a much better, much faster, and &lt;em&gt;much&lt;/em&gt; cheaper education than a university degree.  Finally, I think that using teams of this kind could be a remarkably cost-effective way to get very high quality software written very quickly.&lt;/p&gt;</description>
      <pubDate>Wed, 01 Apr 2009 16:51:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:f9df49b6-e79e-445b-96de-203dbf363851</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/04/01/master-craftsman-teams</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
    </item>
    <item>
      <title>Let's Hear it for the Zealots!</title>
      <description>&lt;p&gt;In his March 1st, 2009 &lt;a href="http://www.sdtimes.com/link/33300"&gt;column&lt;/a&gt; in SDTimes, Andrew Binstock takes the &amp;#8220;Zealots of Agile&amp;#8221; to task for claiming that Agile is the &lt;em&gt;one true way&lt;/em&gt;.  He made the counter-argument that non-agile projects have succeeded, and that agile projects have failed.  He implied that the attitudes of the agile zealots are blind to these facts.&lt;/p&gt;


	&lt;p&gt;What a load of dingoes kidneys!&lt;/p&gt;


	&lt;p&gt;There is a difference between a zealot, and a religious fanatic.  A religious fanatic cannot envision themselves to be wrong.  We in the agile community may indeed be zealots, but we know we can be wrong.  We know that projects succeeded before agile, and we know that agile projects have failed.  We know that there are other schools of thought that are just as valid as ours.  Indeed, most of us expect (even hope!) that agile will be superseded by something better one day.&lt;/p&gt;


	&lt;p&gt;Some of you may remember my keynote address at the 2002 XPUniverse in Chicago.  My son, Micah, and I got up in front of the group dressed in Jiu Jistsu garb, and commenced to do a martial arts demonstration.&lt;/p&gt;


	&lt;p&gt;After the demonstration I made the point that a student of Karate could have given an equally spellbinding, though quite different, show.  A student of Tae Kwon Do would amaze us with still other wonderful moves.  The morale, of course, was that there are many ways to get the job done.  There are many equally valid schools of thought.&lt;/p&gt;


	&lt;p&gt;However, the knowledge that there are other valid schools of thought does not dilute the zeal a student has for the school of thought he has chosen to study.  Do you think that a Jiu Jistsu master isn&amp;#8217;t a zealot?  You&amp;#8217;d better believe he is!  To be great, one must have zeal.  To rail against zeal is to rail against the desire for greatness.  It is &lt;em&gt;zeal&lt;/em&gt; that makes you go the extra distance to become great.  The Jiu Jitsu master may respect the Karate master, but his goal is to become great at Jiu Jitsu.&lt;/p&gt;


	&lt;p&gt;So I think it is &lt;em&gt;healthy&lt;/em&gt; that agile proponents are vociferous advocates of their school of thought.  They are like Karate students who are excited about their new skills, and want to teach those skills to others.  If their zeal to excel can infect others with similar zeal, so much the better.  We &lt;em&gt;need&lt;/em&gt; people in this industry who want to excel.&lt;/p&gt;


	&lt;p&gt;In his column Andrew derided agile zealots for claiming that Agile was the &lt;em&gt;one true path&lt;/em&gt;.  I don&amp;#8217;t know of any prominent agile advocate who has ever made that claim.  Indeed, when Kent Beck and I sat down in 1999 to plan out the XP Immersion training, we were very concerned that we might turn the XP movement into a religion.  We did not want to create the impression that XPers were the chosen people and that wisdom would die with us.  So we were, in fact, very careful to avoid any hint of the &amp;#8220;one true path&amp;#8221; argument.&lt;/p&gt;


	&lt;p&gt;As evidence of this, consider the Snowbird meeting in 2001.  That meeting was &lt;em&gt;inclusive&lt;/em&gt;, not exclusive.  We invited people from all over the spectrum to join us there.  &lt;span class="caps"&gt;DSDM&lt;/span&gt;, FDD, Scrum, Crystal, &lt;span class="caps"&gt;MDA&lt;/span&gt;, &amp;#38; &lt;span class="caps"&gt;RUP&lt;/span&gt; were all represented; and the agile manifesto (Yes, Andrew, Manifesto![1]) was the result.  That manifesto was a simple statement of values, not a claim to deific knowledge.&lt;/p&gt;


	&lt;p&gt;Am I an Agile Zealot?  Damned right I am!  Do I think Agile is the best way to get software done?  Damned right I do!  I wouldn&amp;#8217;t be doing Agile if I didn&amp;#8217;t think it was best.  Do I think Agile is better than someone else&amp;#8217;s school of thought?  Let me put it this way: I&amp;#8217;m quite happy to go head to head against someone who follows another school of thought.  I believe I&amp;#8217;d code him right into the ground!  Isn&amp;#8217;t that what any good student of his craft would think?  But I also recognize that one day I&amp;#8217;ll lose that competition, and that will be a great day for me because it will give me the opportunity to learn something new and better.&lt;/p&gt;


	&lt;p&gt;Andrew also mentioned that Kent Beck and I are so obsessed with our &amp;#8220;evangelical fervor&amp;#8221; that we: &amp;#8220;endlessly test and endlessly refine and refactor code to the point that it becomes an all-consuming diversion that does not advance the project&amp;#8221;.  &lt;span class="caps"&gt;WTF&lt;/span&gt;?  I&amp;#8217;ve been making monthly releases of FitNesse, and Kent has been cranking out releases of JunitMax; neither of us has been so busy gilding our respective lilies that we are failing to move our respective projects forward. Look around Andrew, we&amp;#8217;re shipping code over here brother.&lt;/p&gt;


	&lt;p&gt;As part of his rant against our &amp;#8220;evangelical fervor&amp;#8221; Andrew asked this rather snide question: &amp;#8220;I broke up that code into a separate class and added seven methods for what benefit, again?&amp;#8221;  This would appear to be a dig against refactoring &amp;#8211; or perhaps &lt;em&gt;excess&lt;/em&gt; refactoring.  Still the question has a simple answer.  We would only break up a module into a class with seven methods if that module was big, ugly, and complex, and by breaking it up we made it simple and easy to understand and modify.  It seems to me that leaving the module in a messy state is irresponsible and unprofessional.&lt;/p&gt;


	&lt;p&gt;Andrew complains that there is very little Agile experience with projects over six million lines of code.  I&amp;#8217;m not sure where he got that number from, perhaps he&amp;#8217;s been watching Steve Austin re-runs.  Actually, the majority of my 2008 consulting business has been with very large companies with products &lt;em&gt;well&lt;/em&gt; over six million lines of code.  Agile-in-the-Large is the name of the game in those companies!&lt;/p&gt;


	&lt;p&gt;Finally, Andrew says Michael Feathers is a &amp;#8220;moderate&amp;#8221; Agile proponent.  This is the same Michael Feathers who wrote a book defining Legacy code as code without tests &amp;#8211; hardly a moderate point of view.  Michael is a master, not a moderate.&lt;/p&gt;


	&lt;p&gt;I think Andrew has fallen into a common trap.  He sees the zeal of the agile proponents and mistakes it for religious fanaticism.  Instead of respecting that zeal as the outward manifestation of the inward desire to excel, he rails against it as being myopic and exclusive and then views all the statements of the agile proponents through that clouded viewport.  Once you have decided that someone is a religious fanatic, it is difficult to accept anything they say.&lt;/p&gt;


	&lt;p&gt;I think standing against religious fanaticism in the software community is a good thing.  I also think that those of us who are zealous must constantly watch that we are not also becoming blind to our own weaknesses and exclusive in our outlook.  But I could wish that those who fear religious fanaticism as much as I do would stop confusing it with professional zeal.&lt;/p&gt;


	&lt;p&gt;So here&amp;#8217;s the bottom line.  People who excel are, by definition, zealots.  People who aren&amp;#8217;t zealous, do not excel. So there&amp;#8217;s nothing wrong with being a zealot; indeed, zeal is a very positive emotion. The trick to being a zealot is to be mindful that the day will eventually come when some other zealot from a different school of thought will code you into the ground.  When that happens, you should thank him for showing you a better way.&lt;/p&gt;


	&lt;p id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; I kicked off the Snowbird meeting by challenging the group to write a &amp;#8220;manifesto&amp;#8221;.  I chose the word &amp;#8220;manifesto&amp;#8221; because some years earlier I had read &lt;em&gt;The Object Oriented Database System Manifesto&lt;/em&gt; and I thought it was a clever use of the word.&lt;/p&gt;</description>
      <pubDate>Tue, 10 Mar 2009 16:58:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:7987e28e-935e-4303-b2e4-1e010beba6b7</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/03/10/lets-hear-it-for-the-zealots</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>Quality:  It's alive!  It's ALIVE!</title>
      <description>&lt;p&gt;Recently James Bach wrote a compelling post entitled &lt;a href="http://www.satisfice.com/blog/archives/224"&gt;Quality is Dead&lt;/a&gt;.  As much as I&amp;#8217;d like to agree, something interesting has just happened that tempts me to believe in a rebirth.&lt;/p&gt;


	&lt;p&gt;Just when James finally declares the death of quality, along comes the &lt;a href="http://manifesto.softwarecraftsmanship.org/main"&gt;Manifesto for Software Craftsmanship&lt;/a&gt;.  This simple document that builds upon the four values declared in the &lt;a href="http://agilemanifesto.org/"&gt;Agile Manifesto&lt;/a&gt; went live late on Friday evening.  Now, at 3PM on Saturday over 600 people have signed it!&lt;/p&gt;


	&lt;p&gt;What does this mean?  I think it means that many of us have seen what James was talking about, and are tired of it.  We don&amp;#8217;t want our users posting blogs &amp;#8211; as James did &amp;#8211; crying that they &lt;span class="caps"&gt;HATE&lt;/span&gt; us.  We want our users to be astonished by the elegance and simplicity of our creations.  We want other software developers to look under the hood and be amazed and impressed at the clarity and simplicity they see.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;We want to be proud of our work!&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;We want our quality back!&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;And so a few weeks ago some software developers gathered at the offices of &lt;a href="http://www.8thlight.com/main"&gt;8th Light&lt;/a&gt; in Libertyville, Illinois, and began the process of creating this manifesto.  There followed a very active and passionate discussion in the &lt;a href="http://groups.google.com/group/software_craftsmanship?lnk=srg"&gt;Software Craftsmanship email group&lt;/a&gt;.  The end result was this manifesto.&lt;/p&gt;


	&lt;p&gt;I encourage all of you to read and sign the manifesto, join the email group, and help bring quality back to life in the software profession.&lt;/p&gt;</description>
      <pubDate>Sat, 07 Mar 2009 15:25:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:7fda0576-ab31-4f6b-bf1c-d87078134a6b</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/03/07/quality-its-alive-its-alive</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Clean Code</category>
    </item>
  </channel>
</rss>

