<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>jbrains.ca: Can't stop the learning</title>
    <link>http://jbrains.ca/blog</link>
    <pubDate>Fri, 16 Jul 2010 08:00:00 GMT</pubDate>
    <description>From the mind of J. B. Rainsberger: software, learning, teaching, playing</description>
    <item>
      <title>Three Steps to a Useful Minimal Feature</title>
      <link>http://jbrains.ca/permalink/309</link>
      <description>&lt;div class='entry posting' id='entry-_posting_309'&gt;
&lt;div class='posting' id='content-_posting_309'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Recently, in the mailing for Steve Freeman and Nat Pryce&amp;#8217;s book &lt;a href='http://bit.ly/cztezO'&gt;&lt;em&gt;Growing Object-Oriented Systems Guided by Tests&lt;/em&gt;&lt;/a&gt;, I followed a discussion that included this comment:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I guess the skill is knowing in what makes as small as possible but valid slice (as you say in the book)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even though &lt;a href='http://bit.ly/9fTj1U'&gt;I&amp;#8217;ve written before about splitting stories&lt;/a&gt;, I have refined my ideas about how to deliver a useful, significant, but small slice of software. I use a simple technique which I describe this way:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Write out any, and I mean any, meaningful end-to-end scenario in detail with concrete values at every step.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Now that you&amp;#8217;ve chosen one real scenario, go to each step in that scenario and ask the question, &amp;#8220;What would I need to assume to eliminate this step?&amp;#8221; If you find those assumptions make for a reasonable scenario, then use that assumption to simplify the scenario.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Repeat step 2 until exhausted or unable to come up with a simplifying assumption with five minutes&amp;#8217; thought.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I&amp;#8217;ve used the example of online bill payment in many of my classes and applied this algorithm. You&amp;#8217;d be surprised how simple, but useful a bill payments system one can build.&lt;/p&gt;

&lt;p&gt;In fact, let&amp;#8217;s look at this example in a bit more detail.&lt;/p&gt;

&lt;p&gt;What does a typical bill payments system look like? I imagine that TD Canada Trust has a fairly representative system, so I&amp;#8217;ll use that as my example.&lt;/p&gt;

&lt;p&gt;First, select the &amp;#8220;Pay Bills&amp;#8221; option.&lt;/p&gt;

&lt;p&gt;&lt;img src='http://images.jbrains.ca/walking_skeleton/BillPayments-1.jpg' alt='Selecting Pay Bills' /&gt;&lt;/p&gt;

&lt;p&gt;Next, select the account to use to pay the bill.&lt;/p&gt;

&lt;p&gt;&lt;img src='http://images.jbrains.ca/walking_skeleton/BillPayments-2.jpg' alt='Selecting the account' /&gt;&lt;/p&gt;

&lt;p&gt;Next, select the bills you&amp;#8217;d like to pay. Once in a while, I want to pay multiple bills at once, such as when my business has to pay the property taxes on a handful of rental properties.&lt;/p&gt;

&lt;p&gt;&lt;img src='http://images.jbrains.ca/walking_skeleton/BillPayments-3.jpg' alt='Selecting the bills to pay' /&gt;&lt;/p&gt;

&lt;p&gt;Next, enter the amount you want to pay, the date on which to pay it, the account from which to pay it (why again?) and whether you want to repeat this payment automatically.&lt;/p&gt;

&lt;p&gt;&lt;img src='http://images.jbrains.ca/walking_skeleton/BillPayments-4.jpg' alt='Entering the details' /&gt;&lt;/p&gt;

&lt;p&gt;Verify the payment details: the amount, the account, the creditor, the date, and the system schedules the payment.&lt;/p&gt;

&lt;p&gt;&lt;img src='http://images.jbrains.ca/walking_skeleton/BillPayments-5.jpg' alt='Verifying the details' /&gt;&lt;/p&gt;

&lt;p&gt;From this, I can describe the scenario in a form that looks like an executable example:&lt;/p&gt;
&lt;p class='scenario-title'&gt;Pay a bill online&lt;/p&gt;&lt;ul class='scenario'&gt;&lt;li&gt;Given that Joe has already logged in&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay a bill&quot;&lt;/li&gt;
&lt;li&gt;Joe selects chequing account 12345 from which to pay the bill&lt;/li&gt;
&lt;li&gt;Joe selects Visa bill with account ending in 2222 as the bill to pay&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay $5,000&quot;&lt;/li&gt;
&lt;li&gt;Joe selects a date 14 days from now as the date on which to pay the bill&lt;/li&gt;
&lt;li&gt;Joe selects &quot;only once&quot; as the frequency with which to pay the bill&lt;/li&gt;
&lt;li&gt;After Joe sees a summary of the bill payment he has asked to schedule, he says &quot;I confirm that I want to pay this bill&quot;&lt;/li&gt;
&lt;li&gt;Now the system schedules to pay the bill as requested and sends Joe an email to confirm the transaction with a link to cancel or change the scheduled payment&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Apart from the numbers, this scenario perfectly accurately reflects how I pay my bills online, although I only wish TD Canada Trust would send me the confirmation email I threw in as the system&amp;#8217;s response. We have completed step 1 of the algorithm: we have specified a complete scenario with concrete values at every step.&lt;/p&gt;
&lt;p class='warning'&gt;You'll notice that we didn't specify Joe's username and password. We don't intend to re-test logging in here, so we don't bother with those details. We will have tested that elsewhere.&lt;/p&gt;
&lt;p&gt;Now we move to step 2 of the algorithm: looking for assumptions we could make about paying a bill online that would eliminate steps in the process. To do this, we have to be prepared to sacrifice any semblance of a decent user experience. Don&amp;#8217;t worry: once the Walking Skeleton runs, you&amp;#8217;ll be able to add all the bells and whistles that will make this feature a pleasure to use. For now, we want to eliminate any detail that distracts us from connecting our feature to the key interfaces it must deal with. In this example, I know I want to expose an HTTP interface to clients (eventually the web) and that I need to connect to the Big Ugly Banking System, but beyond that, I don&amp;#8217;t know that anything else matters. Within this context, then, we can start making our simplifying assumptions.&lt;/p&gt;

&lt;p&gt;That is, until someone remembers that, being a bank, we need to keep a strictly accurate record of all transactions. That means we should add a final step to the scenario: the system records the transaction in its log. While some might consider this a superfluous detail, banking regulators would call it quite essential, and so I find it hard to ignore. This means that we have a third essential interface to which to connect: the transaction logging facility. For our purposes, I&amp;#8217;ll assume that we have one and that it has the usual properties: transaction posting date, description, and debit or credit amount, who performed the transaction and when.&lt;/p&gt;

&lt;p&gt;This itself makes me ask whether we need to log the transaction yet, because in our scenario we&amp;#8217;ve scheduled a payment, and not made one. Scheduling a transaction leads to issues of canceling, editing, and building a process that completes the transaction on the day the customer scheduled it. This leads to our first simplifying assumption: Joe pays the bill immediately.&lt;/p&gt;

&lt;p&gt;This simplifies the scenario because we no longer need Joe to tell the system when to pay the bill: the system always pays the bill immediately. Our revised scenario looks like this:&lt;/p&gt;
&lt;p class='scenario-title'&gt;Pay a bill online&lt;/p&gt;&lt;ul class='scenario'&gt;
&lt;li&gt;Given that Joe has already logged in&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay a bill&quot;&lt;/li&gt;
&lt;li&gt;Joe selects chequing account 12345 from which to pay the bill&lt;/li&gt;
&lt;li&gt;Joe selects Visa bill with account ending in 2222 as the bill to pay&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay $5,000&quot;&lt;/li&gt;
&lt;li&gt;Joe selects &quot;only once&quot; as the frequency with which to pay the bill&lt;/li&gt;
&lt;li&gt;After Joe sees a summary of the bill payment he has asked to schedule, he says &quot;I confirm that I want to pay this bill&quot;&lt;/li&gt;
&lt;li&gt;Now the system schedules pays the bill as requested and sends Joe and email to let him know that the bill was paid&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I like to start at the top and look for simplifying assumptions. First, I see that Joe has to select the account from which to pay the bill, which implies that the system presents a list of accounts to Joe, which we recognize we need to do, but not in the Walking Skeleton. Ultimately, Joe simply needs to specify the account number to debit to pay the bill, so for now we&amp;#8217;ll make him type that in. Our revised scenario looks like this:&lt;/p&gt;
&lt;p class='scenario-title'&gt;Pay a bill online&lt;/p&gt;&lt;ul class='scenario'&gt;
&lt;li&gt;Given that Joe has already logged in&lt;/li&gt;
&lt;li&gt;Given that Joe has already logged in&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay a bill&quot;&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay from account 12345&quot;&lt;/li&gt;
&lt;li&gt;Joe selects Visa bill with account ending in 2222 as the bill to pay&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay $5,000&quot;&lt;/li&gt;
&lt;li&gt;Joe selects &quot;only once&quot; as the frequency with which to pay the bill&lt;/li&gt;
&lt;li&gt;After Joe sees a summary of the bill payment he has asked to schedule, he says &quot;I confirm that I want to pay this bill&quot;&lt;/li&gt;
&lt;li&gt;Now the system schedules pays the bill as requested and sends Joe and email to let him know that the bill was paid&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Next, I see that Joe again has to select the bill to pay, which implies that the system presents a list of bills to pay. We could simplify this by requiring Joe to enter the payee identification number and the account number, even though this means saddling Joe with knowledge of payee identification numbers. In particular, the system neither has to store nor present a list of bill payees, and Joe doesn&amp;#8217;t need to register a creditor before paying them.&lt;/p&gt;
&lt;p class='warning'&gt;I'm making up this notion of payee identification numbers because I don't know how banks really implement this. I imagine whatever they do, it boils down to companies registering as payees for bill payments, which results in issuing them some kind of identification number. If some kind soul wants to educate me on how this really works, I'd gladly edit the article to bring it closer to the banking industry's real implementation.&lt;/p&gt;
&lt;p&gt;Our revised scenario looks like this:&lt;/p&gt;
&lt;p class='scenario-title'&gt;Pay a bill online&lt;/p&gt;&lt;ul class='scenario'&gt;
&lt;li&gt;Given that Joe has already logged in&lt;/li&gt;
&lt;li&gt;Given that Joe has already logged in&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay a bill&quot;&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay from account 12345&quot;&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay to payee number 66666&quot;&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay to account number 2222&quot;&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay $5,000&quot;&lt;/li&gt;
&lt;li&gt;Joe selects &quot;only once&quot; as the frequency with which to pay the bill&lt;/li&gt;
&lt;li&gt;After Joe sees a summary of the bill payment he has asked to schedule, he says &quot;I confirm that I want to pay this bill&quot;&lt;/li&gt;
&lt;li&gt;Now the system schedules pays the bill as requested and sends Joe and email to let him know that the bill was paid&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Next, I notice that Joe has to specify the amount to pay, and I can&amp;#8217;t think of how to eliminate that detail without complicating matters. It does make me think about potential future features, such as &amp;#8220;pay balance off in full&amp;#8221; and &amp;#8220;pay minimum payment required&amp;#8221;, which I note down before returning to this scenario. Joe will simply have to tell us exactly how much to pay towards the bill.&lt;/p&gt;

&lt;p&gt;Next, I notice that Joe has to confirm that he only wants a one-time payment. We can eliminate this detail by assuming that Joe can only pay the bill once. We know that customers want recurring payments, but that only distracts us from implementing the Walking Skeleton. We can eliminate this step, and our revised scenario looks like this:&lt;/p&gt;
&lt;p class='scenario-title'&gt;Pay a bill online&lt;/p&gt;&lt;ul class='scenario'&gt;
&lt;li&gt;Given that Joe has already logged in&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay a bill&quot;&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay from account 12345&quot;&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay to payee number 66666&quot;&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay to account number 2222&quot;&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay $5,000&quot;&lt;/li&gt;
&lt;li&gt;After Joe sees a summary of the bill payment he has asked to schedule, he says &quot;I confirm that I want to pay this bill&quot;&lt;/li&gt;
&lt;li&gt;Now the system schedules pays the bill as requested and sends Joe and email to let him know that the bill was paid&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Next, I notice that Joe has to confirm the bill payment before the system will process the payment. While this step might seem essential for security reasons, remember that we don&amp;#8217;t necessarily have a graphical web interface for our Walking Skeleton implementation, and so we might not even have the opportunity to ask for confirmation of the bill payment. On this basis, we eliminate this step by assuming that Joe has looked over the details before pressing the button to pay the bill. Our revised scenario looks like this:&lt;/p&gt;
&lt;p class='scenario-title'&gt;Pay a bill online&lt;/p&gt;&lt;ul class='scenario'&gt;
&lt;li&gt;Given that Joe has already logged in&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay a bill&quot;&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay from account 12345&quot;&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay to payee number 66666&quot;&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay to account number 2222&quot;&lt;/li&gt;
&lt;li&gt;Joe says &quot;I want to pay $5,000&quot;&lt;/li&gt;
&lt;li&gt;Now the system schedules pays the bill as requested and sends Joe and email to let him know that the bill was paid&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I can&amp;#8217;t see any further simplifications, so I choose to stop here. I suspect this constitutes a close-to-minimal protocol for the &amp;#8220;pay a bill online&amp;#8221; feature. The programmer in me sees this as a single message, which pleases me, because of the simplicity of the interaction. The customer in me can see clearly all the extra stories we need to complete to make this feature available for public use, which makes planning easier. It feels like a win for everyone, except perhaps for Joe, who has a crappy interface to work with.&lt;/p&gt;

&lt;p&gt;Now that we have a Walking Skeleton bill payment feature, we can identify the stories we want to deliver beyond the simplest case, and can decide which ones we need to roll this feature out to paying customers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let Joe choose from a list of available payees which company to pay&lt;/li&gt;

&lt;li&gt;Remember the payees that Joe has previously paid and present them as &amp;#8220;favorites&amp;#8221; so he doesn&amp;#8217;t have to search for them&lt;/li&gt;

&lt;li&gt;Remember the payee accounts that Joe has previously paid so that he doesn&amp;#8217;t have to enter them each time&lt;/li&gt;

&lt;li&gt;Let Joe delete accounts he no longer needs to pay&lt;/li&gt;

&lt;li&gt;Give Joe the option of paying the minimum payment required by the payee&lt;/li&gt;

&lt;li&gt;Give Joe the option of paying the full balance owing&lt;/li&gt;

&lt;li&gt;Let Joe schedule his payment in the future&lt;/li&gt;

&lt;li&gt;Let Joe cancel pending payments&lt;/li&gt;

&lt;li&gt;Let Joe change pending payments&lt;/li&gt;

&lt;li&gt;Send a reminder to Joe to pay a bill he has paid at least three of the past six months (try to detect a recurring payment)&lt;/li&gt;

&lt;li&gt;Let Joe schedule a payment to recur every month (same day each month)&lt;/li&gt;

&lt;li&gt;Notify Joe in advance of automatically detected recurring payments and ask him if he wants us to pay the bill for him&lt;/li&gt;

&lt;li&gt;When emailing Joe about a bill payment, include links to review the scheduled payment, change it, or cancel it, if appropriate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I imagine we could come up with more together, but I find one common thread with all these stories: once we implement the Walking Skeletion, we can implement most of these stories independently of the others. We know that more independent stories means greater opportunities to change priorities as needed as well as greater opportunities to drop features in favor of other more lucrative options. Once again, everyone wins.&lt;/p&gt;
&lt;p class='sell'&gt;Would you like to work with J. B. Rainsberger to realize revenue sooner and lower costs from delivering software? &lt;a href='http://bit.ly/cEP48t'&gt;Schedule a workshop&lt;/a&gt; with J. B. today.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/309';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/309&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 16, 2010  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/stories&quot;&gt;stories&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/planning&quot;&gt;planning&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 16 Jul 2010 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/309</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Design your own TDD learning experience</title>
      <link>http://jbrains.ca/permalink/292</link>
      <description>&lt;div class='entry posting' id='entry-_posting_292'&gt;
&lt;div class='posting' id='content-_posting_292'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&lt;a href=&quot;http://bit.ly/8ihrQK&quot;&gt;Join me in Chicago in September&lt;/a&gt; to learn whether test-driven development will work for you. In this course, you will learn the secrets of modular design from one of test-driven development&#8217;s master practitioners. Bring your laptop and be prepared to change the way you write software.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/292';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/292&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 15, 2010  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/TDD-From-the-Beginning&quot;&gt;TDD From the Beginning&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 15 Jul 2010 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/292</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Best of... June 15, 2010</title>
      <link>http://jbrains.ca/permalink/307</link>
      <description>&lt;div class='entry posting' id='entry-_posting_307'&gt;
&lt;div class='posting' id='content-_posting_307'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;The tweets I found most interesting or useful in the past week.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;#64;mfeathers: You don&amp;#8217;t get abstraction until you&amp;#8217;ve squeezed every bit of duplication from a piece of code walked away and found some more.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;#8220;There are no simple tricks for eliminating blame. You simply must stop doing it.&amp;#8221; &amp;#8211;Juran Institute, Inc.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;Back to Basics: &lt;a href='http://bit.ly/bozYm7'&gt;Efficiency v. Effectiveness&lt;/a&gt; by Matt Heusser&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;#64;ByronKatie: Stress is an alarm clock that lets you know you&amp;#8217;re attached to something not true for you.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/307';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/307&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 17, 2010  08:00
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 17 Jun 2010 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/307</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Some examples of programming in pairs</title>
      <link>http://jbrains.ca/permalink/306</link>
      <description>&lt;div class='entry posting' id='entry-_posting_306'&gt;
&lt;div class='posting' id='content-_posting_306'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I had the pleasure of pairing with Naresh Jain during Agile India 2010 in Bengaluru and Mumbai in January 2010. Naresh recently uploaded some video that I&amp;#8217;d like to share with you.&lt;/p&gt;

&lt;p&gt;This is how we sometimes end up pairing:&lt;/p&gt;
&lt;object height='385' width='640'&gt;&lt;param name='movie' value='http://www.youtube.com/v/IISUO7MzDS0&amp;hl=en_US&amp;fs=1&amp;' /&gt;&lt;param name='allowFullScreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;embed src='http://www.youtube.com/v/IISUO7MzDS0&amp;hl=en_US&amp;fs=1&amp;' type='application/x-shockwave-flash' allowfullscreen='true' allowscriptaccess='always' height='385' width='640' /&gt;&lt;/object&gt;
&lt;p&gt;This is how we like to think we pair:&lt;/p&gt;
&lt;object height='385' width='640'&gt;&lt;param name='movie' value='http://www.youtube.com/v/PdKup_ybJro&amp;hl=en_US&amp;fs=1&amp;' /&gt;&lt;param name='allowFullScreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;embed src='http://www.youtube.com/v/PdKup_ybJro&amp;hl=en_US&amp;fs=1&amp;' type='application/x-shockwave-flash' allowfullscreen='true' allowscriptaccess='always' height='385' width='640' /&gt;&lt;/object&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/306';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/306&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 15, 2010  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/communicating-effectively&quot;&gt;communicating effectively&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 15 Jun 2010 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/306</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Video: Education and Software Craftsmanship</title>
      <link>http://jbrains.ca/permalink/305</link>
      <description>&lt;div class='entry posting' id='entry-_posting_305'&gt;
&lt;div class='posting' id='content-_posting_305'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;In February 2010, MosaicWorks of Bucuresti, Romania, hosted Corey Haines and me to teach the world&amp;#8217;s best introduction to Test-Driven Development. After the class ended, they interviewed us on the topics of software development education and the craftsmanship movement. Please enjoy.&lt;/p&gt;

&lt;p&gt;Part 1:&lt;/p&gt;
&lt;object height='300' width='400'&gt;&lt;param name='allowfullscreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=10372086&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1' /&gt;&lt;embed src='http://vimeo.com/moogaloop.swf?clip_id=10372086&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1' type='application/x-shockwave-flash' allowfullscreen='true' allowscriptaccess='always' height='300' width='400' /&gt;&lt;/object&gt;
&lt;p&gt;Part 2:&lt;/p&gt;
&lt;object height='300' width='400'&gt;&lt;param name='allowfullscreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=10899877&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1' /&gt;&lt;embed src='http://vimeo.com/moogaloop.swf?clip_id=10899877&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1' type='application/x-shockwave-flash' allowfullscreen='true' allowscriptaccess='always' height='300' width='400' /&gt;&lt;/object&gt;
&lt;p&gt;Part 3:&lt;/p&gt;
&lt;object height='300' width='400'&gt;&lt;param name='allowfullscreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=10904638&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1' /&gt;&lt;embed src='http://vimeo.com/moogaloop.swf?clip_id=10904638&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1' type='application/x-shockwave-flash' allowfullscreen='true' allowscriptaccess='always' height='300' width='400' /&gt;&lt;/object&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/305';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/305&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 03, 2010  08:00
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 03 Apr 2010 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/305</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Making decisions doesn't have to be so hard</title>
      <link>http://jbrains.ca/permalink/303</link>
      <description>&lt;div class='entry posting' id='entry-_posting_303'&gt;
&lt;div class='posting' id='content-_posting_303'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I enjoy collaborating on decisions, but only with groups that agree to use a technique I refer to as &lt;em&gt;consent-based decision making&lt;/em&gt;. I might not use that term exactly as the coiners intended, so let me explain what I mean. I characterize consent-based decision making by putting forth a proposal, then looking for reasoned objections. When no-one raises such an objection, we accept the proposal. I find this style of decision making quicker, easier, and better for team unity than typical approaches.&lt;/p&gt;

&lt;p&gt;Consent-based decision making contrasts sharply with a typical decision-making exercise, which tends to follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Present a need or problem.&lt;/li&gt;

&lt;li&gt;Present options.&lt;/li&gt;

&lt;li&gt;Solicit more options from the group.&lt;/li&gt;

&lt;li&gt;Discuss the merits of each option in detail.&lt;/li&gt;

&lt;li&gt;Propose solutions.&lt;/li&gt;

&lt;li&gt;Combine the proposed solutions into a kind of hybrid solution to which everyone can assent.&lt;/li&gt;

&lt;li&gt;Ask for any last-minute objections.&lt;/li&gt;

&lt;li&gt;Decide.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I feel tired trying to make decisions this way, and it seems that the fatigue rises with at least the square of the number of people involved. Not only do I find it difficult to make decisions this way, but that difficulty encourages me to exclude people who might otherwise have valuable input. It puts me in a place of wanting to prune ideas, rather than generate them. You can understand why I&amp;#8217;d want to avoid this kind of consensus building.&lt;/p&gt;

&lt;h2 id='some_objections'&gt;Some objections&lt;/h2&gt;

&lt;p&gt;When I have taught consent-based decision making to my clients, some of them have pointed out that it leads to a particularly negative culture: &amp;#8220;Don&amp;#8217;t bring me problems; bring me solutions.&amp;#8221; I agree that, practised mindlessly, that could happen, but because I insist we practise mindfully, I think we can avoid this problem. Still others have pointed out that this style of decision-making stifles creativity because it intimidates people who want to point out a flaw in a proposal without necessarily having a better proposal. Again I agree, but we can mitigate this risk by looking at one of consent-based decision making&amp;#8217;s greatest strengths: separating generating ideas from selecting a solution.&lt;/p&gt;

&lt;p&gt;I remember dozens of meetings in which I participated in making decisions by building consensus, specifically how inconsistently engaged I felt. I would enter some of these meetings with a desire to generate ideas, brainstorm, and explore solutions; and I would entry other of these meetings tired of sifting through ideas, craving to decide on a course of action. I can&amp;#8217;t tell you why I felt the way I felt, but rather just that it varied, and that I felt it strongly. Sometimes I wanted to expand the solution space, and other times I wanted desperately to contract it. So far, I don&amp;#8217;t see a problem with that, but there are, of course, other people.&lt;/p&gt;

&lt;p&gt;When you and I enter a decision-making meeting with different goals, we create problems for each other. When you want to generate ideas and I want to select a solution, we fight for air time, for space, and indeed for life&amp;#8230; at least, it feels that way to me. I struggle to bring us to a sensible solution, and as my wish comes close to coming true, you trample on it with yet another pie-in-the-sky idea. Worse, your idea might fit perfectly, but I simply won&amp;#8217;t see it that way. I will interpret your every new idea as an attempt to prolong the agony, whereas you will interpret my every attempt to choose a solution as an attempt to shut you down. Result? War. Root cause? Cross purposes. Remedy? Alignment. (Surprised?)&lt;/p&gt;

&lt;h2 id='two_goals_two_meetings'&gt;Two goals, two meetings&lt;/h2&gt;

&lt;p&gt;Consider, instead, having two separate meetings: one to generate proposals, and one to select a proposal. You might find that that helps.&lt;/p&gt;

&lt;p&gt;In the first meeting, we generate ideas, brainstorm, solicit opinions, run impact studies&amp;#8230; whatever we need to do to generate proposals. The people who come to this meeting might or might not care about making the decision. Whatever happens, we can feel certain that whoever shows up wants to lend their ideas to the group, and most importantly, &lt;strong&gt;we ignore any attempt at choosing a solution&lt;/strong&gt;. We agree in advance to ignore them, because we have a different goal in this meeting. We agree not to chastise people for attempting to choose a solution because they form part of our natural impulse to jump to a conclusion. We agree to recognize each other&amp;#8217;s humanity by allowing each other to compare or rank solutions, but we generally ignore those attempts in a quiet, friendly manner. (See &lt;a href='http://www.jbrains.ca/permalink/304'&gt;Ask Why, But Don&amp;#8217;t Answer&lt;/a&gt; for an explanation.)&lt;/p&gt;

&lt;p&gt;The second meeting starts with a proposal. The group may ask clarifying questions, but by now we shouldn&amp;#8217;t need to ask too many. The Proposer than asks the group to vote, which the group does by signaling thumb up, sideways, or down. A thumb up means &amp;#8220;I accept the proposal&amp;#8221;. A thumb sideways means &amp;#8220;I will go with the rest of the group&amp;#8221;. I thumb down means &amp;#8220;I reject the proposal&amp;#8221;. Of course, if you reject the proposal, then &lt;em&gt;you must make a counter-proposal right away&lt;/em&gt;, otherwise the group feels free to ignore your vote. The group repeats this process until either it makes a decision or reaches a deadlock. If it reaches a deadlock, then we immediately adjourn the meeting and schedule another one to explore the competing proposals in depth. Why schedule another meeting? In part, to discourage people from rejecting a proposal just for the sake of rejecting it, and to give those people an opportunity to sleep on it before beginning another round of brainstorming.&lt;/p&gt;

&lt;h2 id='no_silver_bullet'&gt;No silver bullet&lt;/h2&gt;

&lt;p&gt;Naturally, people could abuse this system. And yes, when we have to make particular tough decisions, this system could take longer than the consensus-building approach. Even so, for more routine decisions, consent-based decision making works more quickly and easily, and I&amp;#8217;d rather make easy things easy and hard things possible than optimize for the hard decisions.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/303';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/303&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
March 10, 2010  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coaching&quot;&gt;coaching&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 10 Mar 2010 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/303</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Ask why, but never answer</title>
      <link>http://jbrains.ca/permalink/304</link>
      <description>&lt;div class='entry posting' id='entry-_posting_304'&gt;
&lt;div class='posting' id='content-_posting_304'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Sometimes I go on project archeological digs with my clients through their projects, often focusing on their code bases. We sometimes run a &amp;#8220;code bazaar&amp;#8221;, where we set up a half-dozen machines with code to dig through, then walk in pairs from machine to machine, digging and taking notes. During these digs, I institute a key rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Ask &amp;#8220;why&amp;#8221;, but never answer.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What kind of &amp;#8220;why&amp;#8221; question? Why, the most perplexing one: &lt;em&gt;Why the $%@# did we do this?!&lt;/em&gt; We feel free to ask the question, but we don&amp;#8217;t answer it. If someone feels the impulse to answer it, someone says, &amp;#8220;We don&amp;#8217;t go there.&amp;#8221;&lt;/p&gt;

&lt;p&gt;This rule serves a dual purpose. By never answering &amp;#8220;why&amp;#8221;, we avoid the exercise devolving into wallowing and blaming. We avoid counter-productive actions like justifying, going on the defensive, and shifting the blame. This allows us to have an open, frank discussion of the project in a safe environment. Why, then, do we permit people to &lt;em&gt;ask&lt;/em&gt; &amp;#8220;why&amp;#8221;? Simply put, we don&amp;#8217;t deny human impulse.&lt;/p&gt;

&lt;p&gt;You&amp;#8217;ve experienced it. You&amp;#8217;ve reviewed code, screamed &amp;#8220;What the fuck?!&amp;#8221; and shook your head. I recently read code that made me angry enough that I had to stand and walk around to calm down. (It assigned a field to itself. Don&amp;#8217;t ask.) I understand the power of the impulse to recoil, then demand of the universe how it could allow such a thing to happen. For this reason, we permit each other to ask &amp;#8220;why&amp;#8221;, and even to do so in a loud, obnoxious, pained tone of voice. We simply don&amp;#8217;t answer that question, and if someone tries, we remind them that &amp;#8220;we don&amp;#8217;t go there.&amp;#8221;&lt;/p&gt;

&lt;p&gt;Try it the next time you have to rummage through code, documents, or some other project artifacts as a group. Ask the group to agree on one rule: &lt;strong&gt;you can ask &amp;#8220;why&amp;#8221;, but you can&amp;#8217;t answer it.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/304';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/304&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
March 07, 2010  01:12
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 07 Mar 2010 01:12:30 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/304</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>You're probably sabotaging your people's training</title>
      <link>http://jbrains.ca/permalink/302</link>
      <description>&lt;div class='entry posting' id='entry-_posting_302'&gt;
&lt;div class='posting' id='content-_posting_302'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;You want to make a good investment in your people, and you know they need training, but when you invest thousands of dollars in courses without giving your people the slack they need to apply what they learn, &lt;strong&gt;you&amp;#8217;re just being cruel&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Now granted, you don&amp;#8217;t mean to act cruelly, but you have to take responsibility for the fact that when you give someone a chance to learn, but not to practise, you not only waste their time, but you tear down morale. Some of your people will even interpret your move as shallow, transparent appeasement. I&amp;#8217;ve seen it, and I&amp;#8217;ve felt it.&lt;/p&gt;
&lt;p&gt;Let me explain.&lt;/p&gt;
&lt;p&gt;First, let me start with a diagram that you absolutely need to know. I didn&amp;#8217;t invent it, and I have definitely simplified it, but I believe I&amp;#8217;ve kept its essence intact. This diagram graphs productivity against time as we learn a new skill.&lt;/p&gt;
&lt;p style=&quot;text-align:center;&quot;&gt;&lt;img src=&quot;http://bit.ly/djHQ0c&quot; style=&quot;height: 8cm;&quot; title=&quot;The Learning Curve&quot; alt=&quot;The Learning Curve&quot; /&gt;&lt;/p&gt;
&lt;p&gt;When you provide your people training, you start them off at the beginning of this graph, with whatever productivity level they have in that area. If you wanted to train your people in design techniques, or a new programming language, or a new programming platform, then you could interpret the productivity level in terms of features delivered per week. If you wanted to train your people in negotiation techniques and interpersonal communication, then you could interpret the productivity level in terms of complaints about others, fights, or the general quality of discourse you perceive in meetings and during daily work. However you choose to interpret this graph, it works out the same for just about any measure of productivity. Before training, your people find themselves at the far left, at some baseline level of productivity.&lt;/p&gt;
&lt;p&gt;After training, your people start to incorporate what they learned into their work. As they practise, they learn to execute the new techniques correctly, with uneven results. Once they become comfortable with the basics, they exhibit some improvement, but over weeks or months, they reach the first plateau. At this point, they have learned most of what they will learn from the first set of ideas and techniques they try.&lt;/p&gt;
&lt;p&gt;Next, they incorporate some more of what they learned into their work. This time, their productivity &lt;strong&gt;decreases&lt;/strong&gt; for a while as the new techniques they try clash with what they already know. During this time, they don&amp;#8217;t know which techniques work best in which situations, so sometimes they choose well, and other times they choose poorly. They generally struggle integrating the new ideas and techniques into their work. Eventually they reach a point where the new techniques begin to mesh well with what they know, they see new benefits that they didn&amp;#8217;t see before, their confidence improves, and their productivity resumes its increase, past their previous highest level, on to higher levels than they&amp;#8217;d experienced before. This continues until they reach the next plateau, then the cycle begins again: struggle, bottom out, improve, plateau. This cycle continues indefinitely&amp;#8230; unless you get in their way.&lt;/p&gt;
&lt;h2&gt;Saboteur? You?&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;ve seen two major categories of errors that managers make when they encourage their people to develop new skills: giving them no slack to learn, and panicking when they bottom out the first time. You might not realize you do these things, so watch for them, because I routinely see otherwise thoughtful, intelligent managers ruin potentially game-changing improvement programs by doing one of these two things. Let me clarify what I mean.&lt;/p&gt;
&lt;h2&gt;I&amp;#8217;m going to tell you a story&lt;/h2&gt;
&lt;p&gt;I remember when I first tried to use the Getting Things Done system to manage my own work. I spent dozens of hours creating projects, contexts, and next actions. I think my first task review took an entire day, as I questioned at every step how to review tasks &amp;#8220;correctly&amp;#8221;. I also remember spending plenty of time learning to use first iGTD, then later OmniFocus, struggling with how to synchronize tasks with my calendar, and generally feeling my way around the system. I remember mechanically clipping parts of email into an OmniFocus task, creating a project for it, then responding to the email and marking the OmniFocus project as &amp;#8220;completed&amp;#8221;. I remember thinking that this couldn&amp;#8217;t possibly improve my effectiveness, as it now takes a handful of steps simply to reply to an email, when it used to take only one. Still, I knew that unless I practised the steps, I&amp;#8217;d never manage to execute them deftly, so I invested the time I needed to practise. For that, I needed to build some slack into my schedule.&lt;/p&gt;
&lt;p&gt;Building slack into my schedule meant disappointing some people. It meant letting some revenue-realizing activities slip. I invoiced clients later, I paid bills slightly after they came due, and I turned down some opportunities to market myself that would surely have resulted in an increase in sales. I knew I had to do this, because if I didn&amp;#8217;t improve how well I executed the work I needed to do, I would never clear the ever-lengthening backlog I had to complete. (Before you comment, I did consider throwing away the bottom 80% of my backlog, and could manage to throw away only about 20%. This helps you understand how far behind I fell in completing this work.) Even in a desperate situation, with wolves knocking at the door, I invested the time I needed to learn how to work more effectively, because if I hadn&amp;#8217;t, then I would have continued struggling while even bigger, more ferocious wolves found me and knocked longer and louder.&lt;/p&gt;
&lt;h2&gt;Turning the first corner&lt;/h2&gt;
&lt;p&gt;Over several weeks, I noticed the first hint of what Getting Things Done promises: the feeling of having a trusted system that helps you ensure you do whatever you need to do. I started to see tasks show up a week after I&amp;#8217;d added them, because they started to come due. Unfortunately, while I saw some early wins, I feel into a deeper trap: due dates. Knowing the urgency of my backlog items, I&amp;#8217;d set tentative due dates for the vast majority of the tasks that I felt I needed to complete within two months. Naturally, since I had a blind spot for identifying all the tasks I needed to complete a project, that meant I had hundreds of tasks with due dates, averaging about fifteen per day. Every day when I looked at that list, I felt defeated, but I tried to soldier on. I fell into a rut of completing about five tasks, while deferring five more to &amp;#8220;three days from now&amp;#8221; (or worse, Friday) and, at the end of the day, pushing the last five to the next day. Within two weeks I went back to bed, feeling depressed about having over 40 &amp;#8220;urgent&amp;#8221; tasks to complete in a single day. It seemed hopeless.&lt;/p&gt;
&lt;p&gt;At this point, I could have filed for temporal bankruptcy, abandoned Getting Things Done, thrown away the task list I&amp;#8217;d spent dozens of hours crafting, and wallowed in my own inability to make progress on my backlog. I had some serious deadlines looming, which then passed, and I began to suffer so much from the stress of the wolves at my door that I reach my wit&amp;#8217;s end. I could have simply quit, and for a while, I did.&lt;/p&gt;
&lt;h2&gt;Summoning the courage to try again&lt;/h2&gt;
&lt;p&gt;After a few weeks of fighting fire after fire, interspersed with hours spent in a mild vegetative state in front of the TV, I resolved to try again. I had read a great article about why high achievers procrastinate, and it resonated with me. At the same time, I ended up spending a week at my wife&amp;#8217;s family cottage, re-reading Getting Things Done, then reading The Four Hour Work Week. Armed with more information, more ideas, and renewed enthusiasm, I cracked open OmniFocus, performed a thorough task review, threw away 90% of my due dates, and moved most of the projects into &amp;#8220;Someday&amp;#8221; and &amp;#8220;Maybe&amp;#8221; folders. This took over six hours spread over two days. After I got back to the office and resumed completing tasks, I noticed how much more I felt in control of my work. Within  a month I had made more progress on my backlog than I had in at least two years. I felt better, but noticed a new problem: due dates started sneaking up on me.&lt;/p&gt;
&lt;h2&gt;Into the abyss once more&lt;/h2&gt;
&lt;p&gt;Since I had stopped setting due dates for most tasks, I found that some due dates began sneaking up on me. Some deadlines blew right past me. I felt a momentary and mild depressive state as I wondered whether I had chosen incorrectly in removing all the due dates. I read some more, thought some more, and performed another very thorough task review. After a week I decided to experiment with adding due dates only when I absolutely knew the date on which a task came due, then measure the results. I would occasionally agonize during a task review about whether I needed to put a due date on a certain task. Sometimes I decided in a few seconds, and sometimes it took me fifteen minutes, because I didn&amp;#8217;t want to do this mindlessly. I needed to avoid falling back into the old habit of deferring tasks that had due dates, but didn&amp;#8217;t really need doing by that date. I needed not to see 40 tasks due on a Friday ever again. I persisted and, since then, I gladly report that I get good results from my use of Getting Things Done: I still have the occasional hiccup with a due date sneaking up on me, but it happens once every couple of months. For the most part, I do what needs doing and aggressively look for ways to delegate what others could capably do for me. Services like Your Man in India and elance.com help me with that. I still have things to learn, but I&amp;#8217;ve reached a pretty comfortable plateau where my productivity level appears to have matched my current workload.&lt;/p&gt;
&lt;h2&gt;And then&amp;#8230;?&lt;/h2&gt;
&lt;p&gt;So why did I tell you that story? I hope to demonstrate the power of having slack to apply what you learn when you learn it, and the power of not panicking when things start to go wrong. Specifically, I have this advice for you:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;If you plan to provide training to your people, you need also to provide about 20% slack time for them to practise what they learn.&lt;/li&gt;
	&lt;li&gt;If you cannot provide your people with 20% slack time, then &lt;b&gt;do not schedule any training yet&lt;/b&gt;. Instead, figure out how to get them the slack time they need.&lt;/li&gt;
	&lt;li&gt;If you have currently scheduled training for your people and they won&amp;#8217;t have the slack time they need to practise what they will learn, then balance the cost of canceling the training against the cost of getting them that slack time between now and when the training will begin.&lt;/li&gt;
	&lt;li&gt;After your people complete their training, work with them to build a charter related to the way they will use what they learn. This consists of a time-boxed experiment with a single measure of progress and a single goal related to that measure.&lt;/li&gt;
	&lt;li&gt;When you choose the length of time for your time-boxed experiment, make sure make it long enough to get past the first bottoming-out phase working towards the second plateau.&lt;/li&gt;
	&lt;li&gt;When your people show that they continue to struggle even half-way through the experiment, &lt;b&gt;don&amp;#8217;t panic&lt;/b&gt;! Trust the system, and maintain your commitment to invest in the entire experiment. Continue to measure progress, and make sure to check in with your people frequently and regularly, but whatever you do, &lt;b&gt;don&amp;#8217;t panic&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;#8217;d like to learn how to help your team adopt new practices effectively, schedule a private course with J. B. During your initial conversations with him, he will walk you through chartering how your people will use what he teaches them, help you figure out how to give them the slack time they need, and even give you tips on how not to panic.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/302';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/302&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
March 04, 2010  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/training&quot;&gt;training&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coaching&quot;&gt;coaching&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 04 Mar 2010 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/302</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>&quot;Integration Tests Are A Scam&quot; Is A Scam</title>
      <link>http://jbrains.ca/permalink/299</link>
      <description>&lt;div class='entry posting' id='entry-_posting_299'&gt;
&lt;div class='posting' id='content-_posting_299'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I made this announcement at a &lt;a href=&quot;http://bit.ly/4CKm1P&quot;&gt;&lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; course in Bucuresti&lt;/a&gt; this week, and I wanted to make it here: I now fully and freely admit that when I use the term &amp;#8220;integration tests&amp;#8221; I confuse people unnecessarily, and so I will stop.&lt;/p&gt;
&lt;p&gt;As a result, you will notice me change from &amp;#8220;integration tests&amp;#8221; to &amp;#8220;integrated tests&amp;#8221;, because I believe the latter term better fits the meaning I intend to convey as well as avoids confusion with what everyone else means by &amp;#8220;integration tests&amp;#8221;. I agree to reserve the term &amp;#8220;integration tests&amp;#8221; for tests that focus on checking the integration points between subsystems, systems, or any nontrivial client/supplier relationship. Integration tests might be integrated tests, and might be collaboration tests. Your choice.&lt;/p&gt;
&lt;p&gt;I apologize for the confusion I created, and appreciate you for hanging in there while I refactor my considerable library of legacy articles. That will take time and I can&amp;#8217;t make it my full-time job.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/299';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/299&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
February 14, 2010  13:53
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/integrated-tests-are-a-scam&quot;&gt;integrated tests are a scam&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 14 Feb 2010 13:53:20 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/299</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>What sessions do you want to see at Agile 2010?</title>
      <link>http://jbrains.ca/permalink/296</link>
      <description>&lt;div class='entry posting' id='entry-_posting_296'&gt;
&lt;div class='posting' id='content-_posting_296'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have already submitted one session to &lt;a href=&quot;http://agile2010.agilealliance.org&quot;&gt;Agile 2010&lt;/a&gt;, and I don&amp;#8217;t know what else to submit for the year. I&amp;#8217;d like to leave one slot open for a potential collaboration (hint, hint), but as for a solo session, what do you think I could present or facilitate that you&amp;#8217;d spend 90 minutes of your precious time attending? I&amp;#8217;d prefer to do something new, which means no &amp;#8220;Integration Tests Are A Scam&amp;#8221; and no &amp;#8220;XP: My Greatest Misses&amp;#8221;, but that doesn&amp;#8217;t mean that I couldn&amp;#8217;t run a session on this topics.&lt;/p&gt;
&lt;p&gt;You could help me by outlining what you might see in a session description in the Agile 2010 program that would attract you over the other sessions. Perhaps I can deliver that very session!&lt;/p&gt;
&lt;p&gt;Thanks for your help.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/296';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/296&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
February 04, 2010  13:56
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2010&quot;&gt;agile 2010&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 04 Feb 2010 13:56:41 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/296</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Using integration tests mindfully: a case study</title>
      <link>http://jbrains.ca/permalink/295</link>
      <description>&lt;div class='entry posting' id='entry-_posting_295'&gt;
&lt;div class='posting' id='content-_posting_295'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p style=&quot;float:right;&quot;&gt;&lt;img src=&quot;http://www.energizedwork.com/images/crew/guspower.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Gus Power commented about the way he uses integration tests in his work.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Interesting series of articles &amp;amp; comments. I also read Steve Freeman&amp;#8217;s article in response to the same topic. It&amp;#8217;s got me thinking about how we work and I thought I&amp;#8217;d take the time to describe it here.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;You define an integration test as &amp;#8220;&amp;#8230; any test whose result (pass or fail) depends on the correctness of the implementation of more than one piece of non-trivial behavior.&amp;#8221; We have many such components that exhibit such non-trivial behaviour in the products we create, many of which are not developed by us. And we have integration tests to verify they work. I&amp;#8217;m not just talking about 3rd party libraries and frameworks here, I&amp;#8217;m referring to the whole system: caching layers. load balancers, &lt;span class=&quot;caps&quot;&gt;DNS&lt;/span&gt; servers, CDNs, virtualization etc. When we build software it only becomes a product or service for our users when it has been deployed into a suitable environment; an environment that typically contains more than just the software we have written and packaged. Since our users&amp;#8217; experience and perception of quality result from their interaction with a deployed instance of the whole system, not just their interaction with the software at a unit level, we have come to value end-to-end integration testing. I believe there&amp;#8217;s merit in testing these components in symphony and will attempt to clarify what kind of integration testing I&amp;#8217;m talking about.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;For a given piece of functionality we write an executable acceptance test in human readable form (for web projects we typically use some domain-specific extensions to selenium, for services we have used &lt;span class=&quot;caps&quot;&gt;FIT&lt;/span&gt; and it&amp;#8217;s ilk, sometimes we roll our own if there&amp;#8217;s nothing expressive enough available). We run it against a deployed version of the application (usually local though not always) which typically has a running web/application server and database. The test fails. We determine what endpoint needs to be created/enhanced and then we switch context down into unit-test land. A typical scenario would involve enhancing a unit test for the url mappings, adding one for the controller, then one for any additional service, domain object etc. When we&amp;#8217;re happy and have tested and designed each of the required units we jump back up a level and get our acceptance test to progress further. The customer steers the development effort as he sees vertical &amp;#8216;slices&amp;#8217; of functionality emerge. The acceptance test is added to a suite for that functional area. The continuous build system will then execute that test against a fully deployed (but scaled down) replica of the production environment, with hardware load balancer, vlans, multiple nodes (session affinity) and so forth. Any additional environmental monitoring (e.g. nagios alerting) is also done as part of this development effort and is deployed into the test environment along with the updated code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Setting up the infrastructure to do this kind of testing takes investment, both initial and ongoing. The continuous build needs to be highly &amp;#8216;parallelized&amp;#8217; so you get feedback from a checkin in 10 mins or less (we&amp;#8217;re heavy users of virtualization, usually VMWare or OpenVZ). The individual acceptance test suites need to be kept small enough to run quickly before check-in.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Benefits of this approach&lt;br /&gt;
* The continuous context-switch between acceptance test and unit test is key to our staying focused on delivering what the customer actually wants.&lt;br /&gt;
* The customer has multiple feedback points that he can learn from and use to steer the development effort.&lt;br /&gt;
* It confirms that the whole system works together &amp;#8211; networking, &lt;span class=&quot;caps&quot;&gt;DNS&lt;/span&gt;, load balancing, automated deployment, session handling, database replication etc.&lt;br /&gt;
* We create additional &amp;#8216;non-functional&amp;#8217; acceptance tests that automatically exercise other aspects of the system such as fail-over and recovery. &lt;br /&gt;
* Upgrades to parts of the system (switches, load balancers, web caches, library versions, database server versions etc.) can be tested in a known and controlled way.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;We&amp;#8217;ve caught a number of integration-related issues using this approach (a few examples: broken database failover due to missing primary keys, captcha validation not working due to a web cache not behaving correctly, data not persisting because one database server had the wrong locale) and stopped them before they have reached our users. We have used the feedback as a basis for improving our products and their delivery at a system level.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;OK this reply has now become far too long :-/ It would of course be good to discuss this in person sometime :)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;mdash;Gus Power&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Thanks for the substantial comment, Gus. For those who don&amp;#8217;t know Gus, he is one of the joint recipients of the 2009 Gordon Pask Award for contribution to Agile practice. I invite you to &lt;a href=&quot;http://www.energizedwork.com/&quot;&gt;follow his work and learn from his example&lt;/a&gt;. On to the substance of Gus&amp;#8217; comment.&lt;/p&gt;
&lt;p&gt;Gus, it appears you do not use integration tests to check basic behavior exhaustively. While I try not to use integration tests to check basic behavior at all, I mostly hope to stop programmers from attempting to write exhaustive integration tests that check basic correctness conditions. I wrote in &lt;a href=&quot;http://bit.ly/9Sybn0&quot;&gt;Not Just Slow: Integration Tests are a Vortex of Doom&lt;/a&gt; about the vicious cycle I see when teams rely on integration tests to check basic correctness. I encourage them to stop that particular insanity. I would hesitate to use integration tests as even smoke tests for basic correctness, but if I found myself in a situation where I needed to write such tests, I&amp;#8217;d do it, then look for ways to render them obsolete.&lt;/p&gt;
&lt;p&gt;Also, you mention writing &amp;#8220;human-readable acceptance tests&amp;#8221;, and I certainly use such tests in my work. When I counsel against using integration tests, I advise it within the context of programmer tests only. While I strongly encourage teams to allow even some of their acceptance tests to check policy or business rule behavior directly and in isolation, I understand and agree that one generally needs to write some acceptance tests as integration tests.&lt;/p&gt;
&lt;p&gt;In general, you describe using integration tests quite purposefully, mindfully, and responsibly. I expect no less from a practitioner of your caliber. I would truly enjoy working with you on a project.&lt;/p&gt;
&lt;p&gt;Finally, you mention that your integration tests catch system-level issues, such as a broken database schema, mistaken cache integration, and so on. I expect integration tests to find only, or at least mostly, these problems. None of these sound like basic correctness problems.&lt;/p&gt;
&lt;p&gt;So Gus, I appreciate you for writing a great description of using integration tests well. I wish we had more examples like this. I truly wish I &lt;strong&gt;saw&lt;/strong&gt; more examples like this. Sadly, I don&amp;#8217;t: I see teams trying to check basic correctness issues with plodding, brittle, misleading tests. For those, I stress the need to eliminate integration tests.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/295';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/295&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 31, 2010  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/integrated-tests-are-a-scam&quot;&gt;integrated tests are a scam&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 31 Jan 2010 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/295</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Not Just Slow: Integration Tests are a Vortex of Doom</title>
      <link>http://jbrains.ca/permalink/294</link>
      <description>&lt;div class='entry posting' id='entry-_posting_294'&gt;
&lt;div class='posting' id='content-_posting_294'&gt;
&lt;div style='text-align: justify'&gt;
&lt;style type=&quot;text/css&quot;&gt;
&lt;p&gt;.reader-comment {&lt;br /&gt;
  font-size: small;&lt;br /&gt;
  font-weight: italic;&lt;br /&gt;
}&lt;/p&gt;
&lt;/style&gt;
&lt;p style=&quot;float:right;&quot;&gt;&lt;img src=&quot;http://a1.twimg.com/profile_images/53743804/ArtemMarchenko-BlackWhite_bigger.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote style=&quot;.reader-comment;&quot;&gt;
&lt;p style=&quot;.reader-comment;&quot;&gt;&amp;#8220;Aha! So @jbrains is really against the integration tests just because they are too slow for hourly use&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote style=&quot;.reader-comment;&quot;&gt;
&lt;p style=&quot;.reader-comment;&quot;&gt;It reminds me about the Ferrari IT story (XP team, dozens of deployments a year on many continents) that started from getting a big visible counter of a total number of tests and wrote just big amount of &lt;strong&gt;any&lt;/strong&gt; tests first. You need to start somewhere and getting large integration tests is definitely better than nothing. As long as you are prepared to improve the testing practices later. &amp;mdash;Artem Marchenko&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I agree with this sentiment. I tell the story of my very first attempt at test-first programming&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn5f691627262dafca9ce11b15b45a5e91100e9144&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;, how I wrote about 125 tests, many of which fit my definition of &amp;#8220;integration test&amp;#8221;, and which took 12 minutes to execute. This meant that, on average, I only made 8-12 edits per hour when writing that code. I recognized then, and I still recognize now, that even making only 8-12 edits per hour&amp;mdash;4-6 edits per hour towards the end&amp;mdash;that I produced better software than I did when I would write code almost continuously for several hours at a time. As much as I disparage those integration tests today, I appreciated them a great deal at the time I wrote them. I find integration tests useful for finding system-level problems, as the first step in fixing a mistake, and if I genuinely can&amp;#8217;t write a focused object test, then I will usually write an integration test.&lt;/p&gt;
&lt;p&gt;As you say, Artem, I simply don&amp;#8217;t stop there.&lt;/p&gt;
&lt;p&gt;When I label integration tests a &lt;em&gt;scam&lt;/em&gt;, I mean to emphasize the self-replicating nature of integration tests. It starts simply enough: you write a handful of integration tests, which give you a lot of freedom to implement your design in a way that introduces unfortunate dependencies, which makes focused object testing quite difficult. As a result, you will probably resign yourself to writing more integration tests, which do nothing to improve your dependency problems, and the cycle begins again.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/artem-marchenko/cycle-of-pain-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Integration tests help cause pain, even though they appear to help reduce pain. Therein lies the scam.&lt;/p&gt;
&lt;p&gt;I must acknowledge this: if you started writing tests this week, or this month, or even this year, then you will probably benefit more from writing integration tests than trying to write perfectly focused object tests. I have said and written elsewhere that I believe a programmer needs to write about 1500 to burn into her brain the basic patterns of good tests. Even so, as you write those tests, I want you to remain aware of the cost. Even if you don&amp;#8217;t know how to write a good, focused object test, if you &lt;em&gt;want&lt;/em&gt; to write more such tests, and especially if you &lt;em&gt;try&lt;/em&gt; to write more such tests, then I will have completed the first phase of my mission to eradicate programmer reliance on integration tests to show the basic correctness of their code.&lt;/p&gt;
&lt;p&gt;Join us! Turn one integration test into a small suite of focused object tests today. If you don&amp;#8217;t yet see how to replace an entire integration test with equivalent focused object tests, then write at least one or two focused object tests along side the integration test. Try it. I promise, you&amp;#8217;ll like it.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn5f691627262dafca9ce11b15b45a5e91100e9144&quot;&gt;&lt;sup&gt;1&lt;/sup&gt; I use the term &lt;em&gt;test-first programming&lt;/em&gt; to refer to test-driven design without the evolutionary design part. With test-first programming, I develop a specific design, then I use tests to help me type it in correctly.&lt;/p&gt;
&lt;p&gt;One last comment to my good friend Artem: please don&amp;#8217;t &lt;a href=&quot;http://www.google.com?q=lullaby+words&quot;&gt;put me to sleep&lt;/a&gt; with the word &amp;#8220;just&amp;#8221;!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/294';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/294&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 28, 2010  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/integrated-tests-are-a-scam&quot;&gt;integrated tests are a scam&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 28 Jan 2010 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/294</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The importance of aligning authority with responsibility</title>
      <link>http://jbrains.ca/permalink/293</link>
      <description>&lt;div class='entry posting' id='entry-_posting_293'&gt;
&lt;div class='posting' id='content-_posting_293'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Some ideas simply click with you. I remember reading about &amp;#8220;the alignment of authority and responsibility&amp;#8221; for the first time and feeling how much that idea resonated with me.&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; I worked at &lt;span class=&quot;caps&quot;&gt;IBM&lt;/span&gt; at the time, on the (then) Net.Commerce project, and after about a year, I began to feel some responsibility for delivering on a project plan without any authority to negotiate scope, priorities, or timing with a stakeholder. I remember clearly staring at a whiteboard that waited for me to put work estimates next to a long list of tasks. I refused to do it.&lt;/p&gt;
&lt;p&gt;&amp;#8220;I don&amp;#8217;t know long it will take,&amp;#8221; I told my manager.&lt;/p&gt;
&lt;p&gt;&amp;#8220;Forget about getting the numbers right. Just give me something to put in the plan.&amp;#8221; I knew he supported me, but he needed me to understand the difficulty in his position. He felt a similar powerlessness and asked me to help him work through it. I felt quite sad about it. While his response didn&amp;#8217;t help me in the short term, but it opened my eyes to what I now know to call &lt;a href=&quot;http://bit.ly/7IicUj&quot;&gt;Schedule Chicken&lt;/a&gt;. I felt truly powerless in having to make a commitment to a schedule in which I did not believe.&lt;/p&gt;
&lt;p&gt;I had had project managers hold me to rough estimates in the past. I had read about the &amp;#8220;best practice&amp;#8221; called &lt;a href=&quot;http://bit.ly/7w7NTG&quot;&gt;No Hallway Estimates&lt;/a&gt;. I felt that Management (that nebulous machine that doesn&amp;#8217;t really exist) foisted responsibility on me without the authority I needed to accept and deliver on that responsibility.&lt;/p&gt;
&lt;p&gt;I had had enough. I started walking up and down the halls, asking, &amp;#8220;Why do you make me guess? I always guess wrong.&amp;#8221; Within two years, I left &lt;span class=&quot;caps&quot;&gt;IBM&lt;/span&gt; with serious &lt;em&gt;Authority Deficit Disorder&lt;/em&gt;. If you find yourself in a position of having to manage people with low authority and high responsibility, then you need to know the &lt;strong&gt;Law of Conservation of Authority and Responsibility&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;People will correct an imbalance of authority and responsibility, whether you want them to or not, and on their schedule, not yours.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Consider the case of Jane, who has spent two years suffering from Authority Deficit Disorder. If you don&amp;#8217;t give her more authority, then she will reach her breaking point, disrupt your organization, and eventually leave. Unfortunately, if you decide to give her more authority, then she will spend about two years demanding authority without responsibility, just to compensate for her two years of Authority Deficit Disorder. She will demand it. Either way, Jane will disrupt your organization, your plans, and probably your life. You will suffer, whether you deserve it or don&amp;#8217;t.&lt;/p&gt;
&lt;p&gt;So the Law of Conservation of Authority and Responsibility has a corollary.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When a person suffering from Authority Deficit Disorder has reached his breaking point, nothing you do can remedy the situation, except to wait.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Jane spent two years suffering, so she probably needs two years to recover. I understand how powerless and unfair that is, but I don&amp;#8217;t find it any less unfair than the treatment Jane endured. This leads me to conclude&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When you withhold authority, but insist on responsible behavior, everyone loses.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I don&amp;#8217;t know how to solve that problem without simply balancing authority and responsibility better.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn&quot;&gt;&lt;sup&gt;1&lt;/sup&gt; I haven&amp;#8217;t read it, but found at least one reference to this idea in Harry Chambers and Robert Craft&amp;#8217;s &lt;a href=&quot;http://bit.ly/7wRyAm&quot;&gt;&lt;em&gt;No Fear Management&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/293';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/293&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 25, 2010  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coaching&quot;&gt;coaching&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/consulting&quot;&gt;consulting&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 25 Jan 2010 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/293</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Lend your voice and face to Agile India 2010</title>
      <link>http://jbrains.ca/permalink/291</link>
      <description>&lt;div class='entry posting' id='entry-_posting_291'&gt;
&lt;div class='posting' id='content-_posting_291'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I will have the opportunity to address the &lt;a href=&quot;http://www.agileindia.org&quot;&gt;Agile India 2010&lt;/a&gt; events in Mumbai and Bangalore this month on a simple topic:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What silly thing do you want people on software projects to stop doing in 2010?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&amp;#8217;d love your help. A number of people have already responded on Twitter with the hashtag &lt;a href=&quot;http://search.twitter.com/search?q=%23StopIt2010&quot;&gt;#StopIt2010&lt;/a&gt;, but I invite you to go one step further. Voice your opinion, with video if you can, and audio if you don&amp;#8217;t have a camera handy, answering the question I&amp;#8217;ve asked above.&lt;/p&gt;
&lt;p&gt;Please introduce yourself, say &amp;#8220;Hello&amp;#8221; to our audience, and give the 20-second version of your rant. You can practise by writing your rant out in 140 characters first, then reading it.&lt;/p&gt;
&lt;p&gt;If you can record video, then please simply upload the video somewhere (youtube.com, vimeo.com, dropio.com), add a comment to this entry, and tweet your link with the hashtag #StopIt2010.&lt;/p&gt;
&lt;p&gt;If you can only record audio, then please package the audio and a nice, big picture of you, and upload it somewhere, like dropio.com, add a comment to this entry, and tweet your link with the hashtag #StopIt2010.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ll pick my favorites and include them in my keynote.&lt;/p&gt;
&lt;p&gt;So please&amp;#8230; go for it. Rant away. Submit more than one, if you like. You can use this template, if it helps you:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hello to everyone at Agile India! My name is J. B. Rainsberger and I want programmers to stop insisting that writing the tests after the code is just as good as writing the tests first. Stop it!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Thanks!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/291';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/291&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 10, 2010  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 10 Jan 2010 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/291</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Introduction to Agile and the Theory of Constraints</title>
      <link>http://jbrains.ca/permalink/290</link>
      <description>&lt;div class='entry posting' id='entry-_posting_290'&gt;
&lt;div class='posting' id='content-_posting_290'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&lt;object width=&quot;400&quot; height=&quot;300&quot;&gt;&lt;param name=&quot;allowfullscreen&quot; value=&quot;true&quot; /&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot; /&gt;&lt;param name=&quot;movie&quot; value=&quot;http://vimeo.com/moogaloop.swf?clip_id=7858952&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1&quot; /&gt;&lt;embed src=&quot;http://vimeo.com/moogaloop.swf?clip_id=7858952&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1&quot; type=&quot;application/x-shockwave-flash&quot; allowfullscreen=&quot;true&quot; allowscriptaccess=&quot;always&quot; width=&quot;400&quot; height=&quot;300&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;p&gt;&lt;a href=&quot;http://vimeo.com/7858952&quot;&gt;J. B. Rainsberger, &amp;#8220;Theory of Constraints&amp;#8221;, Agileee conference, 2009&lt;/a&gt; from &lt;a href=&quot;http://vimeo.com/user2696171&quot;&gt;Alexey Krivitsky&lt;/a&gt; on &lt;a href=&quot;http://vimeo.com&quot;&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;I would like to find people willing to add subtitles to this video in any language, including transcribing it in English. If you&amp;#8217;d like to do this, then please do it! I only ask that you email me with a link to the resulting video so I can add a link from here. Thanks.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/290';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/290&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 20, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coaching&quot;&gt;coaching&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 20 Dec 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/290</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Healthy Eating for the Road Warrior... in Toronto</title>
      <link>http://jbrains.ca/permalink/287</link>
      <description>&lt;div class='entry posting' id='entry-_posting_287'&gt;
&lt;div class='posting' id='content-_posting_287'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Alistair McKinnell recently exposed me to a great vegan restaurant in Toronto, and I&amp;#8217;d like to pass the information on to my fellow road warriors looking for healthy eating while on the road. If you have a gig coming up in downtown Toronto, then I highly recommend &lt;a href=&quot;http://www.fressenrestaurant.com/&quot;&gt;&lt;strong&gt;Fressen&lt;/strong&gt; at 478 Queen St W&lt;/a&gt;. I ate there with a few associates and new friends after Agile Tour Toronto this week and thoroughly enjoyed it.&lt;/p&gt;
&lt;p&gt;They have a tapas menu, larger appetizers, main meals, soup and dessert. Like most good tapas/meze/maza, I can feel as sated sharing a half-dozen small dishes as I would with a standard, North-American-sized main dish. I especially enjoyed the sweet potato soup, tomato and cucumber salad, marinated olives, beet salad (that surprised me) and, jicama/mango salad and, of course, the chocolate terrine dessert they served Tuesday night.&lt;/p&gt;
&lt;p&gt;Sadly, their online menu shows dinner from summer 2006, so you&amp;#8217;ll just have to go to see the most recent menu. For a party of four, I recommend 7 to 9 tapas dishes, soup, and the four of you can probably share the dessert. I am 5&amp;#8217;10&amp;quot;/235 and love to eat, so take it from me that 1/4 of that dessert satisfies!&lt;/p&gt;
&lt;p&gt;I see from their site an address for &amp;#8220;Urban Herbivore&amp;#8221;, but no link, so try going there at your own risk. I&amp;#8217;d love to try it.&lt;/p&gt;
&lt;p&gt;A place like Fressen simply cements my new-found love affair with the Queen/Spadina area of Toronto, which we&amp;#8217;ve got to know better as business travelers than we ever got to know as residents of Toronto. I can design an ideal business traveler&amp;#8217;s day in the area:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Morning espresso at Dark Horse Espresso Bar around Spadina/Sullivan&lt;/li&gt;
	&lt;li&gt;Lunch at Fressen&lt;/li&gt;
	&lt;li&gt;Take-back-to-the-hotel dinner at Fresh on Spadina&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I could do that every day, easily.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/287';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/287&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 23, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/business-travel&quot;&gt;business travel&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 23 Oct 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/287</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>&quot;One of the high points of the whole conference for me&quot;</title>
      <link>http://jbrains.ca/permalink/286</link>
      <description>&lt;div class='entry posting' id='entry-_posting_286'&gt;
&lt;div class='posting' id='content-_posting_286'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I&amp;#8217;d like to share one very positive bit of feedback from my Agile 2009 sessions:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;XP: My Greatest Misses 2000-2009&amp;#8230; was actually one of the high-points of the whole conference for me.  Amongst other things, you talked about the soft skills you need as a consultant which was deeply fascinating.  I still remember your &amp;#8220;recommendation&amp;#8221; to accept that everything you say will be given the harshest interpretation, and to give what other people say the most generous interpretation.  That was an &amp;#8220;epiphany&amp;#8221; moment for me which has already made a positive change in my life (on many occasions). &lt;span style=&quot;white-space: nowrap;&quot;&gt;&amp;ndash;Keith Erskine&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/286';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/286&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 06, 2009  12:11
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile-2009&quot;&gt;agile 2009&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 06 Oct 2009 12:11:39 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/286</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>How test-driven development works (and more!)</title>
      <link>http://jbrains.ca/permalink/285</link>
      <description>&lt;div class='entry posting' id='entry-_posting_285'&gt;
&lt;div class='posting' id='content-_posting_285'&gt;
&lt;div style='text-align: justify'&gt;
&lt;style type=&quot;text/css&quot;&gt;
.diagram {
  border: 1px solid;
  display: block;
  margin-left: auto;
  margin-right: auto;
}
&lt;/style&gt;

&lt;p&gt;It surprises me, from time to time, how much I still need to justify test-driven development to prospects and would-be course attendees. Many feel that &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; has &lt;a href=&quot;http://bit.ly/DlqgE&quot;&gt;crossed the chasm&lt;/a&gt;, while others still see &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; as a cultish practice worth marginalizing. I take some blame for those who find &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; cultish, because until now I haven&amp;#8217;t had a strong, sensible, theoretical basis to justify &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; as an idea. I could do no better than &amp;#8220;it works for me&amp;#8221; or &amp;#8220;my friends like it&amp;#8221;. That has changed since I&amp;#8217;ve started giving my talk &amp;#8220;Introduction to Agile with the Theory of Constraints&amp;#8221; in which I use concepts from Theory of Constraints to motivate the practices of agile software development, notably those of extreme programming. If you buy in to ideas from Theory of Constraints or Lean Manufacturing, then I think I now have a stronger argument to justify the core programming practices in extreme programming in particular and agile software development in general. I don&amp;#8217;t even need all of the Theory of Constraints but rather a simple appeal to fundamental concepts in Queuing Theory.&lt;/p&gt;
&lt;h2&gt;Queuing Theory?&lt;/h2&gt;
&lt;p&gt;Yes, Queueing Theory. (And I don&amp;#8217;t plan to capitalize that any longer.) I don&amp;#8217;t proclaim to have any particular expertise in this area, but I have already seen how to use queuing theory ideas in optimizing network-based systems, and I see no reason we couldn&amp;#8217;t extend that to software delivery systems. Better, I only need to appeal to a single idea from queuing theory to make my point.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Given a process B, which follows a process A, sometimes in performing B we need to perform some of A again. We can remove the need to rework by taking some portion of process B and performing it before process A&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn929200631b63d58b76efdc50683459021a49108d&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This merits a diagram. If we have this problem&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/general_loopback_problem.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;then we can solve it by doing this&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/general_loopback_solution.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;and the resulting system will work more efficiently by removing wasteful rework. I assume here that we derive no significant benefit from the rework itself, which I suppose I must justify, but let&amp;#8217;s not ruin a good story with the truth. Here I&amp;#8217;ve described the general problem, and by applying it to software development, I can&amp;#8230; well, I find it more effective if I save the punchline for the end.&lt;/p&gt;
&lt;h2&gt;Winston Royce, 1970, revisited&lt;/h2&gt;
&lt;p&gt;I imagine you know this diagram&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/royce_diagram.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;and appreciate that Royce wrote in his now infamous paper that this single-phase waterfall &lt;em&gt;is risky and invites failure&lt;/em&gt;. If you don&amp;#8217;t appreciate that, then I cannot strongly recommend enough your reading the &lt;a href=&quot;http://bit.ly/IWtmq&quot;&gt;original paper&lt;/a&gt; in its entirety, rather than stopping after page 2 as most people have done&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn8f486c28234de4a917f7dcb3ea5c3f9762197b3b&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;We can apply the queuing theory result I&amp;#8217;ve just cited to this diagram and generate some interesting conclusions. I&amp;#8217;ll start by focusing in on this portion of the system&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/code_then_test.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;We write code, then we test it. Sadly, we occasionally find a &lt;em&gt;bug&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn37407f6fcf324ef95b587da692e9f3f5fdfe9544&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/em&gt; which makes us change the code we wrote after we thought we&amp;#8217;d finished it. That makes a loop of the type we can unravel with our queueing theory result.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/code_then_test_loop.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Since &amp;#8220;coding&amp;#8221; is process A and &amp;#8220;testing&amp;#8221; is process B, we need to do some testing before we start coding.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/test_then_code_then_test.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It doesn&amp;#8217;t take long for this to become a virtuous loop where we writing only the code we need to write in order to pass the tests we write.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/test_first_programming_loop.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I use the term &lt;strong&gt;test-first programming&lt;/strong&gt; to describe this cycle&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn42800d5a26f388c8d6e8e3ffa47a5986f300a681&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. When we practise test-first programming, we design as much detail as we can before writing the first test, then use the tests to help us type in our implementation correctly. Most teams most of the time can use test-first programming to reduce their &lt;del&gt;defect&lt;/del&gt; mistake count to near zero, which increases their productivity and improves their ability to deliver, by helping them waste less time agonizing over whether to fix mistakes late in a release. I started this way in 2000 when I first discovered &lt;a href=&quot;http://www.junit.org&quot;&gt;JUnit&lt;/a&gt; and stopped making silly mistakes in the code I wrote, which I found significantly beneficial in helping me code more confidently. I still designed most of what I built mostly up front.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/design_then_do_tfp.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;After a while, though, I recognized a new process loop: I found some parts of my design difficult to test, or I found some parts of my design didn&amp;#8217;t fit together when I tried to type them in.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/design_then_do_tfp_then_do_design.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Returning to our queuing theory result, since &amp;#8220;designing&amp;#8221; is process A and &amp;#8220;doing test-first programming&amp;#8221; is process B, we need to do some test-first programming before we start designing.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/do_tfp_then_design_then_do_tfp.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It doesn&amp;#8217;t take long for this to become a virtuous loop where we check our design ideas as we think of them and implement only the parts of the design we can justify needing. When we include &lt;em&gt;refactoring&lt;/em&gt; in our practice, we can confidently &amp;#8220;under-design&amp;#8221; compared to the level of design we expect to need by the end of a task, which I believe amounts to designing appropriately for the code we need to implement right now. This virtuous loop combines test-first programming and evolutionary design, including guiding principles like &amp;#8220;you aren&amp;#8217;t gonna need it&amp;#8221; and the &lt;a href=&quot;http://www.jbrains.ca/permalink/276&quot;&gt;four elements of simple design&lt;/a&gt; into &lt;strong&gt;test-driven development&lt;/strong&gt;, where we check our implementation by running tests and we check our design ideas by writing tests.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/test_driven_development_loop.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Where test-first programming helps most teams most of the time reduce their mistake count to near zero, test-driven development helps them reduce their design inventory&amp;mdash;mostly code that gets in our way because it doesn&amp;#8217;t actively help us deliver a feature&amp;mdash;to near zero. This further increases productivity and improves their ability to deliver by helping them waste less time agonizing over design problems they  find costly to fix. I waited until I&amp;#8217;d spent an entire release practising test-first programming before doing more test-driven development. My transition consisted of trying to do less and less up-front design for each task, letting myself feel comfortable with each new step. Within two years I estimate I designed about 5% as much up front as I did before I started practising test-first programming. I can&amp;#8217;t measure the corresponding improvement in my design, but I look back at projects that took 3 months before I practised test-driven development that I now feel confident I could complete&amp;mdash;truly complete&amp;mdash;in one week. Of course, we can&amp;#8217;t stop here!&lt;/p&gt;
&lt;p&gt;Enter our friend &lt;em&gt;analysis&lt;/em&gt;. To simplify the discussion, I will treat &lt;em&gt;analysis&lt;/em&gt; as &amp;#8220;discovering the features we want in our software&amp;#8221; without forcing myself to state too precisely how that happens&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fnf209b0d3e58a3af938d06622092e2d22fe5576ae&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;. Once again, we have our familiar situation.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/analyze_then_do_tdd_loop.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Once again, we face the situation where in the process of implementing features we discover new features we need, current features we don&amp;#8217;t need, and learn new things about features we know we need to build. This adds to our analysis, meaning that we should try test-driving some features before we try to implement others.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/do_tdd_then_analyze_then_do_tdd.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It doesn&amp;#8217;t take long for this to become a virtuous loop in which our desire to implement (and deliver!) features drives them ever smaller, as we extract more concentrated value out of each one&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn60c0904d8c5b974a81d7880859d00436580b0ecd&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;. When we implement feature 12 we learn something about features 23, 30 and 52. We might decide not to deliver feature 30 any more. We might decide to expand feature 23 to encompass a few more key cases. We might decide to rush feature 52 to the top of the pile. Most teams most of the time find that this cycle helps them reduce the number of rarely- or infrequently-used features in their system&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fne0379ee62ae77f8ef9665f756f0d1fc1dfe65ac1&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;. This yet again increases productivity and improves their ability to deliver meaningful software to their stakeholders by eliminating the time wasted on delivering too much of a feature too soon, the time wasted on entire features we thought we needed but realized we don&amp;#8217;t, and the time wasted arguing about what a feature means, rather than writing examples together: business-oriented tests that describe how a feature works in enough detail for the business and technical project community to agree on the conditions of satisfaction for delivering the feature.&lt;/p&gt;
&lt;p&gt;I call this &lt;strong&gt;behavior-driven development&lt;/strong&gt;, and refuse to spell it with the &lt;em&gt;u&lt;/em&gt; that provides as much value to the word as your appendix does to your body&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn5633c401863a40d26bdd6d2b1d7acd5f367fdd24&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/behavior_driven_development_loop.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Once again, I didn&amp;#8217;t coin the phrase, and some might argue against the way I use it, but I find it apt. This cycle include practices like business and technical people writing examples together, feature injection, feature splitting, and value-based (rather than cost-based) planning.&lt;/p&gt;
&lt;p&gt;At this point, I think I&amp;#8217;ve done my job. I believe I&amp;#8217;ve justified not only test-first programming or test-driven development, but full-on behavior-driven development, using only a single result from fundamental queuing theory. I&amp;#8217;ve made only a single assumption&amp;mdash;that we agree on the appropriateness of applying queuing theory to a software development system. I&amp;#8217;ve tried to add as little as possible to my reasoning in order to keep it as context-free as possible. As a result I claim that most teams most of the time will benefit from moving along the path from code-and-fix to test-first programming to test-driven development to behavior-driven development.&lt;/p&gt;
&lt;p&gt;Now, for homework, what happens when we consider these processes?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/theory_of_bdd/bdd_then_deploy.jpg&quot; class=&quot;diagram&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Surely at least one you&amp;#8217;ve needed to deliver more features for software you&amp;#8217;d already deployed. How well does that work? What problems do you encounter? What if you applied our new favorite queuing theory result to that rework loop?&lt;/p&gt;
&lt;hr /&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn929200631b63d58b76efdc50683459021a49108d&quot;&gt;&lt;sup&gt;1&lt;/sup&gt; I really need a citation for this, and when I find it, I will place it here.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn8f486c28234de4a917f7dcb3ea5c3f9762197b3b&quot;&gt;&lt;sup&gt;2&lt;/sup&gt; I digress, but I really can&amp;#8217;t help myself on that one.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn37407f6fcf324ef95b587da692e9f3f5fdfe9544&quot;&gt;&lt;sup&gt;3&lt;/sup&gt; Also known as &lt;em&gt;defect&lt;/em&gt; or, for the truly congruent, &lt;em&gt;mistake&lt;/em&gt;.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn42800d5a26f388c8d6e8e3ffa47a5986f300a681&quot;&gt;&lt;sup&gt;4&lt;/sup&gt; Clearly I didn&amp;#8217;t coin the phrase, but I know many people who treat &amp;#8220;test-driven development&amp;#8221; as a simple renaming of &amp;#8220;test-first programming&amp;#8221;, and I believe making a stronger distinction adds real value to the conversation.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fnf209b0d3e58a3af938d06622092e2d22fe5576ae&quot;&gt;&lt;sup&gt;5&lt;/sup&gt; I don&amp;#8217;t think &amp;#8220;gathering requirements&amp;#8221;, as though we could pick them like berries, fits as a metaphor. I like &amp;#8220;trawling for requirements&amp;#8221;, which I believe I first read in Mike Cohn&amp;#8217;s &lt;a href=&quot;http://bit.ly/223n5D&quot;&gt;&lt;em&gt;User Stories Applied&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn60c0904d8c5b974a81d7880859d00436580b0ecd&quot;&gt;&lt;sup&gt;6&lt;/sup&gt; We can easily apply the &amp;#8220;Pareto Distribution&amp;#8221; here in that we can deliver 80% of the value from implementing 20% of the feature.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fne0379ee62ae77f8ef9665f756f0d1fc1dfe65ac1&quot;&gt;&lt;sup&gt;7&lt;/sup&gt; You recall that Jim Johnson of the Standish Group reported in 1994 that 45% of developed features are &amp;#8220;never used&amp;#8221;. As I recall, only 7% of features were used very frequently.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn5633c401863a40d26bdd6d2b1d7acd5f367fdd24&quot;&gt;&lt;sup&gt;8&lt;/sup&gt; My Canadian and British brethren and sistren be damned. I assert my right as a Canadian to choose the British spelling when I prefer it and the American spelling when it saves me time.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/285';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/285&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 02, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/stories&quot;&gt;stories&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/consulting&quot;&gt;consulting&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 02 Oct 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/285</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Questions about feedback from Agile 2009</title>
      <link>http://jbrains.ca/permalink/284</link>
      <description>&lt;div class='entry posting' id='entry-_posting_284'&gt;
&lt;div class='posting' id='content-_posting_284'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I presented three 90-minute sessions at Agile 2009 with varying degrees of success. Most notably, in two of my sessions, where I expected to use a flipchart and draw diagrams as I spoke, I found myself in long, narrow rooms with in excess of 100 people. That meant that few people could see the flipchart, which proved a sizable disadvantage for them. To you who attended my sessions, but couldn&amp;#8217;t see what I wrote on the flipchart, I apologize and have corrected the problem. Frankly, I feel good about having audiences large enough to have this problem!&lt;/p&gt;
&lt;p&gt;While I felt quite good about the majority of attendee feedback, I did receive some feedback that puzzled me. I wanted to post that material here in hopes that if you gave me some of this feedback that you&amp;#8217;d email me and help me understand either what you meant to say or how you intended me to use the information you gave me. I really do not want to lay your feedback to waste, but if I don&amp;#8217;t understand it and can&amp;#8217;t use it, then I simply won&amp;#8217;t change anything related to it.&lt;/p&gt;
&lt;p&gt;So if you gave any of this feedback, then please answer my questions by sending me email at the address you can see on every page.&lt;/p&gt;
&lt;h2&gt;Introduction to Agile with the Theory of Constraints&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;It&amp;#8217;s boring to listen for 90 minutes; get the audience involved too.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I think this could work well, but I don&amp;#8217;t know how to do that with this session in particular. Can you suggest one or two ways I could have got you involved in the session that you would have liked?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Room too big for just flipchart&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I gave this talk at AgileEE with a tablet PC as an e-flipchart and that appeared to work much better. I think I&amp;#8217;ve solved this problem.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;It may have been a little bit more organized and focused.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I appreciate this perspective. I have changed the session to include a 20-minute introduction of all the key Theory of Constraints topics: throughput accounting, bottlenecks, and even production/production capacity. I think this helps give the session a more focused feel. I like to keep the talk quite fluid, because I don&amp;#8217;t know how to cover everything important in only 90 minutes. To talk about all the common agile practices, I think, would require a half day. I also don&amp;#8217;t want to give exactly the same talk every time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;References to studies, concepts could use prepared diagrams, references so the flow isn&amp;#8217;t interrupted.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I like this idea. As I give this talk more frequently, I will start identifying common bits that I use in every talk, and can start preparing some material like that. I recently gave this talk privately to a client and included some prepared, but handwritten, slides. I think it worked well, so I rather appreciate the suggestion.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Make sure to emphasize importance of bottleneck, provide facts and background [instead of &amp;#8216;some study I read&amp;#8217;], inventory == all work in progress&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I appreciate these suggestions. I know I forgot bottlenecks, and have introduced a first-pass to the talk that ensures I talk about the key Theory of Constraints concepts, including throughput accountings, bottlenecks, and production/production capacity. When I gave the talk at AgileEE and again privately to a client, I made sure to highlight all these areas in the first 15 minutes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I understand the desire to make the references more meaningful by using less handwaving. I admit that I simply don&amp;#8217;t care that much about these references for such a session, and recognize that others care more about that. I suppose I have the attitude that I don&amp;#8217;t intend my talk to fit into the academic style, even though I see how one could consider that a cop-out.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Puzzle: you present solutions, can you also include the problem-solving part?&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I don&amp;#8217;t quite understand this request. Can you tell me more about what you mean? Can you give me an example of what you&amp;#8217;d expect?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;It would have been nice to hear some positive arguments about the &amp;#8216;softer side&amp;#8217; (team work, etc.)&amp;#8230;&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I can&amp;#8217;t interpret this comment meaningfully, because I don&amp;#8217;t know at all how it relates to this talk. Can you give me an example of a positive argument about teamwork that you think I could have included?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;&amp;#8230;and tips for selling agile to customers (the point of view was a bit business-restricted).&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I simply don&amp;#8217;t understand this comment. What do you mean by &amp;#8220;business-restricted&amp;#8221;?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Regarding selling agile to customers, I discuss this issue in detail in a different talk entitled &amp;#8220;Strategic Selling and Agile&amp;#8221;, which I perform with Niraj Khanna.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;I would have liked a hand-out to help me know the outline/main points of the talk&amp;#8230;.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I agree that that would help, and as I give any talk more frequently, an outline emerges. In the most recent version of this talk, I gave an outline that I believe helped the audience better anticipate the content of the talk.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Also, references to books mentioned would be helpful on hand-out.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I will include a reference to a librarything.com list in future versions of the talk.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;I found it difficult to take notes on everything because he talked quickly.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I appreciate the difficulty in taking notes when someone speaks quickly. I do try to speak at a more reasonable pace, but frankly I don&amp;#8217;t know how easily nor how quickly I&amp;#8217;ll manage to make a lasting change there. I will try.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Created slides would have been easier to follow, but you&amp;#8217;d still want flip charts.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Thank you for acknowledging the value of both prepared material and spontaneous material. I will include some prepared material in future versions of this talk.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Have more expertise in ToC&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I suppose you mean that I should learn more about ToC. I agree that that could help, but I don&amp;#8217;t yet see how more expertise in ToC would improve this talk in particular. Can you give me an example of how that would have helped?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;In more recent versions of this talk I make a point of asking the audience whether anyone considers themselves an expert in Theory of Constraints. I then acknowledge my relatively broad and shallow knowledge of the topic and ask them to forgive any mistakes I make or correct me gently.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Show some real examples of actual changes and how they helped change those critical parameters [meaning, I think, throughput, inventory, and operating expenses.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I really like this idea and have begun to think about how to include this in the 90-minute version of this talk, even though I find the short version already overflowing with material that I don&amp;#8217;t usually get to talk about. In a longer version of the talk I&amp;#8217;d find it easier to include such information.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Good, informative but heavy of XP practices, so less interesting to me.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I started learning about agile with XP, so I find it natural to use mostly XP examples. Which non-XP practices would you like me to have addressed? Perhaps I can do that some other way for you.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Slides would be helpful.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I had two talks with the same issue. I didn&amp;#8217;t expect an audience of over 100 people in each one. Would you have preferred slides because you prefer them as reading material, or because you couldn&amp;#8217;t see the flipchart, or for some other specific reason? I prefer not to assume to know the significance of your interest in slides. -&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Shorter.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Understood. What would you suggest I cut?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Some facts wrong. Some sources quoted wrong.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Please believe me when I say that I made any such mistake unintentionally. Can you remember any facts or sources that I got wrong? I&amp;#8217;d like to correct myself in future versions of the talk.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Wanted a bit more rigor around ToC, based on [the] title.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Can you give me an example of how I could have increased rigor around ToC for future versions of this talk?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Integration Tests Are A Scam&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Not testable prior to presentation to customer&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What do you mean by &amp;#8220;testable prior to presentation by customer&amp;#8221;?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Didn&amp;#8217;t address some of the bigger problems we have like how to test integration + DB (unintelligible) quickly&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I couldn&amp;#8217;t read one key word in this comment. I would appreciate the commenter clarifying what he or she wrote.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Made a meal of explaining something quite simple&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I think ideas derive power from simplicity, so I don&amp;#8217;t necessarily view this as a negative. Moreover, if these concepts are so simple, then why isn&amp;#8217;t everyone doing it?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Should have prepared charts&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I don&amp;#8217;t quite agree with the &amp;#8220;should&amp;#8221; party, but I do plan to use e-flipcharts for future presentations. I did this at AgileEE 2009 and it looks like it will work well and can leave attendees with something to which they can later refer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Good presentation, more for developers only, which I was unaware by the description&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I re-read the description and I can&amp;#8217;t decide how to interpret it other than for programmers. Please tell me how you interpreted the description that didn&amp;#8217;t strongly suggest the audience would consist of programmers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Would be nice to have some tips of how to keep the tests in agreement. It&amp;#8217;s not automatable, so humans need to keep track.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I thought I did this, but in case I didn&amp;#8217;t, please &lt;a href=&quot;http://www.jbrains.ca/permalink/278&quot;&gt;read this example&lt;/a&gt; where, near the end, I describe the algorithm I use to match up collaboration tests and contracts tests. I believe one could automate some of this, either in the style of &lt;code&gt;lint&lt;/code&gt; or in the style of &lt;code&gt;Cucumber&lt;/code&gt; and its &amp;#8220;here&amp;#8217;s what you need to write to implement that step&amp;#8221; feature.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Talk was on unit tests rather than &amp;#8216;integration&amp;#8217; tests; felt session was mislabeled.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I understand this a little, but I don&amp;#8217;t understand how the talk was not on integration tests. I talked about them all the way through. Moreover, since I titled it &amp;#8220;integration tests are a scam&amp;#8221;, I assume that would suggest that I wasn&amp;#8217;t going to praise or recommend using integration tests.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;You make the case integration tests are a waste of time and effort in almost all cases. You should outline where they do add value.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I really like this comment, and I will do that in this space sometime soon. Briefly, they add value when they check for system-level problems and unintended emergent behaviors that focused tests can&amp;#8217;t find.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Too fast; too auditory &amp;#8211; hard to integrate this way&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I apologize for this. I do sometimes talk too quickly because the topic excites me. As I perform this presentation more, I can more easily create long-lasting artifacts that will help people remember what I described.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Took too long to get to interesting &amp;#8216;contract tests&amp;#8217;. Seemed somewhat disorganized.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I can appreciate this sentiment. I suppose that in every audience at least one person will feel this way. I think that for most people, most of the time, I need the introductory material before I describe contract tests.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;As for feeling disorganized, what could I have done to make it feel more organized for you? An outline? Something you could see to keep track of my position in the talk?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;I&amp;#8217;m not sure half the room could read the easel.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Agreed. I didn&amp;#8217;t expect so many people, and it makes me happy to know that my audience has started growing. I have started using a tablet as an e-flipchart. I hope that helps.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;If the speaker&amp;#8217;s argument that we need more unit and story-level tests on component modules, I buy that and he could have said so. If he said that integration tests are not a complete test regime for development, I agree. But integration tests are a scam &amp;#8594; get real &lt;span class=&quot;caps&quot;&gt;HIS&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;TITLE&lt;/span&gt; is a scam.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I think I did say that we need more unit and story-level tests on component modules. I think I did say that integration tests are not a complete test regime for development. I still stand by the title: I believe there is more to the problem than that: integration tests sucker programmers into writing more integration tests, and that&amp;#8217;s the scam.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;35 minutes to get to mock objects and strategies for using mocks&amp;#8230; yuck.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I can appreciate that perspective. What did you expect? I can try to give more of that next time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;I&amp;#8217;d like to see some code, especially to see how this technique provides confidence through multiple levels of collaboration.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I agree that that would help. I don&amp;#8217;t know how to do that well in a 90-minute session.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Would have loved to see some real example contract tests on a large system.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I appreciate this comment, and would love to have included some, but my clients don&amp;#8217;t let me show their code. Also, I find it hard to include examples like that in a 90-minute session. In a half-day session I&amp;#8217;d find it easy to do, if any of my clients would let me show their code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;I was looking for how to fix integration/&lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; tests&amp;#8230; Description of session should have made it clearer that it was programmer tests not standard integration/&lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; tests.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I will look at how to improve the description to make that clearer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Turned out to be a lot more basic than I thought &amp;#8212; seemed to be &amp;#8216;why use mock objects&amp;#8217; but handwaved over the difficulty of using them.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I wish you had got more of what you wanted from the session. I think this session includes more than just &amp;#8216;why use mock objects&amp;#8217;, but I can see why you might have that impression. As for &amp;#8216;handwaving over the difficulty of using mock objects&amp;#8217;, can you share some of the difficulties you would have liked me to discuss?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Handwriting so poor&amp;mdash;can&amp;#8217;t read the flip chart&amp;mdash;use &lt;span class=&quot;caps&quot;&gt;PPT&lt;/span&gt;. I found his swearing offensive.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I apologize for the quality of my handwriting. I know I need to raise my awareness of this issue, and I think I have started to do that. I prefer not to use PowerPoint in general, so I have started using a tablet PC as an electronic flipchart so that more people can easily read what I&amp;#8217;ve written.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Regarding the swearing, I apologize for having offended you. I know that I take that risk and I understand that swearing represents lazy speaking.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Straightforward but a bit boring.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I wish you had been able to get more out of the session that you did. I find it surprising that you&amp;#8217;d stay the entire time in a session that you found boring, but I appreciate your determination. What would you like me to do with this information? What might I have done to excite you more?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;XP: My Greatest Misses 2000-2009&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;I wasn&amp;#8217;t sure where we were in the list of misses. What I needed was a list, maybe on the flipchart.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I take full responsibility for this. I have written the misses as an article, which you can easily find online with google. I didn&amp;#8217;t ask Agile 2009 to print this list as a handout because I wanted to save paper.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Also, as the talk evolves, my perspective about my misses evolves, and I don&amp;#8217;t give this talk the same way I did in 2007 when I did it for the first time, so I worry that any list would become out of date and useless. Perhaps I underestimate the value of that list.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Over-labored one problem of mis-interpretations of one&amp;#8217;s communications.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I suppose I find this problem so important that it merits emphasis. Also, thinking back to the talk, I saw links from other mistakes to miscommunication that I hadn&amp;#8217;t seen before, and I wanted to share those new connections with you as they happened. I see how that would appear as over-laboring the point.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;I expected more examples of things you can do wrong with XP rather than a discourse of (J. B.&amp;#8217;s) personal mistakes.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I don&amp;#8217;t quite know how to react to this comment. I think that both the title and the description make it clear that I will talk about my mistakes, and not about mistakes one might make. I even put &amp;#8220;My&amp;#8221; in the title to suggest that point. I don&amp;#8217;t know how to make that clearer in the future, but if you can suggest something, then I&amp;#8217;d like to know about it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Good storyteller, but would have preferred a bit more focus.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I understand and agree. I like my talks to proceed somewhat in a stream-of-consciousness style, and I understand the risk I assume by doing this. When I give talks with a narrower technical focus, I tend to do a better job of following a clearer structure. I suppose I don&amp;#8217;t see this talk as fitting into that category.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I find it surprising though, that you&amp;#8217;d rate my presentation skills with the worst possible rating, but you only offer the comment &amp;#8220;would have preferred more focus&amp;#8221;. Your innocuous comment doesn&amp;#8217;t appear to match your extremely low rating. Can you tell me more about what you feel I did wrong?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Too much talkative, too sleepy.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I don&amp;#8217;t know what to do with this comment. It&amp;#8217;s a talk. There will be talking. It&amp;#8217;s a talk about my mistakes, and you can&amp;#8217;t tell the audience my mistakes&amp;mdash;only I can. What do you suggest that I could have done differently?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Personal info is good, helpful and helps develop rapport, but a few examples went a little too far (example: your wife crying).&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I appreciate this sentiment, and I apologize for making you feel uncomfortable. I have a trusting nature, so I find myself more comfortable making myself more vulnerable than others do. I wanted to emphasize the significance of what I&amp;#8217;d learned, showing that it goes far beyond my work as a consultant.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don&amp;#8217;t know that we actually got through 10 misses.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I understand. I don&amp;#8217;t remember promising to get through 10 misses. :) To read all 10, please google &amp;#8220;rainsberger greatest misses&amp;#8221; and you&amp;#8217;ll find the article with a similar title that provides a summary of 10 specific misses. I apologize if you didn&amp;#8217;t get as much variety in the talk as you&amp;#8217;d have liked. As I was talking, I felt things becoming a bit monotonous, but I didn&amp;#8217;t know what to do about it at the moment. I suppose I could have just paused, admitted that I needed to move on to another idea, then done so. I can remember that for future versions of this talk.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Maybe I did not understand the topic description. I thought it would be examples from the industry.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I think I included plenty of examples of my work in the industry, although I did also include more personal examples that occurred outside my work as a consultant. As for misunderstanding the topic description, what did you expect from the session given the way you interpreted the description?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;This talk is valuable to experienced coaches, but not too much would be evident to a novice coach. It might be hard for them to identify a big idea or theme. [Best idea was saved for last.]&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I had hoped that novice coaches would find my mistakes useful in that they could watch out for making those same mistakes themselves. Some other coaches and practitioners have told me directly that they notice themselves making similar mistakes and now have some ideas how to stop themselves before they do too much damage. So it seems at least some novice coaches managed to get from the talk what I intended to convey. Of course, I have no way to know how many other novice coaches left the room reeling and confused, because none of them have told me as much.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;As for saving the best idea for last, I assure you that I didn&amp;#8217;t do that intentionally. Sometimes it takes that long for the best idea to come out.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Go Leafs&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You are bastard.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Editor&amp;#8217;s note: I know who left the &amp;#8220;Go Leafs&amp;#8221; comment. We are friends and I am joking with him. Please hold your cards and letters.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Joe, I hope you feel better! You&amp;#8217;re smart enough, you&amp;#8217;re good enough, and by golly, I like you!&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I appreciate the sentiment, and I further appreciate you letting me know who you are in your comments, but then I don&amp;#8217;t understand why you rated the session so poorly. That doesn&amp;#8217;t match your comment, which appeared humorously supportive in nature. I don&amp;#8217;t want to interpret your comment as sarcasm and condescension, but given your ratings, I find it hard to interpret it otherwise.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;I wish there was more time for Q&amp;amp;A.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I apologize. I wish there were clocks in the room so that I could have managed my time better. I think I simply need to stop after 2/3 of the time available, even mid-sentence, just to ensure we have enough time for Q&amp;amp;A.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;I thought Joe&amp;#8217;s insights and ideas were great, really valuable. It just didn&amp;#8217;t match description. Should de-couple the XP in the title.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I don&amp;#8217;t understand why the content didn&amp;#8217;t match the description. I would like to know more about the mismatch you perceived. I use XP as my primary toolset when I consult, so most of, if not all, my misses come from XP or XP-leaning projects. What could I have said or done that would have made that connection clearer for you?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/284';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/284&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 29, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile-2009&quot;&gt;agile 2009&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 29 Sep 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/284</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Click On Macs saved Apple a customer today</title>
      <link>http://jbrains.ca/permalink/283</link>
      <description>&lt;div class='entry posting' id='entry-_posting_283'&gt;
&lt;div class='posting' id='content-_posting_283'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;It took several years, but Apple had me thinking about switching back today, until &lt;a href=&quot;http://blog.rainsberger.ca/&quot;&gt;Sarah&lt;/a&gt; and &lt;a href=&quot;http://www.clickonmacs.com/&quot;&gt;ClickOnMacs&lt;/a&gt; in Toronto teamed up to saved the day.&lt;/p&gt;
&lt;p&gt;The internal hard disk on my MacBook Pro began failing in the past few days. I suspected bad sectors based on random pauses while the machine appeared to write temporary data out to disk. Booting to my trusty backup drive made the problem disappear, which reminds me to recognize Hitachi for their fine 500 GB &lt;a href=&quot;http://bit.ly/KEgvR&quot;&gt;SimpleDrive Mini&lt;/a&gt; and Shirt Pocket&amp;#8217;s reliable &lt;a href=&quot;http://www.shirt-pocket.com/SuperDuper/SuperDuperDescription.html&quot;&gt;SuperDuper!&lt;/a&gt; backup system for allowing me to keep working in spite of a wonky internal disk. Sadly, when I tried to fix the internal disk by software means, I ran out of rocks pretty quickly.&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;I managed to learn that the &amp;#8220;Write all zeros&amp;#8221; feature of Disk Utility identifies bad sectors and pushes them out of the way. I tried that and my drive&amp;#8217;s capacity fell by only 300 MB. I could live with that minor loss, but after restoring my backup, Verify Disk failed. At this point, I gave up on the disk and Apple decided to let me down.&lt;/p&gt;
&lt;p&gt;Sarah made Genius Bar appointments at all three Toronto locations, but couldn&amp;#8217;t get anything before Thursday, when we had to fly to Istanbul. Of those three locations, one claimed to be too short staffed to deal with us. Neither of the other two were willing to tell us whether they had the necessary service parts available to fix my machine before we had to fly. We even asked them merely to make sure they weren&amp;#8217;t already out of stock, so we could avoid a wasted two-hour trip on the day we need to fly seven time zones east. They didn&amp;#8217;t care, preferring instead to play poor disempowered employees. Sad.&lt;/p&gt;
&lt;p&gt;Next, when I remembered I had a ProCare membership, I thought I&amp;#8217;d get quick service that way. No dice. First, my membership expired without any notification. Next, I asked about renewing my membership to jump the service line, and they said they&amp;#8217;d only let me drop the machine off with no estimate of whether they could repair it in time to fly. Sad.&lt;/p&gt;
&lt;p&gt;Finally, Sarah remembered Click On Macs downtown in Toronto. I called them, gave them my computer at 1:30 PM and they invited me to return by 5:30 PM to pick the machine up. I authorized them to install a new hard disk if they couldn&amp;#8217;t fix the existing one. All that for less than $200. Nice.&lt;/p&gt;
&lt;p&gt;So Apple, I won&amp;#8217;t switch quite yet, but be aware that I priced out buying two disposable Dell laptops to avoid this nonsense. If Click On Macs hadn&amp;#8217;t done what you flatly refused to do, I&amp;#8217;d have bought a Dell today.&lt;/p&gt;
&lt;h3&gt;But wait, there&amp;#8217;s more!&lt;/h3&gt;
&lt;p&gt;When I picked up my machine, I asked about the lead time on a &lt;span class=&quot;caps&quot;&gt;RAM&lt;/span&gt; upgrade from 4 GB to 8 GB, expecting it to take a few days. They answered &amp;#8220;we can do it now&amp;#8221; and offered me a much more reasonable price than Apple did. I walked out of there with 8 GB &lt;span class=&quot;caps&quot;&gt;RAM&lt;/span&gt; and a new, 7200-&lt;span class=&quot;caps&quot;&gt;RPM&lt;/span&gt;, 320-GB internal hard disk which, thanks to SuperDuper!, will boot to my OS by the time we come back from the Blue Jays game, and I&amp;#8217;ll manage to return my dealings with my computer back to normal.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn&quot;&gt;&lt;sup&gt;1&lt;/sup&gt; A curling reference. Try Wikipedia.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/283';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/283&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 25, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/mac&quot;&gt;mac&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 25 Sep 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/283</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The World's Shortest Article on Behavior-Driven Development, revisited</title>
      <link>http://jbrains.ca/permalink/38</link>
      <description>&lt;div class='entry posting' id='entry-_posting_38'&gt;
&lt;div class='posting' id='content-_posting_38'&gt;
&lt;div style='text-align: justify'&gt;
&lt;blockquote style=&quot;font-size: small;&quot;&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;&lt;em&gt;I added more to this article on September 18, 2009.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;On May 21, 2006, I wrote the world&amp;#8217;s shortest article on Behavior-Driven Development. Although the title links to the entire article, it is so short that I can reproduce it here.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What is Behavior-Driven Development (&lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt;)?&lt;/p&gt;
&lt;p&gt;It is Test-Driven Development (&lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;) practiced &lt;em&gt;correctly&lt;/em&gt;; nothing more.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At the time, I wrote this in anger, for reasons that I&amp;#8217;m too tired to get in to just now (it is 4:30 AM on the last day of Agile 2006), but I wanted to share with you that my anger is changing to some more positive emotion regarding this topic.&lt;/p&gt;
&lt;p&gt;The fact that &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; are equivalent&amp;mdash;isomorphic, even&amp;mdash;has its good points and bad points. &lt;strong&gt;I am unclear at the present moment&lt;/strong&gt; whether the good outweigh the bad or the other way around.&lt;/p&gt;
&lt;p&gt;What I dislike about the existence of two (perhaps three or more) different names for the same thing is that it can confuse people and divide them. Think of a single language written in two alphabets: while the speakers understand one another, they cannot read one another&amp;#8217;s literature. I would hate to see that happen.&lt;/p&gt;
&lt;p&gt;What I like about it is that we have two (perhaps three or more) standard approaches to explaining the technique that suit different audiences. To some, the word &amp;#8220;test&amp;#8221; resonates well, and to others, the words &amp;#8220;behavior&amp;#8221; or &amp;#8220;example&amp;#8221; resonate well. Rather than haphazardly sprinkling the word &amp;#8220;behavior&amp;#8221; into conversations about &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;, we can use an entire, cohesive vocabulary to explain &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; to someone who prefers to talk about behaviors over tests. I imagine this would help.&lt;/p&gt;
&lt;p&gt;I would like to thank the people in room 2411 of the Hyatt Regency in Minneapolis for their willingness to participate in a spirited debate on this topic. It was tiring, and it was late, but I found it worth the effort.&lt;/p&gt;
&lt;h3&gt;Times have changed&lt;/h3&gt;
&lt;p&gt;In the time since I first wrote this article, &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; has evolved and my opinion of it has evolved as well. I now see how &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; ideas map well to the way I deliver features, complete with Feature Injection and the inner &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; design cycle. The &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; community have described how they set up a pull system for features, which I&amp;#8217;ve been doing for years. As always seems the case, we had much more in common with one another than we originally thought!&lt;/p&gt;
&lt;p&gt;Thanks to all the BDDers who have patiently worked with me on this unification, even when they didn&amp;#8217;t know they were doing it: Dan North, Chris Matts, Olav Maassen, Aslak Helles&amp;oslash;y and Liz Keough.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/38';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/38&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 19, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2006&quot;&gt;agile 2006&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 19 Sep 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/38</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>jbrains Classic: Null as a method parameter</title>
      <link>http://jbrains.ca/permalink/282</link>
      <description>&lt;div class='entry posting' id='entry-_posting_282'&gt;
&lt;div class='posting' id='content-_posting_282'&gt;
&lt;div style='text-align: justify'&gt;
&lt;blockquote style=&quot;font-size: small;&quot;&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;&lt;em&gt;I originally published this on March 2, 2005.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Unless I&amp;#8217;m publishing an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; for general use, I don&amp;#8217;t worry about testing method parameters against &lt;code&gt;null&lt;/code&gt;. It&amp;#8217;s too much code and too many duplicate tests. Besides, I would be testing the wrong thing.&lt;/p&gt;
&lt;p&gt;When a method receives &lt;code&gt;null&lt;/code&gt; as a parameter, the invoker&amp;mdash;and not the receiver&amp;mdash;is missing a test.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/282';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/282&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 18, 2009  15:54
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 18 Sep 2009 15:54:20 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/282</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Comments on &quot;Integration Tests Are A Scam&quot; at Agile 2009</title>
      <link>http://jbrains.ca/permalink/260</link>
      <description>&lt;div class='entry posting' id='entry-_posting_260'&gt;
&lt;div class='posting' id='content-_posting_260'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;You managed to get me rethinking my ideas about testing.  That&amp;#8217;s great!  That&amp;#8217;s what I came for. &amp;mdash; Nick Southwell&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/260';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/260&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 18, 2009  15:45
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 18 Sep 2009 15:45:46 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/260</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>jbrains Classic: Contract Tests</title>
      <link>http://jbrains.ca/permalink/281</link>
      <description>&lt;div class='entry posting' id='entry-_posting_281'&gt;
&lt;div class='posting' id='content-_posting_281'&gt;
&lt;div style='text-align: justify'&gt;
&lt;blockquote style=&quot;font-size: small;&quot;&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;&lt;em&gt;I originally published this on March 2, 2005.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Contract Tests&lt;/strong&gt; explain how a class should extend a superclass or implement and interface, so that I don&amp;#8217;t have to read a bunch of prose to figure out how to do that. Typically, a contract test case class is abstract, then I extend it and implement a creation method or two to return instances of my own implementation of the given interface. That gives me a standard battery of tests I can run to drive my implementation. It might not be perfect (I&amp;#8217;ll have n failing tests to start) but I prefer it to documentation written in prose.&lt;/p&gt;
&lt;p&gt;So if you&amp;#8217;re delivering something you want me to extend and I need to follow more than three rules, please deliver me some contract tests.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/281';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/281&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 18, 2009  15:42
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 18 Sep 2009 15:42:11 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/281</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>When to fake; when to mock</title>
      <link>http://jbrains.ca/permalink/280</link>
      <description>&lt;div class='entry posting' id='entry-_posting_280'&gt;
&lt;div class='posting' id='content-_posting_280'&gt;
&lt;div style='text-align: justify'&gt;
&lt;blockquote style=&quot;font-size: small;&quot;&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;&lt;em&gt;I originally published this on January 3, 2005. One of my other postings links to this article, so I wanted to bring it back to life. Thanks to James Breen for pointing out the broken link to me.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In working with Pat Welsh I had occasion to describe in a rather pithy way when to fake and when to mock, so I thought I&amp;#8217;d share that with you.&lt;/p&gt;
&lt;p&gt;To be clear, I mean &amp;#8220;mock&amp;#8221; in the sense of interaction-based testing with mock objects, and I mean &amp;#8220;fake&amp;#8221; in the sense of state-based testing with fakes or stubs. Google if you need a stronger definition of those terms, but they suit me for now.&lt;/p&gt;
&lt;blockquote style=&quot;font-size: small;&quot;&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;Note that I use the term &amp;#8220;stub&amp;#8221; when I used to say &amp;#8220;fake&amp;#8221;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So then, I want to test some object in isolation from the rest of the system. In broad terms, I need to write tests to answer two essential questions:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Am I using the objects around me correctly? Am I invoking the right methods at the right times with the right parameters?&lt;/li&gt;
	&lt;li&gt;Am I reacting to the objects around me correctly? Do I handle errors reasonably? Do I respond well to the answers they send me?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For the first kind of test, I generally mock; and for the second kind of test, I generally fake.&lt;/p&gt;
&lt;p&gt;Put another way, I lean on interaction-based testing to verify how my object talks to its collaborators; but I lean on state-based testing to verify how well that object listens.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/280';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/280&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 18, 2009  15:02
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 18 Sep 2009 15:02:15 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/280</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Increase your sphere of influence by focusing on people one at a time</title>
      <link>http://jbrains.ca/permalink/279</link>
      <description>&lt;div class='entry posting' id='entry-_posting_279'&gt;
&lt;div class='posting' id='content-_posting_279'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I&amp;#8217;ve spent the better part of the last five years helping a variety of organizations with some form of agile transition. In the process, I have experienced the symptoms that Patrick Lencioni described in his enjoyable &lt;a href=&quot;http://bit.ly/1PlfyC&quot;&gt;The Three Signs of a Miserable Job&lt;/a&gt;. After a couple of years, it really dawned on me that I suffered from the kind of delusions of grandeur one sometimes associates with consultants: I thought I could fix the company, and worse, that doing so represented my mandate. Looking back, I find the result predictable: limited reach and ultimate failure. I needed to change my approach.&lt;/p&gt;
&lt;p&gt;I let go of the notion that I had a mandate to fix the organization. As my good friend Patrick Wilson-Welsh taught me, I had to &lt;em&gt;release the outcome&lt;/em&gt;. Instead, I relinquished responsibility for fixing the organization and accepted responsibility for having positive impact on individual people. As I did this, I noticed my results changed. (Surprise!)&lt;/p&gt;
&lt;p&gt;I spent less time talking to teams and more time working with individuals. I designed with the programmers, I worked through stories with the business analysts, and I helped the build team simplify some parts of the build. I exchanged my good habits for their domain knowledge. I genuinely wanted to help, and I think I did.&lt;/p&gt;
&lt;p&gt;The more I focused on individuals, the more I noticed those individuals sharing what I&amp;#8217;d taught them with their peers. I&amp;#8217;d created little consultants-in-training, but those with a definite goal of improving circumstances for their peers, their managers, and their organization. I created a little von Neumann machine out of the tidbits I shared. Months later I found that my message had reached dozens of people, many of whom actually gave it the time of day. I hadn&amp;#8217;t seen that two years earlier.&lt;/p&gt;
&lt;p&gt;Based on this experience, then, I focus my work on individuals, and I find my work has more impact. I enjoy it more, too. Everyone wins.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/279';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/279&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 15, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/emotional-health&quot;&gt;emotional health&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/consulting&quot;&gt;consulting&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 15 Sep 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/279</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Part 4: Surely we need integration tests for the Mars rover!</title>
      <link>http://jbrains.ca/permalink/278</link>
      <description>&lt;div class='entry posting' id='entry-_posting_278'&gt;
&lt;div class='posting' id='content-_posting_278'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Recently, &amp;#8220;Guest&amp;#8221; &lt;a href=&quot;http://www.jbrains.ca/permalink/260&quot;&gt;commented&lt;/a&gt; about my Agile 2009 tutorial, &lt;a href=&quot;http://www.jbrains.ca/permalink/259&quot;&gt;Integration Tests Are A Scam&lt;/a&gt;. &amp;#8220;Guest&amp;#8221; wrote this:&lt;/p&gt;
&lt;blockquote style=&quot;font-style: italic;&quot;&gt;
&lt;p style=&quot;font-style: italic;&quot;&gt;A Mars rover mission failed because of a lack of integration tests. The parachute system was successfully tested. The system that detaches the parachute after the landing was successfully &amp;#8211; but independently &amp;#8211; tested. On Mars when the parachute successfully opened the deceleration &amp;#8220;jerked&amp;#8221; the lander, then the detachment system interpreted the jerking as a landing and successfully detached the parachute. Oops. Integration tests may be costly but they are absolutely necessary.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I don&amp;#8217;t doubt the necessity of integration tests. I depend on them to solve difficult system-level problems. By contrast, I routinely see teams using them to detect unexpected consequences, and I don&amp;#8217;t think we need them for that purpose. I prefer to use them to confirm an uneasy feeling that an unintended consequence lurks.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s consider a clean implementation of the situation my commenter describes. I see this design, comprising the lander, the parachute, the detachment system, an accelerometer and an altimeter. A controller connects all these things together. Let&amp;#8217;s look at the &amp;#8220;code&amp;#8221;, which I&amp;#8217;ve written in a fantasy language that looks a little like Java/C# and a little like Ruby.&lt;/p&gt;
&lt;blockquote style=&quot;font-size: small;&quot;&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;Ashley Moran has posted a working Ruby version of this example. If you speak Ruby, then I highly recommend &lt;a href=&quot;http://bit.ly/8sQlbR&quot;&gt;looking at that example&lt;/a&gt; after you&amp;#8217;ve read this.}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185020&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;Controller.initialize() {               &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;parachute = Parachute.new(lander)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;detachment_system = DetachmentSystem.new(parachute)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer = Accelerometer.new()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;lander = Lander.new(accelerometer, Altimeter.new())&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer.add_observer(detachment_system)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;}  &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;Parachute {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;&amp;nbsp;&amp;nbsp;needs a lander&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC11&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC12&quot;&gt;&amp;nbsp;&amp;nbsp;open() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC13&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lander.decelerate()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC14&quot;&gt;&amp;nbsp;&amp;nbsp;}             &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC15&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC16&quot;&gt;&amp;nbsp;&amp;nbsp;detach() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC17&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (lander.has_landed == false)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC18&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise &amp;quot;You broke the lander, idiot.&amp;quot;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC19&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC20&quot;&gt;}      &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC21&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC22&quot;&gt;AccelerationObserver is a role {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC23&quot;&gt;&amp;nbsp;&amp;nbsp;handle_acceleration_report(acceleration) {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC24&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;raise &amp;quot;Subclass responsibility&amp;quot;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC25&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC26&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC27&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC28&quot;&gt;DetachmentSystem acts as AccelerationObserver {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC29&quot;&gt;&amp;nbsp;&amp;nbsp;needs a parachute&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC30&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC31&quot;&gt;&amp;nbsp;&amp;nbsp;handle_acceleration_report(acceleration) {}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC32&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (acceleration &amp;lt;= -50.ms2) {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC33&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC34&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC35&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC36&quot;&gt;}               &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC37&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC38&quot;&gt;Accelerometer acts as Observable {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC39&quot;&gt;&amp;nbsp;&amp;nbsp;manages many acceleration_observers&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC40&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC41&quot;&gt;&amp;nbsp;&amp;nbsp;report_acceleration(acceleration) {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC42&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;acceleration_observers.each() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC43&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;each.handle_acceleration_report(acceleration)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC44&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC45&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC46&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC47&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC48&quot;&gt;Lander {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC49&quot;&gt;&amp;nbsp;&amp;nbsp;needs an accelerometer  &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC50&quot;&gt;&amp;nbsp;&amp;nbsp;needs an altimeter&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC51&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC52&quot;&gt;&amp;nbsp;&amp;nbsp;decelerate() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC53&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// I know how much to decelerate by&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC54&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;accelerometer.report_acceleration(how_much)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC55&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC56&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC57&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185020/029126795025ebc095f05ef97b39af4ee0479c99/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185020&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;I need to test what happens when I open the parachute. The lander should decelerate.&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185026&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testOpenParachute() { &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;parachute = Parachute.new(lander = mock(Lander))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;lander.expects().decelerate() &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;parachute.open() &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185026/1f16f2e2e3513fdfb0e9434d2b3610353fd4a141/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185026&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Since this test expects the lander to decelerate, I have to test that. When the lander decelerates, the accelerometer should report its deceleration.&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185027&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testLanderDecelerates() {                  &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer = mock(Accelerometer)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;lander = Lander.new(accelerometer)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer.expects().report_acceleration(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;lander.decelerate()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185027/1ddf011da15152df20d4eba65e1b57ac94a638d0/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185027&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Since this test shows that the accelerometer can report acceleration of -50 m/s&lt;sup&gt;2&lt;/sup&gt;, I have to test that.&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185029&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testAccelerometerCanReportRapidAcceleration() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer = Accelerometer.new()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer.add_observer(observer = mock(AccelerationObserver))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;observer.expects().handle_acceleration_report(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer.report_acceleration(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;}                                          &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185029/1f0bb87f14af33b5a1e361084f9d7681966d8216/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185029&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Since this test shows that any acceleration observer must be prepared to handle an acceleration report of -50 m/s&lt;sup&gt;2&lt;/sup&gt;, I have to test that.&lt;/p&gt;
&lt;p&gt;First, the general test for the contract of the interface:&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185030&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;AccelerationObserverTest {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;testAccelerationObserverCanHandleRapidAcceleration() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;observer = create_acceleration_observer() // subclass responsibility&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;observer.handle_acceleration_report(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.should execute_without_incident&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;}                                                      &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185030/0153625081492a73e556d06b394751ac7b60779e/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185030&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now the test for &lt;code&gt;DetachmentSystem&lt;/code&gt;, which acts as an &lt;code&gt;AccelerationObserver&lt;/code&gt;. What should it do if it detects such sudden deceleration? It should detach the parachute.&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185031&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;DetachmentSystemTest extends AccelerationObserverTest {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;// I inherit  testAccelerationObserverCanHandleRapidAcceleration()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;create_acceleration_observer() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DetachmentSystem.new(parachute = mock(Parachute))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.expects().detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185031/67c2a266c7c9a5295d185869eb8abd338a13d770/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185031&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You might find that easier to read this way, by inlining the method &lt;code&gt;create_acceleration_observer()&lt;/code&gt;:&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185032&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;DetachmentSystemTest {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;testRespondsToRapidAcceleration() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;detachment_system = DetachmentSystem.new(parachute = mock(Parachute))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.expects().detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;detachment_system.handle_acceleration_report(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.should execute_without_incident&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;}                              &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185032/9af808918a355eed88b3989b0b8b98ad5673194f/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185032&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Since this test expects the parachute to be able to detach, I have to test that. Now, detaching only works if we&amp;#8217;ve landed. (I&amp;#8217;ve simplified on purpose. Suppose the parachute can&amp;#8217;t survive a drop from any height. It&amp;#8217;s easy to add that detail in later.)&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185033&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;ParachuteTest {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;testDetachingWhileLanded() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute = Parachute.new(lander = mock(Lander))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lander.stubs().has_landed().to_return(true)    &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.should execute_without_incident&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;&amp;nbsp;&amp;nbsp;testDetachingWhileNotLanded() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC11&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute = Parachute.new(lander = mock(Lander))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC12&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lander.stubs().has_landed().to_return(false)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC13&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC14&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC15&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.should raise(&amp;quot;You broke the lander, idiot.&amp;quot;)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC16&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC17&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC18&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185033/d566e795af04db2dc29e0da17b3cf8f8f8800b9d/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185033&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Hm. I notice that &lt;code&gt;parachute.detach()&lt;/code&gt; might fail. But I just wrote a test that uses &lt;code&gt;parachute.detach()&lt;/code&gt; and doesn&amp;#8217;t yet show how it handles that method failing. I have to test that.&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185034&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;DetachmentSystemTest {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;testRespondsToDetachFailing() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;detachment_system = DetachmentSystem.new(parachute = mock(Parachute))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.stubs().detach().to_raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;detachment_system.handle_acceleration_report(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}.should raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC11&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185034/73eefaab8529f4a26a0488a6d34afe2e819286ed/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185034&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Hm. So handling an acceleration report of -50 m/s&lt;sup&gt;2&lt;/sup&gt; can fail. Who might issue such a right? The accelerometer. Since the detach system doesn&amp;#8217;t handle this failure, I have to test what the accelerometer does when issuing an acceleration report might fail.&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185035&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testAccelerometerCanRespondToFailureWhenReportingAcceleration() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer = Accelerometer.new()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer.add_observer(observer = mock(AccelerationObserver))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;observer.stubs().handle_acceleration_report().to_raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;accelerometer.report_acceleration(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;}.should raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185035/c86ed2c04981ab8050efe82ee530327449dde4f7/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185035&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It turns out that the accelerometer might fail when reporting acceleration of -50 m/s&lt;sup&gt;2&lt;/sup&gt;. When might it do that? When the lander decelerates. What happens then?&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185036&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testLanderDeceleratesRespondsToFailure() {                  &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer = mock(Accelerometer)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;lander = Lander.new(accelerometer)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;accelerometer.stubs().report_acceleration().to_raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lander.decelerate()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;}.should raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185036/eb192b978d1f3caa931ff1cfaaa1f296e45724d1/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185036&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Hm. So decelerating could fail! All right, who causes the lander to decelerate? That code might fail. Oh yes&amp;#8230; the parachute opening!&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185037&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testOpenParachuteRespondsToFailure() { &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;parachute = Parachute.new(lander = mock(Lander))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;lander.stubs().decelerate().to_raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.open() &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;}.should raise(AnyException)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;}  &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185037/f3f719d33f6d216cb73c194e59bf1e899226205a/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185037&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So opening the parachute could fail! We probably want to nail down when that happens. We have a test that shows us when:&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185038&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testDetachingWhileNotLanded() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;parachute = Parachute.new(lander = mock(Lander))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;lander.stubs().has_landed().to_return(false)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;this_block {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;}.should raise(&amp;quot;You broke the lander, idiot.&amp;quot;)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185038/9a3256c986335fe66e3fbd06fbbde7f8a5a6365c/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185038&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So the parachute opening could cause it to detach because the lander hasn&amp;#8217;t landed yet. I don&amp;#8217;t know about you, but I think the parachute provides the most value when its helps the lander land, and not once it has landed. That tells me that someone, somewhere needs to handle the exception that &lt;code&gt;detach()&lt;/code&gt; would raise, or at least prevent &lt;code&gt;detach()&lt;/code&gt; from happening while the altimeter reads above a few meters off the ground.&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185039&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testDoNotDetachWhenTheLanderIsTooHighUp() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;altimeter = mock(Altimeter)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;altimeter.stubs().altitude().to_return(5.m)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;DetachmentSystem.new(parachute = mock(Parachute))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;parachute.expects(no_invocations_of).detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;detachment_system.handle_acceleration_report(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;&amp;nbsp;&amp;nbsp;// ???&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC11&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC12&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185039/36dc5b6ee47ebbf219b808b39f474c3636ceb766/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185039&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In writing this test, I see that in order to stop the detachment system from telling the parachute to detach, it needs access to the altimeter.&lt;/p&gt;
&lt;p&gt;Integration problem detected. When I wire the detachment system up to the altimeter, even the collaboration test shows how to ensure that the parachute doesn&amp;#8217;t detach in this kind of dangerous situation.&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185040&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;testDoNotDetachWhenTheLanderIsTooHighUp() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;DetachmentSystem.new(parachute = mock(Parachute), altimeter = mock(Altimeter))&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;altimeter.stubs().altitude().to_return(5.m)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;parachute.expects(no_invocations_of).detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;detachment_system.handle_acceleration_report(-50.ms2)&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185040/28e7056741f7b7197816dddb2151b2af269c22a5/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185040&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This means I have to add the following production behavior.&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-185041&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;DetachmentSystem acts as AccelerationObserver {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;needs a parachute&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;needs an altimeter // NEW!&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&amp;nbsp;handle_acceleration_report(acceleration) {}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (acceleration &amp;lt;= -50.ms2 and altimeter.altitude() &amp;lt; 5.m) {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;parachute.detach()&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;}               &lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC11&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/185041/75baea8b5de141d632b36eea6c569bcf0bcf5428/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/185041&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Integration problem solved with no integration tests. Instead, I have a bunch of collaboration tests, one important contract test, and &lt;del&gt;the ability to notice things&lt;/del&gt; a systematic approach to choosing the next test, which I describe in the comments below. Any questions?&lt;/p&gt;
&lt;blockquote style=&quot;font-size: small; font-style: italic;&quot;&gt;
&lt;p style=&quot;font-size: small; font-style: italic;&quot;&gt;Dan Fabulich rightly jumped on me for using the phrase &amp;#8220;an ability to notice things&amp;#8221; just a little earlier in this article. I choose that phrase lazily because I didn&amp;#8217;t want to patronize you by writing, &amp;#8220;an ability to perform basic reasoning&amp;#8221;. Oops. I thought about how I choose the next test, and I decided to take the time to include that here. Enjoy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In this example, I used no magic to choose the next test; but rather some fundamental reasoning.&lt;/p&gt;
&lt;p&gt;Every time I say &amp;#8220;I need &lt;em&gt;a thing&lt;/em&gt; to do &lt;em&gt;X&lt;/em&gt;&amp;#8221; I introduce an interface. In my current test, I end up stubbing or mocking one of those tests.&lt;/p&gt;
&lt;p&gt;(See &lt;a href=&quot;http://www.jbrains.ca/permalink/90&quot;&gt;A sign you&amp;#8217;re mocking too much&lt;/a&gt; for more about when I avoid interfaces and when I routinely create them.)&lt;/p&gt;
&lt;p&gt;Every time I &lt;em&gt;stub&lt;/em&gt; a method, I make an assumption about what values that method can return. To check that assumption, I have to write a test that expects the return value I&amp;#8217;ve just stubbed. I use only basic logic there: if A depends on B returning x, then I have to know that B can return x, so I have to write a test for that.&lt;/p&gt;
&lt;p&gt;Every time I &lt;em&gt;mock&lt;/em&gt; a method, I make an assumption about a service the interface provides. To check that assumption, I have to write a test that tries to invoke that method with the parameters I just expected. Again, I use only basic logic there: if A causes B to invoke c(d, e, f) then I have to know that I&amp;#8217;ve tested what happens when B invokes c(d, e, f), so I have to write a test for that.&lt;/p&gt;
&lt;p&gt;Every time I introduce a method on an interface, I make a decision about its behavior, which forms the &lt;em&gt;contract&lt;/em&gt; of that method. To justify that decision, I have to write tests that help me implement that behavior correctly whenever I implement that interface. I write &lt;a href=&quot;http://www.jbrains.ca/permalink/165&quot;&gt;contract tests&lt;/a&gt; for that. Once again, I use only basic logic there: if A claims to be able to do c(d, e, f) with outcomes x, y, and z, then when B implements A, it must be able to do c(d, e, f) with outcomes x, y, and z (and possibly other non-destructive outcomes).&lt;/p&gt;
&lt;p&gt;I simply kept applying these points over and over again until I stopped needing tests. Along the way, I found a problem and fixed it before it left my hands.&lt;/p&gt;
&lt;p&gt;If I can describe the steps well enough for others to follow &amp;#8211; and I posit I&amp;#8217;ve just done that here &amp;#8211; then I don&amp;#8217;t agree to labeling it &amp;#8220;magic&amp;#8221;.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/278';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/278&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 12, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/integrated-tests-are-a-scam&quot;&gt;integrated tests are a scam&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 12 Sep 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/278</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The Four Elements of Simple Design</title>
      <link>http://jbrains.ca/permalink/276</link>
      <description>&lt;div class='entry posting' id='entry-_posting_276'&gt;
&lt;div class='posting' id='content-_posting_276'&gt;
&lt;div style='text-align: justify'&gt;
&lt;blockquote style=&quot;font-size: small;&quot;&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;&lt;em&gt;I realize that I&amp;#8217;ve never really written this down before, and I say it so frequently in my work as a trainer and mentor, that I think it bears repeating.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I have reduced everything I&amp;#8217;ve ever learned about effective object-oriented design to the four elements of simple design that I first learned from Kent Beck&amp;#8217;s work. Maybe you can, too.&lt;/p&gt;
&lt;p&gt;I define &lt;strong&gt;simple design&lt;/strong&gt; this way. A design is simple to the extent that it:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Passes its tests&lt;/li&gt;
	&lt;li&gt;Minimizes duplication&lt;/li&gt;
	&lt;li&gt;Maximizes clarity&lt;/li&gt;
	&lt;li&gt;Has fewer elements&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note that I put these properties in priority order. I&amp;#8217;m willing to copy-and-paste to get a test passing, but once the test passes, I can usually remove the duplication quickly. I&amp;#8217;m willing to extract code into a method and call it &lt;code&gt;foo()&lt;/code&gt; in order to get rid of duplicate code, although that name &lt;code&gt;foo()&lt;/code&gt; rarely survives more than 15 minutes. Finally, I will gladly introduce interfaces, classes, methods and variables to clarify the intent of a piece of code, although generally speaking once I make things more clear, I can find things to cut.&lt;/p&gt;
&lt;p&gt;Some people put &amp;#8220;minimize duplication&amp;#8221; and &amp;#8220;maximize clarity&amp;#8221; in a tie for second place. I don&amp;#8217;t. My experience has led me to conclude that removing duplication helps more than fixing bad names does. Moreover, removing duplication tends to allow a suitable structure to emerge, whereas bad names highlight an inappropriate distribution of responsibilities. I use this observation as a key element of my demonstration, &amp;#8220;Architecture Without Trying&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Now I should point out that, as a test-driven development (and now also a behavior-driven development) practitioner, I write tests as I draw breath, so I don&amp;#8217;t really need to emphasize that part.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;del&gt;Passes its tests&lt;/del&gt;&lt;/li&gt;
	&lt;li&gt;Minimizes duplication&lt;/li&gt;
	&lt;li&gt;Maximizes clarity&lt;/li&gt;
	&lt;li&gt;Has fewer elements&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I should also point out that I&amp;#8217;ve yet to see a codebase with low duplication and high clarity that, nonetheless, had considerably more design elements than it needed, so I don&amp;#8217;t really need to emphasize that part, either.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;del&gt;Passes its tests&lt;/del&gt;&lt;/li&gt;
	&lt;li&gt;Minimizes duplication&lt;/li&gt;
	&lt;li&gt;Maximizes clarity&lt;/li&gt;
	&lt;li&gt;&lt;del&gt;Has fewer elements&lt;/del&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That leaves me with two key elements of simple design: &lt;strong&gt;remove duplication and fix bad names&lt;/strong&gt;. When I remove duplication, I tend to see an appropriate structure emerge, and when I fix bad names, I tend to see responsibilities slide into appropriate parts of the design.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I claim these to be axioms of modular design, with a &amp;#8220;parallel postulate&amp;#8221; of whether you use objects or not.&lt;/strong&gt; If you use objects, you get object-oriented design, and if you don&amp;#8217;t, you get structured design. (I don&amp;#8217;t know how functional design fits into this yet, because I haven&amp;#8217;t done enough of it.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I claim that developing strong skills of detecting duplication, removing duplication, identifying naming problems, and fixing naming problems equates to learning everything ever written about object-oriented design.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Put more simply, if you master removing duplication and fixing bad names, then I claim you master object-oriented design.&lt;/p&gt;
&lt;p&gt;Now I wouldn&amp;#8217;t bother burning your old &lt;span class=&quot;caps&quot;&gt;OOD&lt;/span&gt;/&lt;span class=&quot;caps&quot;&gt;OOP&lt;/span&gt; books, but I will tell you that if you have an interested buyer, then feel free to sell them.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/276';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/276&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 10, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 10 Sep 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/276</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The Code Whisperer: Detecting anemic class hierarchies</title>
      <link>http://jbrains.ca/permalink/277</link>
      <description>&lt;div class='entry posting' id='entry-_posting_277'&gt;
&lt;div class='posting' id='content-_posting_277'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;When I remove duplication from the siblings in a class hierarchy, I extract some code out to collaborators and pull some code up into the superclass. This often results in a kind of degenerate class hierarchy where the subclasses only override methods that return values or constants. They look like this:&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-183817&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;class FindAllUsersRequest extends GetRequest {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public FindAllUsersRequest(parameters) {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;super(parameters);&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC6&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public URL getRequestUrl() {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC7&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return URL.create(&amp;quot;http://www.jbrains.ca/users/all&amp;quot;);&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC8&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC9&quot;&gt;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC10&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/183817/8da0bc3562fb0502941814ec06cf997d342c50f9/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/183817&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Here we could replace class &lt;code&gt;FindAllUsersRequest&lt;/code&gt; with a method on a &lt;code&gt;GetRequestFactory&lt;/code&gt;&amp;mdash;an instance where I find a factory appropriate.&lt;/p&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;http://gist.github.com/stylesheets/gist/embed.css&quot;/&gt;&lt;div id=&quot;gist-183818&quot; class=&quot;gist&quot;&gt;
&lt;div class=&quot;gist-file&quot;&gt;
&lt;div class=&quot;gist-data gist-syntax&quot;&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;div class=&quot;line&quot; id=&quot;LC1&quot;&gt;class GetRequestFactory {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC2&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;static GetRequest findAllUsers(parameters) {&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC3&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return new GetRequest(requestUrl: URL.create(&amp;quot;http://www.jbrains.ca/users/all&amp;quot;), parameters);&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC4&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/div&gt;&lt;div class=&quot;line&quot; id=&quot;LC5&quot;&gt;}&lt;/div&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;gist-meta&quot;&gt;
&lt;a href=&quot;http://gist.github.com/raw/183818/eed99761e33790a9686d204167b1585367bab956/gistfile1.txt&quot; style=&quot;float:right;&quot;&gt;view raw&lt;/a&gt;
&lt;a href=&quot;http://gist.github.com/183818&quot;&gt;This Gist&lt;/a&gt; brought to you by &lt;a href=&quot;http://github.com&quot;&gt;GitHub&lt;/a&gt;.
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In this case, we go from a class hierarchy with high duplication in the methods to a class hierarchy with duplication in which methods they override and that they override them to return simple values we could store (and memoize!). From here, we remove the subclasses, as they don&amp;#8217;t pull their weight.&lt;/p&gt;
&lt;p&gt;So the next you refactor a class hierarchy, watch to see whether your hierarchy wants to become a degenerate one like the example here. If so, I recommend you consider collapsing it.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/277';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/277&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 10, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 10 Sep 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/277</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Interlude: The Tutorial</title>
      <link>http://jbrains.ca/permalink/259</link>
      <description>&lt;div class='entry posting' id='entry-_posting_259'&gt;
&lt;div class='posting' id='content-_posting_259'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I presented Integration Tests Are A Scam as a tutorial at Agile 2009. Since I haven&amp;#8217;t managed to summarize more of my ideas on the subject, let me lean on Gabino Roche, Jr. to &lt;a href=&quot;http://tinyurl.com/nlrkhf&quot;&gt;do that for me&lt;/a&gt;. He refers to my earlier work describing &lt;a href=&quot;http://www.jbrains.ca/permalink/165&quot;&gt;contract tests&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I hope this helps the ones of you who&amp;#8217;ve anticipated my writing more on the topic.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/259';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/259&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 02, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/integrated-tests-are-a-scam&quot;&gt;integrated tests are a scam&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 02 Sep 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/259</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Ask first; conclude later</title>
      <link>http://jbrains.ca/permalink/258</link>
      <description>&lt;div class='entry posting' id='entry-_posting_258'&gt;
&lt;div class='posting' id='content-_posting_258'&gt;
&lt;div style='text-align: justify'&gt;
&lt;blockquote style=&quot;font-size: small;&quot;&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;&lt;em&gt;I became embroiled in a melee over the Gordon Pask Award yesterday in Twitterland. People suggested I write about those conversations here to clarify the award&amp;#8217;s purpose, but instead, I decided to write about an incident emblematic of the root cause of the Pask Award confusion.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;My wife, Sarah, pointed me to this article, intriguingly titled &lt;a href=&quot;http://blogs.zdnet.com/weblife/?p=149&quot;&gt;I&amp;#8217;m done with GMail&lt;/a&gt; complaining that GMail doesn&amp;#8217;t have folders, so he can&amp;#8217;t get to Inbox Zero.&lt;/p&gt;
&lt;p&gt;Sigh.&lt;/p&gt;
&lt;p&gt;I wanted to reply with the following, but ZDNet waited until I pressed &amp;#8220;Add Your Opinion&amp;#8221; to tell me I must register to post replies. Since I&amp;#8217;ve read &lt;a href=&quot;http://tinyurl.com/kn7suv&quot;&gt;Influence&lt;/a&gt; I don&amp;#8217;t fall for the Consistency principle much any more. That means I had to post my response here. Enjoy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hello, there.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;As you know by now, labels act like folders, and if you use &lt;span class=&quot;caps&quot;&gt;IMAP&lt;/span&gt; for sharing mail between GMail online and an offline mail client, labels become folders. I&amp;#8217;m not here just to repeat those two points.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I&amp;#8217;d like to offer this advice: next time when something /really/ doesn&amp;#8217;t act the way you&amp;#8217;d expect it to, ask a question. I recommend this question:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I&amp;#8217;ve used Yahoo! mail and GMail, and it shocks me that GMail doesn&amp;#8217;t have folders. I know the people at Google use email, so they can&amp;#8217;t have all decided that folders have no value. That just doesn&amp;#8217;t compute to me. There must be a way to have folders in GMail that I can&amp;#8217;t see. Will someone please tell me what&amp;#8217;s going on here?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Maybe if you&amp;#8217;d done this instead of accusing GMail of ruthlessly taking a feature away from you, then you wouldn&amp;#8217;t have looked like such an idiot or dick for posting this.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Don&amp;#8217;t worry: we all learn this lesson eventually.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/258';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/258&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 31, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/communicating-effectively&quot;&gt;communicating effectively&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 31 Aug 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/258</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Awesome virtual personal assistant/research needs work</title>
      <link>http://jbrains.ca/permalink/257</link>
      <description>&lt;div class='entry posting' id='entry-_posting_257'&gt;
&lt;div class='posting' id='content-_posting_257'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have worked with Rebecca Slominsky (annaonthemoon79 at gmail dot com) a few times and she has done thorough, quick, and professional research for me. If you need an affordable, excellent virtual personal assistant, I highly recommend her. If you&amp;#8217;ve thought about outsourcing some annoying task that anyone anywhere in the world could do, then do please hire Rebecca to do it. Reasonable rates, excellent work, excellent service.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/257';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/257&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 19, 2009  08:00
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 19 Aug 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/257</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>libxml2: Can't upgrade it; can't downgrade it</title>
      <link>http://jbrains.ca/permalink/256</link>
      <description>&lt;div class='entry posting' id='entry-_posting_256'&gt;
&lt;div class='posting' id='content-_posting_256'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;It started simply enough: I wanted to use &lt;code&gt;webrat&lt;/code&gt; to write view specs with its &lt;code&gt;Matchers&lt;/code&gt; to add some specs to this very weblog. I swear, that&amp;#8217;s all I wanted to do.&lt;/p&gt;
&lt;p&gt;When I managed to run those specs properly, I&amp;#8217;d get this message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;HI.  You&amp;#8217;re using libxml2 version 2.6.16 which is over 4 years old and has plenty of bugs.  We suggest that for maximum &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt;/&lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; parsing pleasure, you upgrade your version of libxml2 and re-install nokogiri. If you like using libxml2 version 2.6.16, but don&amp;#8217;t like this warning, please define the constant I_KNOW_I_AM_USING_AN_OLD_AND_BUGGY_VERSION_OF_LIBXML2 before requring nokogiri.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Very well: let me upgrade &lt;code&gt;libxml2&lt;/code&gt;. Big mistake.&lt;/p&gt;
&lt;p&gt;I tried downloading &lt;code&gt;libxml2&lt;/code&gt; version 2.7, then I went through the usual motions: &lt;code&gt;configure&lt;/code&gt;, &lt;code&gt;make&lt;/code&gt;, &lt;code&gt;sudo make install&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Then I couldn&amp;#8217;t run anything. Sometimes I couldn&amp;#8217;t even boot. I kept seeing the &lt;code&gt;wrong architecture&lt;/code&gt; message when I tried to run various programs on my MacBook.&lt;/p&gt;
&lt;p&gt;I tried deleting &lt;code&gt;libxml&lt;/code&gt; from &lt;code&gt;/usr/lib&lt;/code&gt; and rebuilding, but then I couldn&amp;#8217;t even &lt;code&gt;sudo&lt;/code&gt;. I didn&amp;#8217;t know what the hell was going on.&lt;/p&gt;
&lt;p&gt;Finally, I booted from my backup disk (thank you, SuperDuper!) and copied &lt;code&gt;/usr/lib/libxml*&lt;/code&gt; back onto my internal hard disk. I booted from my internal disk and all returned to normal, including the annoying &lt;code&gt;nokogiri&lt;/code&gt; message. I suppose I&amp;#8217;ll have to live with the message for now.&lt;/p&gt;
&lt;p&gt;Still&amp;#8230; has anyone successfully upgraded &lt;code&gt;libxml&lt;/code&gt; to version 2.7 on Mac OS 10.5.7? I&amp;#8217;d like to know.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/256';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/256&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 13, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/rails&quot;&gt;rails&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/mac&quot;&gt;mac&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/adventures-in-RSpec&quot;&gt;adventures in RSpec&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 13 Aug 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/256</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Design your own TDD course!</title>
      <link>http://jbrains.ca/permalink/255</link>
      <description>&lt;div class='entry posting' id='entry-_posting_255'&gt;
&lt;div class='posting' id='content-_posting_255'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Do you know someone who needs a strong, in-depth introduction to test-driven development and modular design? How about someone who wants to take the next step in their evolution as a &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; practitioner? How about someone stuck on the merry-go-round of too many defects, a long backlog of feature requests, too many times designing themselves into a corner?&lt;/p&gt;
&lt;p&gt;&amp;#8230;or is that someone &lt;em&gt;you&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.obtiva.com&quot;&gt;Obtiva&lt;/a&gt; and I would like to present an uncommon opportunity for would-be &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; practitioners: a chance to design your own &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; course with me over three days. You get to learn what you want to learn, practise what you want to practise, do what you want to do. All you need to do is &lt;a href=&quot;http://tinyurl.com/n2y2yk&quot;&gt;register now&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now I know what one of you is thinking: this sounds like a trainer who&amp;#8217;s too lazy to design a course and wants me to do his work for him.&lt;/p&gt;
&lt;p&gt;Not at all. I have already designed a great introductory &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; course, and I&amp;#8217;ll teach that to whoever wants it, but I want to teach you what &lt;em&gt;you&lt;/em&gt; want to learn, and I&amp;#8217;m ready to do that &lt;a href=&quot;http://tinyurl.com/n2y2yk&quot;&gt;&lt;strong&gt;August 31 to September 2, 2009 at Obtiva in Chicago, Illinois, &lt;span class=&quot;caps&quot;&gt;USA&lt;/span&gt;&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can look through this site for the &lt;a href=&quot;http://www.jbrains.ca/training&quot;&gt;courses I&amp;#8217;ve taught&lt;/a&gt; and for the &lt;a href=&quot;http://www.jbrains.ca/services&quot;&gt;services I provide&lt;/a&gt; for ideas on what we might practise together. I only ask you to keep the topics in the area of test-driven development and modular design. (I treat object-oriented design as modular design with objects, so consider that your free sample.)&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re planning to attend &lt;a href=&quot;http://agile2009.agilealliance.org&quot;&gt;Agile 2009&lt;/a&gt;, then stay an extra few days to &lt;a href=&quot;http://tinyurl.com/n2y2yk&quot;&gt;solidify your understanding of test-driven development and modular design&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I hope to see you there.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/255';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/255&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 30, 2009  15:22
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/training&quot;&gt;training&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 30 Jul 2009 15:22:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/255</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>An open call to Agile 2010 submitters</title>
      <link>http://jbrains.ca/permalink/254</link>
      <description>&lt;div class='entry posting' id='entry-_posting_254'&gt;
&lt;div class='posting' id='content-_posting_254'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I finally read &lt;a href=&quot;http://tinyurl.com/czxfnt&quot;&gt;Mark Levison&amp;#8217;s thoughtful weblog entry&lt;/a&gt; about his experiences reviewing and selecting session proposals for Agile 2009. He makes a number of suggestions, which I reproduce here:&lt;/p&gt;
&lt;div style=&quot;margin-left: 5%; margin-right: 5%&quot;&gt;
&lt;ul&gt;
	&lt;li&gt;Authors need to know that proposals are being reviewed/commented and that replies/updates are a critical part of the acceptance process.&lt;/li&gt;
	&lt;li&gt;Authors need to be notified when a comment/review is added.&lt;/li&gt;
	&lt;li&gt;People who write comments/reviews need to know when replies are made&lt;/li&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt; is not the the only notification system some of use still prefer email.&lt;/li&gt;
	&lt;li&gt;The difference between comments and reviews needs to be made more clear.&lt;/li&gt;
	&lt;li&gt;&#8220;Browse session proposals&#8221; page needs to display the length of the sessions. It makes it easier to make decisions if we know their length.&lt;/li&gt;
	&lt;li&gt;Proposal database should exportable to spreadsheet. A web page is handy but once the hard work begins it would be alot easier if I could just work in Excel or even Google Docs.&lt;/li&gt;
	&lt;li&gt;I don&#8217;t want recommendations visible to the proposal author. These are often friends and colleagues who I want to work with again. This maybe true today but I can&#8217;t tell.&lt;br /&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whether you agree with all Mark&amp;#8217;s suggestions, I think that unless a number of us volunteer to own some feature requests, nothing will change for Agile 2010. I volunteer to own the feature requests related to notifying submitters about comments and reviews. I will send Jim Newkirk, the Agile 2010 chair, an email asking him how I can make myself a customer of the submission system.&lt;/p&gt;
&lt;p&gt;Which feature request do you volunteer to own?&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/254';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/254&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 29, 2009  16:12
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile-2010&quot;&gt;agile 2010&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 29 Jul 2009 16:12:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/254</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Interlude: Basic Correctness</title>
      <link>http://jbrains.ca/permalink/253</link>
      <description>&lt;div class='entry posting' id='entry-_posting_253'&gt;
&lt;div class='posting' id='content-_posting_253'&gt;
&lt;div style='text-align: justify'&gt;
&lt;blockquote style=&quot;font-size: small;&quot;&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;&lt;em&gt;I tried to respond to &lt;a href=&quot;http://jbrains.ca/permalink/251#jsid-1248210041-10&quot;&gt;a comment from James Bach&lt;/a&gt;, but surpassed the 3000-character limit, so I&amp;#8217;ve decided to add this long comment as a short article.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;James Bach&lt;/strong&gt;: I don&amp;#8217;t understand the point of calling a failure discovered by running a test &amp;#8220;unjustifiable.&amp;#8221; Let me offer you a justification: I &lt;span class=&quot;caps&quot;&gt;WANT&lt;/span&gt; TO &lt;span class=&quot;caps&quot;&gt;FIND&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;BUGS&lt;/span&gt;. :)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;J. B. Rainsberger&lt;/strong&gt;: Now now, changing the definition of a term on me constitutes dirty pool. Stop that! :)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;James Bach&lt;/strong&gt;: When you say &amp;#8216;Presumably, we have tests that intend to test step 2, which justifiably fail&amp;#8217; I would say that sounds like a dangerous presumption. Just because we write a test, and that test has a purpose, does not mean the test achieves its purpose. In fact, as far as we know a test &lt;span class=&quot;caps&quot;&gt;NEVER&lt;/span&gt; achieves its deeper purpose of finding all possible interesting bugs in the thing it is testing. Of course, when I test, I want to find all interesting bugs, and of course, I will never know that I have found all of them worth finding.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;J. B. Rainsberger&lt;/strong&gt;: I think you&amp;#8217;ve taken my specific definition of &amp;#8220;justifiable failure&amp;#8221; and extended it past how I chose to use the term. When I write a test that fails because of a defect in the code that test intends to focus on, then I call that failure justifiable. All other failures are not justifiable. As a result, the statement you zeroed in on appears tautological to me&amp;#8230; except my sloppy use of &amp;#8220;presumably&amp;#8221;. Let me clarify what I left unexpressed. Let&amp;#8217;s assume that we have used integration tests to test the five-step process minimally broadly (in other words, we have written tests to find at least all basic correctness defects). That means that we&amp;#8217;ve written some tests specifically to check step 2. Suppose now the existence of a defect in only step 2. When our test for step 4 fails because of the defect in step 2, the tests for step 2 fail justifiably, while the tests for step 4 fail unjustifiably. I haven&amp;#8217;t yet turned my attention to latent and lurking defects, for the reason I provide at the end of this comment.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;James Bach&lt;/strong&gt;: &amp;#8230; That&amp;#8217;s why I use a diversified test strategy. It seems to me that complicated integration tests that cover ground also covered in other tests is a reasonable strategy&amp;#8212; as long as it is not too expenses to produce or maintain. There is a cost/benefit that must be weighed against an opportunity cost, of course.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;J. B. Rainsberger&lt;/strong&gt;: I agree; however, I see too many programmers (in particular) using integration tests to help them find or avoid defects that much less expensive isolated object tests would better help them find or avoid. I center my entire argument on the thesis that too many programmers use these tests in a way that leads to considerable wasted effort in maintenance.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;James Bach&lt;/strong&gt;: So, perhaps you are talking about a restricted context where its not worth the effort of testing a particular function indirectly. Maybe not, but I bet it&amp;#8217;s worth considering that sort of testing. Personally, I like automation that touches a lot of things in a lot of places, as long as I can create and maintain it without too much disruption of my sapient testing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;J. B. Rainsberger&lt;/strong&gt;: Indeed so! I have wanted to reveal these points gradually so as to avoid writing 20,000 words at once, but I limit the arguments in this series to a specific context: programmers writing tests to show the basic correctness of their code. By &lt;em&gt;basic correctness&lt;/em&gt; I refer to the myth of perfect technology: if I ran the system on perfect technology, would it (eventually) compute the right answer every time? I would call such a system &lt;em&gt;entirely basically correct&lt;/em&gt;. While integration tests offer value in other contexts, too many programmers use them to show basic correctness, and when they do that they waste a tremendous amount of time and effort.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/253';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/253&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 22, 2009  02:43
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/integrated-tests-are-a-scam&quot;&gt;integrated tests are a scam&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 22 Jul 2009 02:43:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/253</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Interpreting inaccurate estimates</title>
      <link>http://jbrains.ca/permalink/252</link>
      <description>&lt;div class='entry posting' id='entry-_posting_252'&gt;
&lt;div class='posting' id='content-_posting_252'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I ran across &lt;a href=&quot;http://tinyurl.com/m8rqv7&quot;&gt;this&lt;/a&gt; today and thought I&amp;#8217;d comment briefly about it. How can you interpret inaccurate estimates? What might it mean when you estimate incorrectly?&lt;/p&gt;
&lt;p&gt;I know individuals that beat themselves up over inaccurate estimates. I know teams that beat each other up. I know managers that beat up their teams. I even know a company that awards bonus compensation based on the accurate of their programmers&amp;#8217; estimates. In those environments, inaccurate estimates hurt, so although I don&amp;#8217;t like cost estimates in general for most teams most of the time, I recognize that some people must play the game to keep their job. That said, I return to something Ward Cunningham said in the early days about Fit: when we look at test results in a spreadsheet, we can look at patterns of red cells to learn something about our patterns of failure. He drew our attention to two kinds of patterns: systematic failure and sporadic failure.&lt;/p&gt;
&lt;p&gt;In the early XP literature, books like &lt;em&gt;Planning XP&lt;/em&gt; told us that by measuring velocity we gracefully handle systematic estimate inaccuracy as the &amp;#8220;value&amp;#8221; of our story points fluctuates over time. Think of it like a floating currency: its value in hours changes slowly over time as our ability to complete points improves. If you prefer to estimate in hours, then after several months, you might notice a bunch of stories whose actual costs were close to some constant multiplier of the estimate. In that case, you would consider multiplying all remaining estimates by that constant until you internalized it and began estimating in the &amp;#8220;new scale&amp;#8221; out of habit. Even when I cared deeply about cost estimates, I worried little about systematic inaccuracies.&lt;/p&gt;
&lt;p&gt;Sporadic inaccuracy hurts more. Since we provide cost estimates to that others might plan, we owe it to them to lower the variance of the actual cost of our work, in order to make planning more useful. I have developed a conjecture over the last few years that changes the question of sporadic estimate inaccuracy:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The actual cost of a story depends on (among other things) the complexity of the story and the current state of the design. The higher our technical debt, the more that cost dominates the cost of the story.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I have noticed various people floating the definition of &amp;#8220;technical debt&amp;#8221; to suit their needs, so I want to clarify what I mean by &amp;#8220;technical debt&amp;#8221;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;By &lt;em&gt;technical debt&lt;/em&gt; I refer to the latent cost of the amount of rot in the design. I think of technical debt as the cost of the design improvements we need to make in order to feel comfortable adding features or fixing defects in that part of the system.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can think of technical debt as financial debt: interest-bearing principal owed to another party. In this case, the other party is the system or the project, the principal is the current design and the interest is the extra cost associated with either rescuing or working around the current design. With these definitions established, I can state my conjecture this way:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In systems with high technical debt, the cost of repaying that technical debt dominates the cost of a story.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since not all stories affects all parts of the design uniformly, we can do a little better:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The cost of a story depends on the complexity of the story and the amount of technical debt in the areas of the design we need to change or extend to deliver the story. Working in areas with high technical debt causes the cost of repaying that debt to dominate the cost of the story.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I think you get the point. From this it follows that in systems with generally high technical debt, the &lt;em&gt;distribution&lt;/em&gt; of technical debt effectively determines the variance in the cost of the stories. Sporadic estimate inaccuracy, then, likely has a clear root cause: high technical debt distributed decidedly non-uniformly. This follows logically, because if the system distributed technical debt uniformly, then our estimates would show systematic inaccuracy.&lt;/p&gt;
&lt;p&gt;This allows me to make two broad claims:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;In general, if a system has high and sporadic technical debt, we&amp;#8217;ll tend to estimate with sporadic inaccuracy &lt;em&gt;even if we estimate the relative complexity of those stories with perfect accuracy&lt;/em&gt;.&lt;/li&gt;
	&lt;li&gt;In general, we should estimate with at most systematic inaccuracy when delivering stories for a greenfield system or component.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I can interpret these claims more pithily:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;If your estimates suck when adding features to a legacy system, blame the shittiness of the codebase.&lt;/li&gt;
	&lt;li&gt;If your estimates such when adding features to mostly clean code, blame the shittiness of the programmers.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In particular, if you feel bad because your estimates suck when adding features to a legacy system, &lt;em&gt;you can relax&lt;/em&gt;. As you attempt to build those features with high discipline, the resulting volatility in your actual costs will come from the current state of the design. The design will actually try to convince you to cut corners. Cutting corners can only improve the accuracy of your estimate for the current story &lt;em&gt;at the expense of the remaining stories&lt;/em&gt;. Cutting corners can only get your project manager off your back for a day or two. You will eventually need to stop cutting corners.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/252';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/252&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 21, 2009  18:48
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/stories&quot;&gt;stories&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 21 Jul 2009 18:48:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/252</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Part 3: The risks associated with lengthy tests</title>
      <link>http://jbrains.ca/permalink/251</link>
      <description>&lt;div class='entry posting' id='entry-_posting_251'&gt;
&lt;div class='posting' id='content-_posting_251'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I just read a tweet from Dale Emery that turned my attention back to the topic of integration tests and their scamminess.&lt;/p&gt;
&lt;p&gt;&lt;iframe name=&quot;tp54114&quot; id=&quot;tp54114&quot; width=&quot;500&quot; height=&quot;200&quot; frameborder=&quot;0&quot; src=&quot;http://tweetpaste.thingamaweb.com/embed/54114/&quot; style=&quot;overflow: hidden; display: block; width: 500px; height: 200px;&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://tweetpaste.thingamaweb.com/embed/54114/&quot; target=&quot;_blank&quot;&gt;View dhemery&amp;rsquo;s tweet&lt;/a&gt;&lt;/p&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;Since practitioners tend to write acceptance tests as end-to-end (or integration) tests, I think I can safely substitute the phrase &amp;#8220;integration tests&amp;#8221; here for &amp;#8220;acceptance tests&amp;#8221; and retain the essence of Dale&amp;#8217;s meaning. I do this because I don&amp;#8217;t want you to conclude from what I plan to write that I treat acceptance tests with the same disdain as I treat integration tests. I already went through that when Eric Lefevre-Ardant introduced us to &lt;a href=&quot;http://agile2009.wordpress.com/2009/07/13/meet-david-agile-developer/&quot;&gt;David, Agile Developer&lt;/a&gt;, one of the personas that the Agile 200x conference has developed to help people choose sessions at the conference. While I felt flattered that he chose my session as one to attend, he accidentally misnamed it &amp;#8220;Acceptance Tests Are A Scam&amp;#8221;, which set off a miniature firestorm in Twitterland. In short: I like acceptance tests when we write them to confirm the presence of a feature; and I dislike them when programmers write integration tests, checking the design and behavior of large parts of the system, and call them &amp;#8220;acceptance tests&amp;#8221; to justify their existence.&lt;/p&gt;
&lt;p&gt;Back to Dale&amp;#8217;s question, which I paraphrase: how often do we write faulty integration tests, meaning that the test failure points to an error in the test, rather than in the production code? Rather than attempt to answer that question, I prefer to write about a strongly related idea: integration tests &lt;em&gt;necessarily&lt;/em&gt; fail more frequently and in a more costly manner than isolated object tests, even when the underlying production code behaves as expected. To simplify the discourse a bit, let me introduce the term &lt;em&gt;unjustifiable test failure&lt;/em&gt; to mean a test failure without a corresponding defect in the production code. When an incorrect test fails, I will call that failure unjustifiable.&lt;/p&gt;
&lt;h2&gt;The cost of unjustifiable test failures&lt;/h2&gt;
&lt;p&gt;An unjustifiable failure has both a clear cost an a hidden cost. We know the immediate, clear cost: an unjustifiable failure causes me to do root cause analysis on a nonexistent failure, which costs me something and gains me nothing. More insidious, though, persistent false failures erode my confidence in the tests. I tend to value the tests less. I run them less frequently, reducing the actual value I get from the resulting feedback. With less feedback comes less confidence in the code, and more conservative behavior. I change the code less frequently; I avoid extensive changes, even when they seem appropriate; I entertain fewer ideas because I can&amp;#8217;t as easily predict the cost of the corresponding changes. I start designing not to lose, rather than designing to win. I can&amp;#8217;t quantify that cost on a given project, but I know it in my heart and we could measure it over time. I think one should eliminate unjustifiable test failures where possible, or at least where easy, and integration tests simply cause an avoidably large number of unjustifiable failures.&lt;/p&gt;
&lt;h2&gt;Integration tests fail unjustifiably more frequently&lt;/h2&gt;
&lt;p&gt;Let me support this conjecture with two key arguments.&lt;/p&gt;
&lt;p&gt;First, integration tests tend to require more lines of code than isolated object tests. Perhaps more formally, as we write more integration tests and more isolated object tests in a system, the average length of the integration tests becomes considerably larger&amp;mdash;at least double&amp;mdash;than the average length of the corresponding isolated object test. If we accept this premise, then combine it with the well-accepted premise that more code means more defects &lt;em&gt;in general&lt;/em&gt;, then it follows directly that integration tests tend to have more defects than isolated object tests. This means that integration tests fail unjustifiably more frequently than isolated object tests.&lt;/p&gt;
&lt;p&gt;Next, because integration tests rely on the correctness of more than one object, it follows directly that a defect in an object results in more integration test failures as compared to the number of failures in corresponding isolated object tests. That production defect, then, results in two classes of test failures: justifiable ones in tests designed to verify the defective behavior, and unjustifiable ones in tests design to verify another behavior, but that happen to execute the defective code.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can envision an example of the latter case by thinking of an integration test that verifies a specific alternate path in step 4 of a 5-step process. This test must execute steps 1 through 3 of the process in order to execute step 4, so if we have a defect in step 2 of the process, then this test fails unjustifiably, because it does not actively try to verify step 2. While the test failure can be justified by a defect in step 2, I call the failure &lt;em&gt;unjustifiable with respect to the behavior under test&lt;/em&gt;, because this test does not deliberately attempt to test step 2. Presumably, we have tests that intend to test step 2, which justifiably fail.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Integration tests, then, result in unjustifiable failures by executing some potentially defective behavior without intending to verify it. While I wouldn&amp;#8217;t call this a defect in the test, the test nevertheless fails unjustifiably.&lt;/p&gt;
&lt;p&gt;I have tried here to describe the problem of unjustifiable test failures and to explain how integration tests necessarily result in more unjustifiable test failures than isolated object tests. I admit that I have not compared the cost of these unjustifiable test failures to the corresponding costs of writing isolated object tests. I cannot hope to complete a thorough quantitative study on the matter. Instead, I simply want to raise the issues, make some conjectures, reason well about them, then let the reader decide. I have decided to write more isolated object tests and fewer integration tests unless I find myself in a drastically different context than the ones I&amp;#8217;ve seen over the past decade or so.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/251';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/251&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 20, 2009  21:17
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/stories&quot;&gt;stories&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/integrated-tests-are-a-scam&quot;&gt;integrated tests are a scam&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 20 Jul 2009 21:17:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/251</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Nominate someone for the 2009 Gordon Pask Award!</title>
      <link>http://jbrains.ca/permalink/250</link>
      <description>&lt;div class='entry posting' id='entry-_posting_250'&gt;
&lt;div class='posting' id='content-_posting_250'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p style=&quot;float: right; padding: 0px 0px 0px 10px;&quot;&gt;&lt;img src=&quot;http://images.jbrains.ca/gordon-pask-logo.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The Gordon Pask Award recognizes two people whose recent contributions to Agile Practice make them, in the opinion of the award committee, people others in the field should emulate. In order that people might emulate them, the Agile Alliance will fund each recipient&amp;#8217;s travel to two different suitable conferences on two different continents. In order to grow the next generation of Agile thought leaders, we give the award to people who have not yet become conference speaking regulars, in part because they have not yet developed a widespread reputation as a top practitioner.&lt;/p&gt;
&lt;h2&gt;Who is Your Mentor?&lt;/h2&gt;
&lt;p&gt;We need your help to identify the next two Gordon Pask Award winners. Please send your nominations to &lt;a href=&quot;mailto:pask-nominations@agilealliance.org&quot;&gt;pask-nominations@agilealliance.org&lt;/a&gt;, including the nominee&amp;#8217;s name, email address and a short summary of your reasons for making the nomination, limited to 200 words.&lt;/p&gt;
&lt;p&gt;In the spirit of Gordon Pask&amp;#8217;s work (see below), we expect you to nominate someone you&amp;#8217;ve learned from directly, face-to-face.  You might also consider asking for additional people to add their names to your nomination. More names don&amp;#8217;t necessarily carry more weight, but they do give us more people to ask about the nominee. Previous winners can be found at the &lt;a href=&quot;http://www.agilealliance.org/show/1656&quot;&gt;Agile Alliance&amp;#8217;s site&lt;/a&gt;.  Award founder Brian Marick comments that the selection process is always difficult:  &amp;#8220;We always worried a lot that it would feel arbitrary&amp;#8230; I&#8217;ve gotten complaints that it&#8217;s too much of a programming award and not enough of a management award and that could well be true.&amp;#8221;  There are always many qualified nominees, who are ruled out when the committee asks &#8220;Does this person actually need our help?&#8221;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;We will accept nominations until August 1, 2009.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;About the Gordon Pask Award&lt;/h2&gt;
&lt;p&gt;Laurent Bossavit, a 2006 recipient, says &amp;#8220;one of the more appealing traits of the agile community [is] that it provides room for new voices to be heard and to offer original contributions&amp;#8221;.  This is a community that fully embraces the notion that through face-to-face conversation comes enhanced understanding&amp;#8230; a community that believes that thoughtful critics and new enthusiasts alike have something to offer.  This emphasis on discourse is partially inspired by the work of Gordon Pask and other cyberneticians, who practically &amp;#8220;had no effect. Eventually they retired, or died, and that was kind of the end of it. The first wave of people failed to build up the next wave,&amp;#8221; according to Brian Marick.  The Agile Alliance&amp;#8217;s support of this award shows a strong commitment to nurture growth and discovery in the agile arena, and to further emphasize its significance, currently it is the &amp;#8220;only award that the Agile community gives,&amp;#8221; says James Shore (2005 recipient).&lt;/p&gt;
&lt;h2&gt;Agility is a Social Phenomenon&lt;/h2&gt;
&lt;p&gt;This is a community of artisans, constantly trying to hone their skills by taking notes from one another.  Bossavit says &amp;#8220;I benefited a lot from the writings of the &amp;#8216;official&amp;#8217; founders of Agile, many of them among the original signatories of the Manifesto&amp;#8230; [but I] couldn&amp;#8217;t have learned about XP, Scrum and all that solely from reading books or articles. Rather, my understanding grew from the opportunity to participate, interactively, in several communities. These included on-line communities such as Ward Cunningham&amp;#8217;s Wiki and the XP mailing list, and real-life gatherings such as the european XP200x conference, the various XP Days, and so on.  I have a huge debt to Jerry Weinberg&amp;#8230; for fostering a community of people passionate about &amp;#8216;peopleware&amp;#8217;, about the human, sociological, psychological  aspects of software.&amp;#8221;&lt;/p&gt;
&lt;p&gt;Agilists are finding better ways to work, to learn, and to teach.  2005 recipient James Shore says he learns by &amp;#8220;trying things and seeing if they work&amp;#8221;, but that&amp;#8217;s not all.  He gained a lot of insight by working with his local Agile User&amp;#8217;s group.  He says, &amp;#8220;I&amp;#8217;d bring in my problems and we&#8217;d talk about them and I&#8217;d say, &amp;#8216;That can&#8217;t possibly work&amp;#8217; and I would go away and try it and come back and say, &amp;#8216;Well, you know&#8230; that worked. Here&#8217;s what I did and now here&#8217;s the new problem I&#8217;m having,&amp;#8217; [something] I wish more people would do.&amp;#8221;  Regarding learning by doing, he goes on to say that, &amp;#8220;training some times works&amp;#8230; you can pick this stuff up from books&amp;#8230; [but] following a leader who has done it before; having them work with you directly is by far the most effective way of getting it in to place quickly&amp;#8221;.  Instead of training sessions in lecture format, 2005 winner J.B. Rainsberger says that he &amp;#8220;tells people stories&amp;#8230; which helps them understand&amp;#8221;.  If you go to any of the agile conferences, you&amp;#8217;ll find games, workshops, debates, and other engaging, interactive formats focused on improving communication.  Not only are the user groups and conferences lively.  &amp;#8220;Agile is bringing back the freedom, creativity and innovation back to software development. It is making life easy and enjoyable for software craftsmen. And I&amp;#8217;m glad to be a part of such a movement,&amp;#8221; says 2007 winner Naresh Jain.&lt;/p&gt;
&lt;h2&gt;Gordon Pask&amp;#8212;Improved Understanding through Discourse&lt;/h2&gt;
&lt;p&gt;The Gordon Pask Award embeds a special message for the Agile Community.  &amp;#8220;Lots of big names are projecting a very dogmatic and rigid view about Agile. In my experience Agile is nothing on those lines,&amp;#8221; says Naresh Jain.  The problem with mass-broadcasts from &amp;#8220;big names&amp;#8221;, from a Gordon Pask perspective, is that we lose out on the collaborative learning.  It&amp;#8217;s not to say that a rigid view of Agility is incorrect.  James Shore says: &amp;quot;we can&#8217;t just say we won&#8217;t do that piece of Agile. [Instead of asking] &amp;#8220;How are we going to solve that problem in a different way?&amp;#8221;, I see people saying, &amp;#8216;That&#8217;s hard. We&#8217;re just not going to worry about that piece of it.&amp;#8217;&amp;quot;  He clarifies that newcomers would be &amp;#8220;better served by&amp;#8230; seeking excellence than trying to fit in.&amp;#8221;  Trying to fit in by following the letter of the law will not give us the gains in productivity promised by Agile.  &amp;#8220;The big wins are not in doing work in two-week Sprints. The big wins are increasing your communication, working simultaneously, because simultaneous phases are also a way of improving that communication so that you don&#8217;t have a throw-it-over-the-wall mentality.&amp;#8221;&lt;/p&gt;
&lt;p&gt;Kent Beck talks about self-similarity in nature&amp;#8212;that is, design patterns that work well, often are replicated in various sizes and environments.  The fact that communication helps us improve our effectiveness on the job, as well as in the Agile community, is a self-similar pattern mastered by award recipient Kenji Hiranabe.  He says that it was not he who won the award in 2008, but it was the strength of the community in Japan that brought the award to him.  This obvious valuing of community before self is also repeated in their conference marketing: &amp;#8220;we prepared &amp;#8216;Pair discount&amp;#8217; pricing and strongly recommended the attendees to come with their boss or clients. The result was 75% of them came in pairs! I believe it is a sign that engineers, managers, and clients have started talking to one another to make this software development world better&amp;#8230; Along the way of introducing Agile to Japan, they came and formed a good community.&amp;#8221;&lt;/p&gt;
&lt;p&gt;Now it&amp;#8217;s your turn.  Nominate someone that has helped you out&amp;#8230; better yet, collaborate with a few colleagues, face to face, to discover who to nominate.  It takes less time than reading this article!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/250';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/250&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 16, 2009  17:51
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 16 Jul 2009 17:51:58 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/250</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Three upcoming events</title>
      <link>http://jbrains.ca/permalink/248</link>
      <description>&lt;div class='entry posting' id='entry-_posting_248'&gt;
&lt;div class='posting' id='content-_posting_248'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I&amp;#8217;d like to draw your attention to three upcoming events.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.vimeo.com/5429547&quot;&gt;Code Retreat in Toronto on August 8, 2009.&lt;/a&gt; Hone your craft in a pressure-free environment. Costs nothing but your time.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://tinyurl.com/n2y2yk&quot;&gt;Your first steps in &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; in Chicago from August 31 to September 2, 2009.&lt;/a&gt; World-class training in &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; from a leading practitioner. &lt;span class=&quot;caps&quot;&gt;USD&lt;/span&gt; 1500 per student with group discounts available.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://agile2009.agilealliance.org&quot;&gt;Agile 2009&lt;/a&gt; remains the premier conference in the world to learn about all things agile. Learn and practise with top practitioners across the spectrum of software and business roles.&lt;/p&gt;
&lt;p&gt;Please join us!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/248';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/248&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 13, 2009  21:12
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2009&quot;&gt;agile 2009&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/TDD-From-the-Beginning&quot;&gt;TDD From the Beginning&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/Code-Retreat&quot;&gt;Code Retreat&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 13 Jul 2009 21:12:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/248</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Please vote for the next Gordon Pask Award logo</title>
      <link>http://jbrains.ca/permalink/247</link>
      <description>&lt;div class='entry posting' id='entry-_posting_247'&gt;
&lt;div class='posting' id='content-_posting_247'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Sebastian Hermida has prepared more logo ideas for us, and we&amp;#8217;d like your feedback.&lt;/p&gt;
&lt;div style=&quot;text-align:center;&quot;&gt;&lt;a href=&quot;http://twitpic.com/3mpde&quot;&gt;&lt;img src=&quot;http://twitpic.com/show/full/3mpde&quot; title=&quot;I failed in my experiment to include this image directly into this entry. That failed, so unfortunately I must ask you to click.&quot; alt=&quot;I failed in my experiment to include this image directly into this entry. That failed, so unfortunately I must ask you to click.&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;js-kit-poll&quot; path=&quot;/poll/pask-logo-2&quot;&gt;&lt;/div&gt;&lt;script src=&quot;http://js-kit.com/for/jbrains.ca/polls.js&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/247';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/247&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 07, 2009  20:28
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/gordon-pask-award-2009&quot;&gt;gordon pask award 2009&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 07 May 2009 20:28:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/247</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>XP 2009 conference is only one month away!</title>
      <link>http://jbrains.ca/permalink/246</link>
      <description>&lt;div class='entry posting' id='entry-_posting_246'&gt;
&lt;div class='posting' id='content-_posting_246'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;XP 2009 is the leading conference on Agile Methods for software development and industry management held annually in Europe. With keynotes from Mary Poppendieck and Ivar Jacobson and tutorials with Pask Award winners Jeff Patton and Steve Freeman, you wil find yourself among the experts with a rare chance to really talk to them face to face! &lt;a href=&quot;http://tinyurl.com/register-xp2009&quot;&gt;Register today.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/246';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/246&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 30, 2009  00:25
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/xp2009&quot;&gt;xp2009&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 30 Apr 2009 00:25:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/246</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Code Retreat Reykjav&#237;k, May 9, 2009</title>
      <link>http://jbrains.ca/permalink/244</link>
      <description>&lt;div class='entry posting' id='entry-_posting_244'&gt;
&lt;div class='posting' id='content-_posting_244'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I take great pleasure in announcing the first ever Code Retreat outside the US, scheduled in Reykjav&#237;k, Iceland on May 9, 2009. I had the pleasure of co-pre-announcing this event at &lt;a href=&quot;http://www.jbrains.ca/permalink/237&quot;&gt;my March 2009 course there&lt;/a&gt; and feel great that the guys at &lt;a href=&quot;http://www.sprettur.is&quot;&gt;Sprettur&lt;/a&gt; have fulfilled their commitment to organize this event. I hope this represents the first step towards a vibrant &lt;a href=&quot;http://manifesto.softwarecraftsmanship.org&quot;&gt;Software Craftsmanship&lt;/a&gt; community in Iceland.&lt;/p&gt;
&lt;p&gt;Please support your local &lt;a href=&quot;http://coderetreat.ning.com&quot;&gt;Code Retreat&lt;/a&gt; event. I will present one in association with PlateSpin in Toronto on August 8, 2009.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/244';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/244&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 29, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/Code-Retreat&quot;&gt;Code Retreat&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 29 Apr 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/244</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Catalysts Coding Contest</title>
      <link>http://jbrains.ca/permalink/243</link>
      <description>&lt;div class='entry posting' id='entry-_posting_243'&gt;
&lt;div class='posting' id='content-_posting_243'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I received this reminder from Christoph Steindl about the contest, now it its third year. I hope you&amp;#8217;ll take a look and even participate!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Do you have a linear performance curve?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;As a software developer, if you can choose you&#8217;d prefer an algorithm with linear run-time complexity &#8220;O(n)&#8221; over one with quadratic &#8220;O(n&#178;)&#8221; or even exponential complexity &#8220;O(2^n)&#8221;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;As an employer or client, you would prefer software developers who show a linear performance curve even if working under heavy load and stress.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The best developers solve difficult problems with the same speed as simpler ones &amp;#8211; their performance curve is linear. On our Hall of Fame you can see for last year&#8217;s contest which participants exhibited a quasi linear performance curve, and which ones showed a quadratic or exponential one.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;This year, everyone can participate in the &lt;a href=&quot;http://www.catalysts.cc/en/events/2009/coding-contest/&quot;&gt;Catalysts Coding Contest&lt;/a&gt; over the Internet, so it&#8217;s a real worldwide competition.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;During the last years we had 60 onsite participants, this year we hope to get 100 onsite + remote participants &#8211; which would then be a large enough code base to draw some valuable conclusions for our research questions:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
	&lt;li&gt;Who is faster? Who is more efficient? Who is more effective? Who is more productive?&lt;/li&gt;
	&lt;li&gt;Does &#8220;Pair Programming&#8221; really make you faster?&lt;/li&gt;
	&lt;li&gt;Does &#8220;Test-Driven Development&#8221; really lead to fewer bugs?&lt;/li&gt;
	&lt;li&gt;How many ways are there to solve a problem?&lt;/li&gt;
	&lt;li&gt;Which programming language is most appropriate for the problem?&lt;/li&gt;
	&lt;li&gt;How many lines of code are necessary?&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;The contest will take place on Friday, June 5th, in the afternoon. The participation fee is just 1 &lt;span class=&quot;caps&quot;&gt;EUR&lt;/span&gt; for remote participants (otherwise we couldn&#8217;t probably distinguish real registrations from fake registrations). &lt;a href=&quot;http://www.catalysts.cc/en/events/2009/coding-contest/&quot;&gt;Please join us!&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/243';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/243&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 16, 2009  16:59
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 16 Apr 2009 16:59:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/243</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Part 2: Some Hidden Costs of Integration Tests</title>
      <link>http://jbrains.ca/permalink/242</link>
      <description>&lt;div class='entry posting' id='entry-_posting_242'&gt;
&lt;div class='posting' id='content-_posting_242'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;&lt;a href=&quot;/category/named/integration-tests-are-a-scam&quot;&gt;Read more in this series&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I fear that this first article in the series may be attacking a view that very few people hold: the idea that one should test all code paths by integration testing alone.&lt;/em&gt; &amp;mdash; Dan Fabulich&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When I tell &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; practitioners &lt;a href=&quot;http://www.jbrains.ca/permalink/239&quot;&gt;my opinion about integration tests&lt;/a&gt;, some treat my position as a straw man. They point out that &amp;#8220;no one&amp;#8221; seriously tries to test entire systems exclusively with integration tests. While I understand their reaction, I need to point out that I never made that claim. I see far more damaging behavior in teams that practise &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;: they duplicate a sizable amount of their effort by designing their objects with thorough focused tests, then adding a suite of integration tests that  verify a substantial amount of the same behavior. I understand why they do it. I used to do it. And I want them to stop.&lt;/p&gt;
&lt;p&gt;Every integration test costs&amp;#8230; well, I don&amp;#8217;t know how to accurately say how much it costs. After computing the superficial cost of writing and maintaining the test, I quickly lose track of the varying effects of writing integration tests in place of, or even in addition to, focused object tests. I can compute the raw execution time tax on integration tests: an average focused test executes in 4 ms, while an average integration tests takes closer to 100 ms. I feel comfortable estimating the difference at a more conservative order of magnitude base 10. Beyond that, I find myself lost in the implications of writing integration tests to form a clear picture of the cost. Let me give you an idea of what I mean.&lt;/p&gt;
&lt;p style=&quot;font-weight: bold; font-size: 120%; font-variant: small-caps;&quot;&gt;A Tale of Two Test Suites&lt;/p&gt;
&lt;p&gt;Consider two test suites. One executes in 6 seconds, and the other in 1 minute. Pretend they cover the same code equally well. I mean that they have the same power to uncover mistakes in the system. Now imagine yourself writing code and executing the 6-second suite. You make a handful of edits, then you run the tests. What do you do for 6 seconds? You predict the outcome of the test run: they will all pass, or the new test will fail because you&amp;#8217;ve just written it, or the new test might pass because you think you wrote too much code to pass a test 10 minutes ago. In that span of time, you have your result: the tests all pass, so now you refactor. You probably needed about 6 seconds to read up to here.&lt;/p&gt;
&lt;p&gt;Now imagine you run the 1-minute test suite. Once again, you predict the result, during which time 6 seconds pass. If you work alone, then after 8 seconds you&amp;#8217;ve started drumming your fingers on the desk or letting your eyes dart around the room. You notice the long list of tasks on the team task board. You start to feel your stomach rumble, noticing the time: 11:42. Time for lunch soon. You wonder what the cantina has for lunch, so you point your browser at their intranet site. Tilapia sounds good. You wonder whether Lisa will join you for lunch, so you switch to your email client. Before you write her, you notice a notification to pay your credit card bill. You can do that in 30 seconds, so you switch back to your browser to log in to online banking and quickly make a payment. It turns out Lisa has a lunch meeting, and you reconsider your choice of fish. Today, you decide, feels like a burger day. In the time you imagined yourself doing that, assuming you guessed how long it took to actually do what you imagined, over 1 minute passed. The computer has spent valuable computing time waiting for you.&lt;/p&gt;
&lt;p&gt;Pairing doesn&amp;#8217;t seem to solve this problem. If you ran this test suite during a pair-programming session, then you probably spent time chatting. At first, you discussed the recent test. After a while, you discussed the task. That killed about 40 seconds, so you started drifting to other topics: the weekend, the kids, XBox, Battlestar Galactica, baseball, management&amp;#8230; then you turned around to notice the test run finished while you were arguing whether Cliff Lee deserved the Cy Young award. I don&amp;#8217;t mind injecting plenty of relaxed conversation into my work, but when waiting repeatedly for a 1-minute test suite it doesn&amp;#8217;t take long to run out of things to talk about.&lt;/p&gt;
&lt;p&gt;I need to point out the dual cost here. The first, we can easily see and measure: the time we spend waiting for the tests plus the time the computer waits for us, because we find it hard to stare at the test runner for 60 seconds and react to it immediately after it finishes. I don&amp;#8217;t care much about that cost. I care about the visible but highly unquantifiable cost of losing focus.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; works well for me in large part because it helps me focus. When I write a test, I clarify my immediate goal, focus on making it pass, then focus on integrating that work more appropriately into the design. I get to do this in short cycles that demand sustained focus and allow brief recovery&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn4391c719ba10f9c4aaa6d687420c7f3ec9dac4ae&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. This cycle of focus and recovery builds rhythm and this rhythm builds momentum. This helps lead to the commonly-cited and powerful state of flow. A 6-second test run provides a moment to recover from exertion; whereas a 1-minute test run disrupts flow. It acts like an annoying short interruption every few minutes. We can try to measure the cumulative effect of these interruptions, but I guess you can imagine a day, possibly a recent one, when periodic short interruptions made it nearly impossible for you to concentrate. How productive did you feel that day? How much did you achieve? How much pressure did you feel to catch up the next day? How relaxed did you feel that evening at home? Did you enjoy dinner? Did you feel present for your spouse or kids or pets? How well did you sleep? How refreshed did you feel the next morning?&lt;/p&gt;
&lt;p&gt;Among the early &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; literature I distinctly remember reading that practising &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; would help me focus, relax, achieve more and feel better at the end of a task. I remember agonizing over integration tests. Teams call me expressly to learn how to tame big, slow, brittle test suites. They don&amp;#8217;t call me when they feel focused, relaxed and productive. I tell you: &lt;strong&gt;integration tests will slowly kill you&lt;/strong&gt;.&lt;/p&gt;
&lt;p style=&quot;font-weight: bold; font-size: 120%; font-variant: small-caps;&quot;&gt;So What Now?&lt;/p&gt;
&lt;p&gt;But you have integration tests now, and you haven&amp;#8217;t yet learned about the alternatives. How can you cope with your reality? You could regain your focus by running the most important 10% of those tests. That would take 6 seconds and fit into your flow. It also runs a substantial risk of failure. You&amp;#8217;ve experienced this. Remember the last time you changed a line of code in one part of the system and it broke something way over there in another module? How did you feel when that happened? How long did you spend tracking down a mistake in some arcane part of they system that perhaps no one understands? How did you deal with having to branch your code changes to deal with the bigger problem? How many times have you told your wild goose chase story to your fellow programmers? How long did you need to recover before returning to a decent state of flow while working on your original task?&lt;/p&gt;
&lt;p&gt;So it appears you have a choice between frequent annoying disruptions and less frequent but comparatively catastrophic disruptions. A Morton&amp;#8217;s Fork you can blame squarely on integration tests. Stop writing them.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn4391c719ba10f9c4aaa6d687420c7f3ec9dac4ae&quot;&gt;&lt;sup&gt;1&lt;/sup&gt; For more about the focus/recovery cycle, I highly recommend &lt;a href=&quot;http://tinyurl.com/dkwtkn&quot;&gt;The Power of Full Engagement&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;&lt;a href=&quot;/category/named/integration-tests-are-a-scam&quot;&gt;Read more in this series&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/242';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/242&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 08, 2009  19:47
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/integrated-tests-are-a-scam&quot;&gt;integrated tests are a scam&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 08 Apr 2009 19:47:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/242</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Toddlers, novelty, and planning</title>
      <link>http://jbrains.ca/permalink/241</link>
      <description>&lt;div class='entry posting' id='entry-_posting_241'&gt;
&lt;div class='posting' id='content-_posting_241'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I visited a dear friend this week and had the chance to meet her young son for the first time since before he turned one year of age. I believe he turned four years old this year, and I got to watch him ready himself to leave his pre-school program. Since Toronto still has winter, Kieran had to negotiate a coat, snow pants, boots, mittens, and all the while he was greeting and saying goodbye to his friends, running around getting some additional exercise, and just generally living in the moment. I don&amp;#8217;t remember how long it took to leave the building, but it took some time. Melissa turned to me and remarked at how slow toddlers move. I disagree.&lt;/p&gt;
&lt;p&gt;A toddler looks slow, but doesn&amp;#8217;t move slowly at all. On the contrary, they move quickly from idea to idea, input to input, person to person, thread to thread, processing a ton of information. Novelty dominates the toddler&amp;#8217;s life, robbing them of the opportunity to focus, as they dart around to every new piece of input. Their apparent speed, then, comes not from moving slowly, but from trying to do everything at once, responding to novelty and generally having no real plan.&lt;/p&gt;
&lt;p&gt;I simply found that interesting. No connection to software. (Wink)&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/241';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/241&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 08, 2009  18:32
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/planning&quot;&gt;planning&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 08 Apr 2009 18:32:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/241</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>See the Tigers at the Jays tonight (April 6)</title>
      <link>http://jbrains.ca/permalink/240</link>
      <description>&lt;div class='entry posting' id='entry-_posting_240'&gt;
&lt;div class='posting' id='content-_posting_240'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;We have one extra ticket to the Tigers/Jays game tonight: it&amp;#8217;s the Jays home opener for 2009. If you&amp;#8217;d like to go, you can have the ticket free of charge, but I must warn you of my conditions.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;We plan arrive in time for the pre-game ceremonies. That likely means we&amp;#8217;re walking into the park no later than 6:15 PM.&lt;/li&gt;
	&lt;li&gt;We plan to stay until the last out, so if you want to leave early, you&amp;#8217;re leaving alone.&lt;/li&gt;
	&lt;li&gt;You will talk &lt;em&gt;baseball&lt;/em&gt; and be happy that I will talk baseball. A lot. Pat Wilson-Welsh calls me his personal color commentator.&lt;/li&gt;
	&lt;li&gt;You will &lt;em&gt;not&lt;/em&gt; talk software. Three strikes and you&amp;#8217;re out.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;#8217;re still interested, send email to the address at the top of this page. If you know my phone number, text me instead, since I won&amp;#8217;t have internet access throughout the entire day&amp;mdash;it will depend on the various coffee shops and restaurants I go to.&lt;/p&gt;
&lt;p&gt;Okey dokey, rum and cokey, let&amp;#8217;s chase balls!&lt;/p&gt;
&lt;p&gt;(If you know that reference, you&amp;#8217;re in.)&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/240';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/240&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 06, 2009  13:20
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/baseball&quot;&gt;baseball&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 06 Apr 2009 13:20:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/240</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Integrated Tests are a Scam: Part 1</title>
      <link>http://jbrains.ca/permalink/239</link>
      <description>&lt;div class='entry posting' id='entry-_posting_239'&gt;
&lt;div class='posting' id='content-_posting_239'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;&lt;a href=&quot;/category/named/integrated-tests-are-a-scam&quot;&gt;Read more in this series&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;font-size: small; font-style: italic;&quot;&gt;On March 1, 2010 I changed the phrase &amp;#8220;integration tests&amp;#8221; to &amp;#8220;integrated tests&amp;#8221; in this article.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Integrated tests are a scam&amp;mdash;a self-replicating virus that threatens to infect your code base, your project, and your team with endless pain and suffering.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Wait&amp;#8230; &lt;em&gt;what?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I mean it. I hate integrated tests. I &lt;em&gt;hate&lt;/em&gt; them, and with a passion. Of course, I should clarify what I mean by &lt;em&gt;integrated tests&lt;/em&gt;, because, like any term in software, we probably don&amp;#8217;t agree on a meaning for it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I use the term &lt;em&gt;integrated test&lt;/em&gt; to mean any test whose result (pass or fail) depends on the correctness of the implementation of more than one piece of non-trivial behavior.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I, too, would prefer a more rigorous definition, but this one works well for most code bases most of the time. I have a simple point: I generally don&amp;#8217;t want to rely on tests that might fail for a variety of reasons. Those tests create more problems than they solve.&lt;/p&gt;
&lt;p&gt;You write integrated tests because you can&amp;#8217;t write perfect unit tests. You know this problem: all your unit tests pass, but someone finds a defect anyway. Sometimes you can explain this by finding an obvious unit test you simply missed, but sometimes you can&amp;#8217;t. In those cases, you decide you need to write an integrated test to make sure that all the production implementations you use in the broken code path now work correctly together.&lt;/p&gt;
&lt;p&gt;So far, no big deal, but you&amp;#8217;ll meet the monster as soon as you think this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If we can find defects even when our tests pass 100%, and if I can only plug the hole with an integrated tests, then &lt;em&gt;we&amp;#8217;d better write integrated tests everywhere&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Bad idea. Really bad.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://www.trumanlibrary.org/photographs/85-7.jpg&quot; style=&quot;width:400px;&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Why so bad? A little bit of simple arithmetic should help explain.&lt;/p&gt;
&lt;p&gt;You have a medium-sized web application with around 20 pages, maybe 10 of which have forms. Each form has an average of 5 fields and the average field needs 3 tests to verify thoroughly. Your architecture has about 10 layers, including web presentation widgets, web presentation pages, abstract presentation, an &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; bridge to your service &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;, controllers, transaction scripts, abstract data repositories, data repository implementations, &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; statement mapping, &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; execution, and application configuration. A typical request/response cycle creates a stack trace 30 frames deep, some of which you wrote, and some of which you&amp;#8217;ve taken off the shelf from a wide variety of open source and commercial packages. How many tests do you need to test this application &lt;em&gt;thoroughly&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;At least 10,000. Maybe a million. &lt;em&gt;One million&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://tinyurl.com/dx68z4&quot;&gt;&lt;em&gt;Wie ist es m&amp;ouml;glich?!&lt;/em&gt;&lt;/a&gt; Consider 10 layers with 3 potential branch points at each layer. Number of code paths: 3&lt;sup&gt;10&lt;/sup&gt; &amp;gt; 59,000. How about 4 branch points per layer?  4&lt;sup&gt;10&lt;/sup&gt; &amp;gt; 1,000,000. How about 3 branch and 12 layers? 3&lt;sup&gt;12&lt;/sup&gt; &amp;gt; 530,000.&lt;/p&gt;
&lt;p&gt;Even if one of your 12 layers has a single code path, 3&lt;sup&gt;11&lt;/sup&gt; &amp;gt; 177,000.&lt;/p&gt;
&lt;p&gt;Even if your 10-layer application has only an average of 3.5 code paths per layer, 3.5&lt;sup&gt;10&lt;/sup&gt; &amp;gt; 275,000&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn39d53086a1a26cc51604a7f53c065c043370e98b&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;To simplify the arithmetic, suppose you need &lt;em&gt;only&lt;/em&gt; 100,000 integrated tests to cover your application. Integrated tests typically touch the file system or a network connection, meaning that they run on average at a rate of no more than 50 tests per second. Your 100,000-test integrated test suite executes in 2000 seconds or 34 minutes. That means that you execute your entire test suite only when you feel ready to check in. Some teams let their continuous build execute those tests, and hope for the best, wasting valuable time when the build fails and they need to backtrack an hour.&lt;/p&gt;
&lt;p&gt;How long do you need to &lt;em&gt;write&lt;/em&gt; 100,000 tests? If it takes 10 minutes to write each test&amp;mdash;that includes thinking time, time futzing around with the test to make it pass the first time, and time maintaining your test database, test web server, test application server, and so on&amp;mdash;then you need 2,778 six-hour human-days (or pair-days if you program in pairs). That works out to 556 five-day human-weeks (or pair-weeks).&lt;/p&gt;
&lt;p&gt;Even if I overestimate by a factor of five, you still need two full-time integrated test writers for a one-year project &lt;em&gt;and&lt;/em&gt; a steady enough flow of work to keep them busy six hours per day &lt;em&gt;and&lt;/em&gt; you can&amp;#8217;t get any of it wrong, because you have no time to rewrite those tests.&lt;/p&gt;
&lt;p&gt;No. You&amp;#8217;ll have those integrated test writers writing production code by week eight.&lt;/p&gt;
&lt;p&gt;Since you won&amp;#8217;t write all those tests, you&amp;#8217;ll write the tests you can. You&amp;#8217;ll write the happy path tests and a few error cases. You won&amp;#8217;t check all ten fields in a form. You won&amp;#8217;t check what happens on February 29. You&amp;#8217;ll jam in a database change rather than copy and paste the 70 tests you need to check it thoroughly. You&amp;#8217;ll write around 50 tests per week, which translates to 2,500 tests in a one-year project. Not 100,000.&lt;/p&gt;
&lt;p&gt;2.5% of the number you need to test your application thoroughly.&lt;/p&gt;
&lt;p&gt;Even if you wrote the most important 2.5%, recognizing the nearly endless duplication in the full complement of tests, you&amp;#8217;d cover somewhere between 10% and 80% of your code paths, and you&amp;#8217;ll have no idea whether you got closer to 10% or 80% until your customers start pounding the first release.&lt;/p&gt;
&lt;p&gt;Do you feel lucky? Well, do you?&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;So you write your 2,500 integrated tests. Perhaps you even write 5,000 of them. When your customer finds a defect, how will you fix it? Yes: with another handful of integrated tests. The more integrated tests you write, the more of a false sense of security you feel. (Remember, you just increased your code path coverage from 5% to 5.01% with those ten integrated tests.) This false sense of security helps you feel good about releasing more undertested code to your customers, which means they find more defects, which you fix with yet more integrated tests. Over time your code path coverage &lt;em&gt;decreases&lt;/em&gt; because the complexity of your code base grows more quickly than your capacity to write enough integrated tests to cover it.&lt;/p&gt;
&lt;p&gt;&amp;#8230;and you wonder why you spend 70% of your time with support calls?&lt;/p&gt;
&lt;p&gt;Integrated tests are a scam. Unreliable, self-replicating time-wasters. They have to go.&lt;/p&gt;
&lt;hr /&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn39d53086a1a26cc51604a7f53c065c043370e98b&quot;&gt;&lt;sup&gt;1&lt;/sup&gt; True: few code bases distribute their complexity to their layers uniformly. Suppose half your 12 layers have only two branch points&amp;mdash;one normal path and one error path&amp;mdash;while the others have 5 branch points. 2&lt;sup&gt;6&lt;/sup&gt;&amp;middot;5&lt;sup&gt;6&lt;/sup&gt; = 1,000,000 and for 4 branch points 2&lt;sup&gt;6&lt;/sup&gt;&amp;middot;4&lt;sup&gt;6&lt;/sup&gt; &amp;gt; 262,000. You can&amp;#8217;t win this game.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn&quot;&gt;&lt;sup&gt;2&lt;/sup&gt; Aslak Helles&amp;oslash;y points to a way to take luck mostly out of the equation. &lt;a href=&quot;http://www.pairwise.org/&quot;&gt;His technique for choosing high-value tests&lt;/a&gt; will certainly help, but it stops short of testing your code &lt;strong&gt;thoroughly&lt;/strong&gt;. I believe you can achieve truly thorough focused tests with similar cost to writing and maintaining integrated tests even using the pairwise test selection technique. (Thanks, Aslak, for your comment on April 12, 2009.)&lt;/p&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;&lt;a href=&quot;/category/named/integrated-tests-are-a-scam&quot;&gt;Read more in this series&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/239';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/239&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 05, 2009  08:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/integrated-tests-are-a-scam&quot;&gt;integrated tests are a scam&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 05 Apr 2009 08:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/239</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Why I try to communicate in E-Prime</title>
      <link>http://jbrains.ca/permalink/238</link>
      <description>&lt;div class='entry posting' id='entry-_posting_238'&gt;
&lt;div class='posting' id='content-_posting_238'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I started trying to communicate exclusively in &lt;a href=&quot;http://en.wikipedia.org/wiki/E-prime&quot;&gt;E-Prime&lt;/a&gt; less than a year ago. I felt motivated to do this primarily by this claim:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The translation [into E-Prime of the sentence &amp;#8220;the movie was good&amp;#8221;, which could become &amp;#8220;I liked the movie&amp;#8221;] communicates the speaker&amp;#8217;s subjective experience of the movie rather than the speaker&amp;#8217;s judgment of the movie. In this example, using E-Prime makes it harder for the writer or reader to confuse a statement of opinion with a statement of fact.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This claim resonated with me for at least two reasons: I tend to judge quickly, and sometimes harshly, so I wanted to reduce the amount of judging I do; and I pride myself on distinguishing opinion from fact, so I&amp;#8217;d like any tool that helps me do that more effectively.&lt;/p&gt;
&lt;p&gt;Rather than reproduce a general argument about the benefit of E-Prime, I&amp;#8217;d rather share an incident that occurred recently to illustrate how E-Prime could improve communication. Granted, each of us gets to decide what constitutes an improvement.&lt;/p&gt;
&lt;p&gt;I had just delivered a two-hour presentation to managers on the subject of test-driven development. I spent the first hour providing the context for test-driven development, reviewing how to apply concepts from Lean manufacturing to software, but focusing on design: concepts like &lt;span class=&quot;caps&quot;&gt;YAGNI&lt;/span&gt;, evolutionary design, writing tests first, and refactoring. I spent the second hour taking questions from the audience in batches of five and answering them quickly &amp;#8212; about ten minutes per batch. I felt good about the session; however, one person decided to give me some feedback just before we closed.&lt;/p&gt;
&lt;p&gt;He did an excellent job of introducing his feedback, almost as though he had recently learned some popular feedback-giving model. He said, almost verbatim:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have a comment for you. It&amp;#8217;s more of a Simon Cowell comment.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I told him that I felt ready to receive his comment.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The first hour was useless evangelism. The second hour was much more valuable. I wish you had run the first hour like the second hour.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If I had felt particularly insecure at that moment, I&amp;#8217;d have likely reacted strongly and negatively. Fortunately, I felt great, so I interpreted his comment more generously. I appreciated his directness, and although I thought he used unnecessarily judgmental language, I didn&amp;#8217;t mind that he did so in front of the rest of the group. That gave me the opportunity to ask this question.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Why didn&amp;#8217;t you say that after ten minutes?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He realized I had made a Lean-related joke, so he smiled and shrugged, before answering that he held his tongue out of respect. I understood. I followed up by telling him that I would have found it &lt;strong&gt;more&lt;/strong&gt; respectful if he had saved me from wasting 50 minutes of everyone&amp;#8217;s time.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;It turns out that few people in the audience agreed with him. At least one person emphasized on his evaluation form how valuable he found the first hour. To borrow from the writers of Frasier, that&amp;#8217;s pretty much what I figured.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If we&amp;#8217;d had more time, I would have taken that moment to launch into a discussion of the &lt;a href=&quot;http://tinyurl.com/3amjmh&quot;&gt;Satir Interaction Model&lt;/a&gt;, given this perfect example of an action (not interrupting me to claim I was wasting people&amp;#8217;s time) with two diametrically opposing interpretations: paying respect by not interrupting; showing lack of respect by letting me crash and burn on stage. You can probably reduce any rocky communication to an instance of a severe difference in interpretation.&lt;/p&gt;
&lt;p&gt;What if this person had communicated using E-Prime? How might this have played out? I offer this potential translation of my commenter&amp;#8217;s comments into E-Prime.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have a comment for you in the style of Simon Cowell. I found the first hour useless, as though you wanted to proselytize me. I found the second hour much more valuable. I wish you had run the first hour more like the second hour.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As I wrote this, I hesitated on translating &amp;#8220;evangelism&amp;#8221;. I settled on the periphrasis &amp;#8220;you proselytized me&amp;#8221;, which I think captures the essence of &amp;#8220;evangelism&amp;#8221; well. I know I could have chosen different words there. I recognize that the words I chose reflect my lingering subconscious feelings about the incident. By writing his comment this way, I better surface my interpretation of it, which I find both clearer and quite instructive. I could have translated it this way.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have a comment for you in the style of Simon Cowell. I found the first hour useless, as though you simply wanted to evangelize about &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;. &amp;#8230;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I react to this slightly less strongly than to the first version, but that difference doesn&amp;#8217;t interest me much. I more care about which the commenter would have chosen: did he choose the word  &amp;#8220;evangelize&amp;#8221; because he wanted to emphasize how I related to him, or because he wanted to emphasize my intention? I believe that knowing that would have helped save me from a harsh reaction had I received his comment from a less centered place than I happened to find myself at the time.&lt;/p&gt;
&lt;p&gt;Communicating with E-Prime could have helped avoid a gross difference in interpretation between the commenter and I, and perhaps could do so more regularly. I count this as one of the many reasons I choose to communicate as much as I can in E-Prime.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/238';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/238&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 03, 2009  13:59
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coaching&quot;&gt;coaching&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/communicating-effectively&quot;&gt;communicating effectively&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 03 Apr 2009 13:59:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/238</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>TDD: From the Beginning</title>
      <link>http://jbrains.ca/permalink/236</link>
      <description>&lt;div class='entry posting' id='entry-_posting_236'&gt;
&lt;div class='posting' id='content-_posting_236'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p style=&quot;font-size: small&quot;&gt;This course runs well both as a public course and a private in-house training session.&lt;/p&gt;
&lt;p&gt;Join J. B. Rainsberger and learn whether test-driven development will work for you. In this course, you will learn the secrets of modular design from one of test-driven development&amp;#8217;s master practitioners. Bring your laptop and be prepared to change the way you write software.&lt;/p&gt;
&lt;h2&gt;Audience&lt;/h2&gt;
&lt;p&gt;You have had professional experience on at least one software project in Java, C#, Python or Ruby. You would like to know how to design software incrementally with test-driven development.&lt;/p&gt;
&lt;h2&gt;You will learn&amp;#8230;&lt;/h2&gt;
&lt;ul&gt;
	&lt;li&gt;how test-driven development can help you deliver software your users will love&lt;/li&gt;
	&lt;li&gt;how test-driven development can help you earn revenue sooner on your software projects&lt;/li&gt;
	&lt;li&gt;how to perform the steps of test-driven development&lt;/li&gt;
	&lt;li&gt;the secrets of truly modular software design&lt;/li&gt;
	&lt;li&gt;how to practise test-driven development and integrate it into your daily practice&lt;/li&gt;
	&lt;li&gt;how to design effectively with interfaces&lt;/li&gt;
	&lt;li&gt;how to test-drive a web user interface without having to deploy your application&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Agenda&lt;/h2&gt;
&lt;h3&gt;Day 1: &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; Bootcamp&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;An introduction to test-driven development and the theory of constraints&lt;/li&gt;
	&lt;li&gt;Realizing the promise of modular design with test-driven development&lt;/li&gt;
	&lt;li&gt;A demonstration of the technique of test-driven development&lt;/li&gt;
	&lt;li&gt;Exercise: test-drive a single-class design&lt;/li&gt;
	&lt;li&gt;Making test-driven development a daily habit&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Day 2: &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; and Evolutionary Architecture&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;A demonstration of evolving an architecture with test-driven development&lt;/li&gt;
	&lt;li&gt;Exercise: test-drive a multiple-class design&lt;/li&gt;
	&lt;li&gt;Zero integration defects without integration tests&lt;/li&gt;
	&lt;li&gt;A demonstration of evolving an architecture through interfaces&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Day 3: &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; and Modular Enterprise Design&lt;/h3&gt;
&lt;ul&gt;
	&lt;li&gt;Exercise: test-drive a multiple-class design with interfaces and test doubles&lt;/li&gt;
	&lt;li&gt;A demonstration of test-driving a dynamic web page without running the web server&lt;/li&gt;
	&lt;li&gt;Remaining questions and answers&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Recommended reading&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.librarything.com/tag/tdd_from_the_beginning&quot;&gt;http://www.librarything.com/tag/tdd_from_the_beginning&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;What attendees have said about this course&lt;/h2&gt;
&lt;p&gt;&lt;iframe name=&quot;tp15404&quot; id=&quot;tp15404&quot; width=&quot;500&quot; height=&quot;200&quot; frameborder=&quot;0&quot; src=&quot;http://tweetpaste.thingamaweb.com/embed/15404/&quot; style=&quot;overflow: hidden; display: block; width: 500px; height: 200px;&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://tweetpaste.thingamaweb.com/embed/15404/&quot; target=&quot;_blank&quot;&gt;View davidhalldor&amp;rsquo;s tweet&lt;/a&gt;&lt;/p&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;&lt;iframe name=&quot;tp15405&quot; id=&quot;tp15405&quot; width=&quot;500&quot; height=&quot;200&quot; frameborder=&quot;0&quot; src=&quot;http://tweetpaste.thingamaweb.com/embed/15405/&quot; style=&quot;overflow: hidden; display: block; width: 500px; height: 200px;&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://tweetpaste.thingamaweb.com/embed/15405/&quot; target=&quot;_blank&quot;&gt;View a13xnet&amp;rsquo;s tweet&lt;/a&gt;&lt;/p&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;Inquire about booking this course by sending email to the address at the top of this page.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/236';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/236&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 03, 2009  11:45
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/training&quot;&gt;training&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/TDD-From-the-Beginning&quot;&gt;TDD From the Beginning&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 03 Apr 2009 11:45:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/236</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Some comments on TDD: From the Beginning in Reykjav&#237;k, Iceland</title>
      <link>http://jbrains.ca/permalink/237</link>
      <description>&lt;div class='entry posting' id='entry-_posting_237'&gt;
&lt;div class='posting' id='content-_posting_237'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I recently presented my course &lt;a href=&quot;http://jbrains.ca/permalink/236&quot;&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;: From the Beginning&lt;/strong&gt;&lt;/a&gt; in Reykjav&#237;k, Iceland in associated with &lt;a href=&quot;http://www.sprettur.is&quot;&gt;Sprettur&lt;/a&gt;. I had a great time working with local programmers, testers. and managers, and I had my first opportunity to visit Reykjav&#237;k, which I&amp;#8217;ve wanted to do for several years.&lt;/p&gt;
&lt;p&gt;I want to thank &lt;a href=&quot;http://www.sprettur.is&quot;&gt;Sprettur&lt;/a&gt; publicly for all they&amp;#8217;ve done for me to prepare for this course. They did what any great host does: let me prepare to teach and take care of the rest. I&amp;#8217;ve only had one difficulty in this trip: deciding where to eat each day.&lt;/p&gt;
&lt;p&gt;As always with these courses, we discussed more than just the mechanics of &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;. We also spent time discussing:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;debugging communication with the Satir Interaction Model (see &lt;a href=&quot;http://tinyurl.com/3amjmh&quot;&gt;Don&amp;#8217;t Let Miscommunication Spiral Out Of Control&lt;/a&gt; for more)&lt;/li&gt;
	&lt;li&gt;how your personal financial situation affects how you work (see &lt;a href=&quot;http://www.weliveherenow.net&quot;&gt;We Live Here Now&lt;/a&gt; to read about how we retired on April 1, 2008)&lt;/li&gt;
	&lt;li&gt;how &lt;a href=&quot;http://tinyurl.com/ccvhpx&quot;&gt;The Goal&lt;/a&gt; relates to test-driven development and evolutionary design&lt;/li&gt;
	&lt;li&gt;how test-driven development teaches the principles of modular design, and good object-oriented design&lt;/li&gt;
	&lt;li&gt;how test-driven development brings a sense of completion to your work and helps you relax more&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also had the chance to see the birth of a Software Craftsmaship Group in Reykjav&#237;k. Gulli and I announced the first non-North American &lt;a href=&quot;http://coderetreat.ning.com&quot;&gt;Code Retreat&lt;/a&gt;, tentatively scheduled to happen before May 31. This will launch a new group in Reykjav&#237;k concerned with issues of software craftsmanship. Thanks to Patrick Wilson-Welsh, Corey Haines, Nayan Hajratwala, LeanDog, and all the people who helped make the Code Retreats in Ann Arbor MI and Cleveland OH such a success. I look forward to Code Retreats in Montr&#233;al, Halifax, and Reyjav&#237;k, if my budget allows.&lt;/p&gt;
&lt;p&gt;In all, a great week, and it hasn&amp;#8217;t ended yet!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/237';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/237&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 03, 2009  11:38
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 03 Apr 2009 11:38:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/237</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Appearing Thursday night in Boston</title>
      <link>http://jbrains.ca/permalink/235</link>
      <description>&lt;div class='entry posting' id='entry-_posting_235'&gt;
&lt;div class='posting' id='content-_posting_235'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Just a quick announcement: I will appear at &lt;a href=&quot;http://tinyurl.com/cuo5on&quot;&gt;Agile Bazaar&lt;/a&gt; in Boston with Niraj Khanna with a talk entitled &lt;a href=&quot;http://tinyurl.com/cuo5on&quot;&gt;Your Agile Sales Approach &lt;del&gt;Sucks&lt;/del&gt; Stinks!&lt;/a&gt; or, &lt;a href=&quot;http://tinyurl.com/cuo5on&quot;&gt;Effective Agile Sales:&lt;br /&gt;
A Good Suit and a Great Pitch Just Doesn&amp;#8217;t Cut it Anymore&lt;/a&gt;. Our talk centers on applying the &lt;a href=&quot;http://tinyurl.com/cx4b2p&quot;&gt;strategic selling model of Miller&lt;/a&gt; to selling agile concepts. It doesn&amp;#8217;t matter whether you&amp;#8217;re an employee selling the idea of agile to your co-workers and manager or an independent service provider selling the idea of agile to prospective customers: you need to stop treating agile like a simple sale and instead understand a model that helps guide you through your sale.&lt;/p&gt;
&lt;p&gt;Please join us!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/235';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/235&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
March 25, 2009  16:47
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/consulting&quot;&gt;consulting&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 25 Mar 2009 16:47:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/235</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Need your feedback on the title &quot;Your Agile Sales Approach Sucks&quot;</title>
      <link>http://jbrains.ca/permalink/234</link>
      <description>&lt;div class='entry posting' id='entry-_posting_234'&gt;
&lt;div class='posting' id='content-_posting_234'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;It&amp;#8217;s conference proposal season, and I have recently had a proposal rejected from XP 2009 entitled &amp;#8220;Your Agile Sales Approach Sucks&amp;#8221;. The tutorial focuses on the difference between a &lt;em&gt;simple&lt;/em&gt; and &lt;em&gt;complex&lt;/em&gt; sale, with the thesis that one must sell any kind of agile transition or practice adoption as a complex sale, whereas most people continue to try to sell it as a simple sale. One of the reviewers labeled the title as &amp;#8220;uselessly provocative&amp;#8221; and, while he didn&amp;#8217;t reject on that basis, might have rated the proposal down due to the title. Another organization asked us to change the title before we presented it at their user group.&lt;/p&gt;
&lt;p&gt;Now I chose the title as an homage to the book &lt;em&gt;Your Marketing Sucks&lt;/em&gt;, whose author calls his approach &amp;#8220;extreme marketing&amp;#8221;. I thought our society generally accepted &amp;#8220;sucks&amp;#8221; in a way they didn&amp;#8217;t 15-20 years ago. Perhaps I have that wrong. I&amp;#8217;d like your help to find out.&lt;/p&gt;
&lt;p&gt;Please leave a comment to help me understand how people react to a tutorial or user group session entitled &amp;#8220;Your Agile Sales Approach Sucks&amp;#8221;, focusing on the word &amp;#8220;sucks&amp;#8221;.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/234';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/234&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
March 13, 2009  11:06
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/consulting&quot;&gt;consulting&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 13 Mar 2009 11:06:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/234</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Please comment on draft logos the Gordon Pask Award</title>
      <link>http://jbrains.ca/permalink/231</link>
      <description>&lt;div class='entry posting' id='entry-_posting_231'&gt;
&lt;div class='posting' id='content-_posting_231'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Sebastian Hermida has drafted some logos for the Gordon Pask Award. Please vote below!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/GordonPaskAward-logos-Hermida.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;div class=&quot;js-kit-poll&quot; path=&quot;/paskawardlogo-poll&quot; permalink=&quot;http://www.jbrains.ca/permalink/231&quot;&gt;&lt;/div&gt;
&lt;script src=&quot;http://js-kit.com/polls.js&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/231';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/231&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
March 03, 2009  03:00
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 03 Mar 2009 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/231</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The Gordon Pask Award program needs volunteers</title>
      <link>http://jbrains.ca/permalink/230</link>
      <description>&lt;div class='entry posting' id='entry-_posting_230'&gt;
&lt;div class='posting' id='content-_posting_230'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Laurent Bossavit and J. B. Rainsberger invite you to participate in the Gordon Pask Award program. We would like to improve the program in a number of ways, including collecting nominations throughout the year, researching candidates&amp;#8217; contributions to the agile community and giving everyone a greater chance to get to know past winners. We need your help to do this well.&lt;/p&gt;
&lt;p&gt;For the moment, we seek volunteers to help with work such as:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;advertise and promote our initiatives on weblogs, in discussion groups, in user groups, at conferences, and wherever you can garner attention&lt;/li&gt;
	&lt;li&gt;design a physical Gordon Pask Award prize&lt;/li&gt;
	&lt;li&gt;interview Brian Marick about the story behind instituting the Gordon Pask Award in 2005&lt;/li&gt;
	&lt;li&gt;interview past award winners and write articles about them&lt;/li&gt;
	&lt;li&gt;connect the program with public relations or press outlets to help promote the award and raise its profile in the larger software community&lt;/li&gt;
	&lt;li&gt;suggest changes to the nomination process&lt;/li&gt;
	&lt;li&gt;suggest something special for the fifth year of the award (2009)&lt;/li&gt;
	&lt;li&gt;design a logo and color scheme for the Gordon Pask Award&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you would like to help, please send email to gordonpaskaward@agilealliance.org and tell us how you&amp;#8217;d like to help. You might tell us you&amp;#8217;d simply like to help in whatever capacity we need, or that you have a specific task or project in mind to which to contribute. We welcome all comers.&lt;/p&gt;
&lt;p&gt;Thank you for your time, attention and interest.&lt;/p&gt;
&lt;p&gt;Laurent Bossavit and J. B. Rainsberger,&lt;br /&gt;
Directors of the Gordon Pask Award Program&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/230';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/230&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
February 28, 2009  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/gordon-pask-award-2009&quot;&gt;gordon pask award 2009&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 28 Feb 2009 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/230</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Please comment on sessions for Agile 2009!</title>
      <link>http://jbrains.ca/permalink/229</link>
      <description>&lt;div class='entry posting' id='entry-_posting_229'&gt;
&lt;div class='posting' id='content-_posting_229'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Dear readers, I need your help.&lt;/p&gt;
&lt;p&gt;I want to comment on at least 200 of the nearly 1000 sessions proposed for Agile 2009, but I have only managed to comment on 40 so far. I will add comments to about 40, but I need your help to get to 200.&lt;/p&gt;
&lt;p&gt;Please go to &lt;a href=&quot;http://agile2009.agilealliance.org&quot;&gt;http://agile2009.agilealliance.org&lt;/a&gt;, register or sign in, pick 10 proposals, read the reviews and comments, then add your own.&lt;/p&gt;
&lt;p&gt;Thanks for your help.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/229';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/229&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
February 24, 2009  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2009&quot;&gt;agile 2009&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 24 Feb 2009 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/229</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Solve Just Enough Of Your Worst Problem</title>
      <link>http://jbrains.ca/permalink/228</link>
      <description>&lt;div class='entry posting' id='entry-_posting_228'&gt;
&lt;div class='posting' id='content-_posting_228'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p style=&quot;font-size: small&quot;&gt;This session can run as a public conference tutorial or as a private in-house training session.&lt;/p&gt;
&lt;p&gt;Many change campaigns fail because we don&amp;#8217;t see the results we expected from the change. We can attribute this failure to a variety of issues: attempting to solve the wrong problem, attempting to solve the right problem with the wrong skills, or failing to measure progress towards solving the problem. Most organizations overlook a key possibility: wasting time solving too much of the right problem.&lt;/p&gt;
&lt;p&gt;Voltaire once said that the perfect is the enemy of the good, and that principle applies here. While we find it comforting to completely solve a well-understood problem, we sometimes spend weeks or months continuing to solve a problem even though another has risen to the level of the most immediate problem. While you tweak your build to perfection, you might forget that it still takes two weeks to deliver upgrades to your customer, or that your customer needs a month to install the upgrade. Stop wasting time solving a problem when you&amp;#8217;ve already solved it enough.&lt;/p&gt;
&lt;p&gt;In this session, J. B. Rainsberger introduces concepts from the Theory of Constraints and Lean Software Development to help attendees uncover their biggest problems, and decide how much of that problem to solve before another biggest problem takes its place. From there, we work together to formulate a plan to solve just enough of your worst problem.&lt;/p&gt;
&lt;p&gt;This session includes &lt;a href=&quot;http://www.jbrains.ca/permalink/227&quot;&gt;An introduction to Agile Through the Theory of Constraints&lt;/a&gt; in a full day tutorial aimed at people who want to explore their software delivery system for problems and solutions.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Understand how to uncover your biggest problem by identifying productive and wasteful activities.&lt;/li&gt;
	&lt;li&gt;Formulate a plan to solve just enough of your biggest problem.&lt;/li&gt;
	&lt;li&gt;Walk away with a deep understanding of the various activities that contribute to the time it takes for you to deliver features once they&amp;#8217;ve been requested.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Please inquire about booking this session by emailing the address at the top of this page.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/228';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/228&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
February 19, 2009  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/training&quot;&gt;training&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/consulting&quot;&gt;consulting&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 19 Feb 2009 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/228</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Some changes at jbrains.ca</title>
      <link>http://jbrains.ca/permalink/225</link>
      <description>&lt;div class='entry posting' id='entry-_posting_225'&gt;
&lt;div class='posting' id='content-_posting_225'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have decided to change jbrains.ca a little. I hope you like the improvements.&lt;/p&gt;
&lt;p&gt;You&amp;#8217;ll notice the search box, a Twitter feed, and a new comments and rating system courtesy of &lt;a href=&quot;http://www.js-kit.com&quot;&gt;JS Kit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thank you to all my readers, and I hope these improvements bring more readers. In the meantime, please feel free to rate old entries, and perhaps even Digg or Reddit a few of them!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/225';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/225&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
February 19, 2009  03:00
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 19 Feb 2009 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/225</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>An introduction to Agile Through the Theory of Constraints</title>
      <link>http://jbrains.ca/permalink/227</link>
      <description>&lt;div class='entry posting' id='entry-_posting_227'&gt;
&lt;div class='posting' id='content-_posting_227'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p style=&quot;font-size: small;&quot;&gt;This session can run as a public conference talk or as a private in-house training session.&lt;/p&gt;
&lt;p&gt;Agile has all these weird, expensive-looking practices: pair programming, test-driven development, regular planning meetings, moving the programmers and business people closer together, focusing people on a single project, multi-disciplinary teams. We can&#8217;t afford to go agile!&lt;/p&gt;
&lt;p&gt;In this session, J. B. Rainsberger introduces agile practices by relating them to core business matters: compounding early earned value and reducing unnecessary costs. Learn why practice and learning are really profit centers. Maybe you can&#8217;t afford not to go agile!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This is a 90-minute talk aimed at people with business knowledge who want to understand how the practices of XP help benefit the bottom line.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You can find &lt;a href=&quot;http://www.youtube.com/watch?v=viezJLrFRQE&quot;&gt;an excerpt from this presentation at XP Day Manhattan 2007&lt;/a&gt; at YouTube.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Understand how agile practices relate directly to core business concerns.&lt;/li&gt;
	&lt;li&gt;Feel more comfortable with agile practices as an investment, rather than a sunk cost.&lt;/li&gt;
	&lt;li&gt;Understand how to present agile practices in a compelling way to business people.&lt;/li&gt;
	&lt;li&gt;See a more concrete, relevant justification for agile practices than &amp;#8220;you&#8217;ll like it, and people will feel better&amp;#8221;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Combine this with &lt;a href=&quot;http://www.jbrains.ca/permalink/228&quot;&gt;Solve Just Enough Of Your Worst Problem&lt;/a&gt; for a complete one-day course.&lt;/p&gt;
&lt;p&gt;Inquire about booking this session by emailing the address at the top of this page.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/227';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/227&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
February 19, 2009  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/training&quot;&gt;training&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/consulting&quot;&gt;consulting&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 19 Feb 2009 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/227</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Sponsor me to speak; receive free consulting</title>
      <link>http://jbrains.ca/permalink/226</link>
      <description>&lt;div class='entry posting' id='entry-_posting_226'&gt;
&lt;div class='posting' id='content-_posting_226'&gt;
&lt;div style='text-align: justify'&gt;
&lt;div style=&quot;float: right;&quot;&gt;
&lt;form action=&quot;https://www.paypal.com/cgi-bin/webscr&quot; method=&quot;post&quot; target=&quot;_blank&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;cmd&quot; value=&quot;_s-xclick&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;hosted_button_id&quot; value=&quot;3342746&quot;&gt;
&lt;input type=&quot;image&quot; src=&quot;https://www.paypal.com/en_US/i/btn/btn_buynowCC_LG.gif&quot; border=&quot;0&quot; name=&quot;submit&quot; alt=&quot;&quot;&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://www.paypal.com/en_US/i/scr/pixel.gif&quot; width=&quot;1&quot; height=&quot;1&quot;&gt;&lt;/p&gt;
&lt;/form&gt;
&lt;/div&gt;
&lt;p&gt;Would you like to support a local software user group or community event? I have begun a speaker sponsorship program with a twist: free consulting.&lt;/p&gt;
&lt;p&gt;When you support a local software user group by sponsoring me to speak at their meetings or conferences, you receive a sponsorship package including a half day of remote consulting, coaching, pairing or training. All this for only &lt;span class=&quot;caps&quot;&gt;CAD&lt;/span&gt; 495. (Canadian sponsors pay &lt;span class=&quot;caps&quot;&gt;GST&lt;/span&gt;.)&lt;/p&gt;
&lt;p&gt;Most local software user groups have to raise money to invite well-known out-of-town speakers. They have a few avenues: local fundraisers, local benefactors, and the Agile Alliance speaker reimbursement program. Most such organizations, however, don&amp;#8217;t have fundraising experience, and the Agile Alliance&amp;#8217;s program still has a relatively limited budget. The people who started these groups didn&amp;#8217;t plan to become expert fundraisers, so let them benefit from your sponsorship to bring me to speak to them.&lt;/p&gt;
&lt;p&gt;The Speaker Sponsorship Package includes&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;two 90-minute remote consulting sessions on the topics of your choosing&lt;/li&gt;
	&lt;li&gt;acknowledgement on the user group or event web site of your sponsorship&lt;/li&gt;
	&lt;li&gt;acknowledgement on jbrains.ca of your sponsorship&lt;/li&gt;
	&lt;li&gt;acknowledgement during my talk of your sponsorship&lt;/li&gt;
	&lt;li&gt;acknowledgement during all my 2009 conference talks of your sponsorship&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Acknowledgement includes your (or your company&amp;#8217;s) name, logo and a link or pointer to your website.&lt;/p&gt;
&lt;p&gt;I will conduct your consulting sessions with Skype (http://www.skype.com) and its screen sharing feature. You need a headset, a webcam and a high-speed internet connection. You can use your sessions to do the following:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;work with me as a pair partner: programming, writing stories, designing business tests, personal planning, and more&lt;/li&gt;
	&lt;li&gt;map your value stream, identify bottlenecks, and devise plans to deal with them&lt;/li&gt;
	&lt;li&gt;run a code review or planning meeting&lt;/li&gt;
	&lt;li&gt;ask for my advice on issues of design, testing, planning, teamwork, communication, installing practices&lt;/li&gt;
	&lt;li&gt;suggest your own session, and as long as I believe I can help you, I will do it&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;float: right;&quot;&gt;
&lt;form action=&quot;https://www.paypal.com/cgi-bin/webscr&quot; method=&quot;post&quot; target=&quot;_blank&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;cmd&quot; value=&quot;_s-xclick&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;hosted_button_id&quot; value=&quot;3342746&quot;&gt;
&lt;input type=&quot;image&quot; src=&quot;https://www.paypal.com/en_US/i/btn/btn_buynowCC_LG.gif&quot; border=&quot;0&quot; name=&quot;submit&quot; alt=&quot;&quot;&gt;
&lt;p&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;https://www.paypal.com/en_US/i/scr/pixel.gif&quot; width=&quot;1&quot; height=&quot;1&quot;&gt;&lt;/p&gt;
&lt;/form&gt;
&lt;/div&gt;
&lt;p&gt;Upcoming sponsorship opportunities:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Sponsor the &lt;a href=&quot;http://agilebazaar.org/&quot;&gt;Agile Bazaar&lt;/a&gt;, the top agile user group in New England, where Niraj Khanna and I will explain on March 26, 2009 why Your Agile Sales Approach Sucks!&lt;/li&gt;
	&lt;li&gt;Sponsor my appearance at &lt;a href=&quot;http://coderetreat.ning.com&quot;&gt;Code Retreat 2&lt;/a&gt;, where I will help Patrick Wilson-Welsh and his crew give programmers a place to practice their technique.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;font-size: small&quot;&gt;Unfortunately, you cannot use your sessions to do classroom training. If you would like to hire me to train your team or organization, please &lt;a href=&quot;http://www.jbrains.ca/training&quot;&gt;read about my training services&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/226';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/226&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
February 19, 2009  01:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coaching&quot;&gt;coaching&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/consulting&quot;&gt;consulting&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 19 Feb 2009 01:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/226</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>On 100% unit test coverage and other nonsensical ideas</title>
      <link>http://jbrains.ca/permalink/223</link>
      <description>&lt;div class='entry posting' id='entry-_posting_223'&gt;
&lt;div class='posting' id='content-_posting_223'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I will simply riff for a while on things I read Joel Spolsky say (I read a transcript of a podcast from &lt;a href=&quot;http://tinyurl.com/at2pt5&quot;&gt;here&lt;/a&gt;) about test-driven development.&lt;/p&gt;
&lt;p&gt;Nobody should strive for 100% test coverage, let alone microtest coverage, for obvious reasons. Among those obvious reasons, I find two glaring ones: we generally don&amp;#8217;t agree on what the term means; and trying to do it leads to writing tests for their own sake, rather than as a means to write sufficiently correct software. I have learned two important things through practice and observation: no single optimal number for test coverage can exist for all projects; and if you insist on an optimal number for test coverage, choose 85%, meaning that the average team ought to test all but the most straightforward 15% of the average system. When I practise &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;, I end up with around 85% test coverage because of the way I apply the principle of Too Simple to Break. Among the 15% untested you will find dead simple get/set methods and dead simple delegation. When Joel concludes something based on the hypothesis that otherwise thoughtful people have 100% test coverage as a goal, he runs well off the track. I don&amp;#8217;t doubt that some people seek 100% test coverage, because those people help keep me in business. Stop it, or I&amp;#8217;ll bury you alive in a box.&lt;/p&gt;
&lt;p&gt;Some innocuous-looking changes cause an unusual number of tests to fail. While I don&amp;#8217;t like this situation, I draw a different conclusion from it than Joel does. I conclude that this points to a design flaw worth exploring. I don&amp;#8217;t have a &amp;#8220;proof&amp;#8221; for this, but I have observed good results when I have treated my own designs this way. In this vain, I follow the maxim I learned from the Pragmatic Programmers: abstractions in code and details in data. Joel uses this example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Because you&amp;#8217;ve changed the design of something&amp;#8230; you&amp;#8217;ve moved a menu, and now everything that relied on that menu being there&amp;#8230; the menu is now elsewhere. And so all those tests now break. And you have to be able to go in and recreate those tests to reflect the new reality of the code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I don&amp;#8217;t understand why we would have microtests that check that a specific menu shows up in a specific location. Remember: abstractions in code and details in data. Also remember: three strikes and you refactor. Putting these two principles together, once I have a few menu items, I&amp;#8217;ve extracted the details about individual menus to some &lt;code&gt;List&lt;/code&gt; of &lt;code&gt;Menu&lt;/code&gt; objects and an engine that operates on them. Also, I have probably separated that &lt;code&gt;List&lt;/code&gt; from the code that presents the menus. If I don&amp;#8217;t like how my code presents the menus, I can fix that with test data that has no bearing on the actual menus. If I don&amp;#8217;t like the order of my menus, I can change the &lt;code&gt;Menu&lt;/code&gt; objects in the &lt;code&gt;List&lt;/code&gt;&amp;mdash;just data&amp;mdash;and do a quick manual inspection without having to change the tests for my menu-presenting engine. Moving a specific menu somewhere should not require any code changes; and if it does, then you have a design flaw: you have details in code. Stop it, or I&amp;#8217;ll bury you alive in a box.&lt;/p&gt;
&lt;p&gt;In general, if a single change causes an unusually high number of tests to fail, then your tests have a duplication problem. Stop letting duplication flourish in your tests, or I&amp;#8217;ll bury you alive in a box.&lt;/p&gt;
&lt;p&gt;Thanks for Bob Newhart for the line &amp;#8220;Stop it, or I&amp;#8217;ll bury you alive in a box&amp;#8221;, which I heard for the first time on Mad TV.&lt;/p&gt;
&lt;p&gt;(Edit 2009-02-23: Corrected Saturday Night Live to Mad TV.)&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/223';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/223&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
February 16, 2009  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 16 Feb 2009 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/223</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Looking for work in Europe in March</title>
      <link>http://jbrains.ca/permalink/222</link>
      <description>&lt;div class='entry posting' id='entry-_posting_222'&gt;
&lt;div class='posting' id='content-_posting_222'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I am teaching a public &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; course in Istanbul February 26-28, so I&amp;#8217;d like to continue the trip elsewhere in Europe. I&amp;#8217;d like to offer my services at a reduced rate to facilitate bunching together work in Europe. If you would like to hire me for some consulting, mentoring, coaching or training, or can introduce me to someone who should be interested, I can offer an expenses-included price that competes &lt;em&gt;very&lt;/em&gt; well with other top-notch consultants. For the right client, with the right personal reference, and in the right place (Cote D&amp;#8217;Azur? Coastal Spain? Austria?) I can lower the price even further.&lt;/p&gt;
&lt;p&gt;Please inquire by email, and be patient, as I&amp;#8217;m on vacation until February 9 and will be entirely out of contact until then. I realize this makes it short notice, but that&amp;#8217;s part of what reduces the price!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/222';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/222&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 30, 2009  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 30 Jan 2009 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/222</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Code Retreat 1 in Ann Arbor, Michigan</title>
      <link>http://jbrains.ca/permalink/221</link>
      <description>&lt;div class='entry posting' id='entry-_posting_221'&gt;
&lt;div class='posting' id='content-_posting_221'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I took some time off to attend the first &lt;a href=&quot;http://coderetreat.ning.com&quot;&gt;Code Retreat&lt;/a&gt; in Ann Arbor on January 24, 2009, the purpose of which was to practice and discussing coding techniques. I would like to thank the organizers for making me feel welcome and driving me around.&lt;/p&gt;
&lt;p&gt;I found a related video. &lt;a href=&quot;http://tinyurl.com/afwqmr&quot;&gt;Enjoy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I was glad to see familiar faces: Bill Wake, Pat Welsh, Ron Jeffries, Chet Hendrickson and Corey Haines. I hope to come back some day.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/221';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/221&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 30, 2009  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/emotional-health&quot;&gt;emotional health&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 30 Jan 2009 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/221</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>We don't need to define good design</title>
      <link>http://jbrains.ca/permalink/220</link>
      <description>&lt;div class='entry posting' id='entry-_posting_220'&gt;
&lt;div class='posting' id='content-_posting_220'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Over the years, I have witnessed a number of attempts to develop a complete, constructive definition of good design. I have witnessed most of this in the Extreme Programming Yahoo! group, in threads that crop up every year or so. A pattern repeats itself: someone asks about how to tell how good a design is, a bunch of people offer suggestions, they start to argue the fine points, someone points out the impossibility of developing a complete definition of good design, someone else points out that a generative definition would suffice, someone else claims that a generate definition doesn&amp;#8217;t do the job&amp;#8230; I could almost write the entire thread myself by now. Some people lament the lack of a complete, constructive definition of good design. I don&amp;#8217;t, and today I finally articulated why I don&amp;#8217;t think we particular need to worry about this.&lt;/p&gt;
&lt;p&gt;I don&amp;#8217;t mean to disparage the search for a clear test of a design&amp;#8217;s &amp;#8220;goodness&amp;#8221;, because I think great things could come from that search: automated design critics, better objective measures of design health, possibly even a model for estimating the cost of maintaining a given design. I would find these things personally useful and I believe the software community would benefit from them. Still, the fact that we don&amp;#8217;t yet have these things doesn&amp;#8217;t need to cause us such consternation, because we can still do so much without it.&lt;/p&gt;
&lt;p&gt;In the past ten years I have learned some incredibly useful things about design:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;When programmers write design tests, they tend to find more of their own defects more quickly, which reduces the overall cost of realizing their design.&lt;/li&gt;
	&lt;li&gt;When programmers duplicate code, defect rates increase, and when they reduce duplication, defect rates decrease.&lt;/li&gt;
	&lt;li&gt;When programmers first start to change unfamiliar code, they tend to start by clarifying unclear names in the code: variable names, method names, class names. This practice helps them change code more safely and less expensively.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have learned these things through my own practice, through pairing with others, and through observing other programmers at work. I find it more significant to note that even with only these three observations, we have improved the value of software design considerably. Even more significant than that, we can still improve the value of software design more by continuing to spread these observations to ever more programmers, projects and teams. We can still do so much more good with these observations than we have already done. We can wait for the next great breakthroughs.&lt;/p&gt;
&lt;p&gt;Imagine the day arrives when every software designer in the world uses tests (or specs, if you prefer) to guide their design, focuses on reducing duplication and pays attention to naming their design elements appropriately. Either we&amp;#8217;ll have seen the next great design breakthrough by then, or we&amp;#8217;ll have seen so much good design that we&amp;#8217;ll have extracted the essential patterns of good design that can lead to a meaningful, useful, deep, objective test for design goodness. Either way, I think we will win.&lt;/p&gt;
&lt;p&gt;In the meantime, I leave the search for a definition of great design to the programmer-philosophers. I get by with the Miller Test: I know it when I see it.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/220';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/220&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 27, 2009  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 27 Jan 2009 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/220</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Please review my session proposal for Agile 2009</title>
      <link>http://jbrains.ca/permalink/219</link>
      <description>&lt;div class='entry posting' id='entry-_posting_219'&gt;
&lt;div class='posting' id='content-_posting_219'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have proposed a 90-minute talk entitled &amp;#8220;An Introduction to Agile Through the Theory of Constraints&amp;#8221;. &lt;a href=&quot;http://agile2009.agilealliance.org/node/553&quot;&gt;Please review it&lt;/a&gt;. Thanks.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/219';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/219&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 26, 2009  16:38
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2009&quot;&gt;agile 2009&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 26 Jan 2009 16:38:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/219</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The Quality/Speed Barrier</title>
      <link>http://jbrains.ca/permalink/218</link>
      <description>&lt;div class='entry posting' id='entry-_posting_218'&gt;
&lt;div class='posting' id='content-_posting_218'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;[Update on February 7, 2009: I need to rewrite this article, and I will, so if it has confused you, don&amp;#8217;t worry. I will fix that soon.]&lt;/p&gt;
&lt;p&gt;I haven&amp;#8217;t yet learned how to measure it, but I believe I have identified a kind of Law of Software Development that I call the &lt;em&gt;Law of the Quality/Speed Barrier&lt;/em&gt;. This law states the following.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;For any project we can find a quality level below which one must trade off quality and speed and above which one derives more speed from better quality.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now I admit that this definition suffers from a lack of precision, so let me explain what I mean. Please hold your cards and letters about &lt;a href=&quot;http://jamesshore.com/Articles/Quality-With-a-Name.html&quot;&gt;the pointlessness of the word &lt;br /&gt;
&lt;em&gt;quality&lt;/em&gt;.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We can measure quality by looking at any useful measure of the general software development community considers to represent quality: defect rate in time, defect density, defect totals, weight defect totals by severity or urgency, marginal cost of a feature, average cost to fix a defect, average cost to assess impact of a proposed change. I don&amp;#8217;t mind which you choose, because for the purposes of the Law of the Quality/Speed Barrier, any will do.&lt;/p&gt;
&lt;p&gt;We can measure speed by looking at the usual measure of speed: effort required to design and correctly implement an average-difficulty feature, team velocity, team velocity trends over time, cost to deliver an average-difficulty feature. Again, choose the one you like, since any one will do.&lt;/p&gt;
&lt;p&gt;However you wish to measure quality and speed, if you have high enough quality, then more quality helps you attain more speed; and if you have low enough quality, then you have to sacrifice quality for more speed and you have to sacrifice speed for more quality. I have not studied hundreds of projects to defend my position; however, I have worked to varying degrees on dozens of projects, and I believe the law has held in all those cases.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/QualitySpeedBarrier.jpg&quot; style=&quot;width: 480px;&quot; title=&quot;Graph of the Quality/Speed Barrier&quot; alt=&quot;Graph of the Quality/Speed Barrier&quot; /&gt;&lt;/p&gt;
&lt;p&gt;You might have observed this in your own project, largely as a general feeling that you might find difficult to substantiate with data, but that nonetheless your every observation seems to confirm.&lt;/p&gt;
&lt;p&gt;What I find most vexing about this law concerns the conclusion that in order to move above the Quality/Speed Barrier, one must sacrifice speed in the interim. My consulting practice includes helping organizations accurately decide when they should start investing more heavily in the kind of change program that would help them increase quality, reach, then eventually surpass, the Barrier. &lt;strong&gt;For most, a simple awareness of the Barrier makes it easier to know whether to invest in trying to cross it.&lt;/strong&gt; In most cases, teams find themselves above the Barrier because they made an agreement to start above the Barrier and not allow themselves to fall below it. It appears much easier to maintain your position above the Barrier if you&amp;#8217;ve started there, just as it appears easiest to maintain your position below the Barrier if ever you&amp;#8217;ve let yourself fall below it, whether you&amp;#8217;ve started below it or not.&lt;/p&gt;
&lt;p&gt;I encourage you to gather some informal feedback from your team about this question. Do you believe you operate above or below the Barrier? How do you know? Do you believe you have started above the Barrier and fallen below it? What have you seen or heard that makes you believe that? Most importantly, if you find yourself below the Barrier, what can you measure or detect that would help you estimate the return on a potential investment in training, changes in work habits and changes in work systems that would help you climb over the Barrier? How would you know you&amp;#8217;ve succeeded?&lt;/p&gt;
&lt;p&gt;As always, the questions matter more than the answers.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/218';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/218&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 21, 2009  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 21 Jan 2009 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/218</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>If I can't inspire myself, at least I can inspire someone else</title>
      <link>http://jbrains.ca/permalink/216</link>
      <description>&lt;div class='entry posting' id='entry-_posting_216'&gt;
&lt;div class='posting' id='content-_posting_216'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I enjoy speaking to people at conferences mainly because perhaps they will try some of the things that I find myself too unmotivated or just plain lazy to try. I just found out that Corey Haines&amp;#8217; &lt;a href=&quot;http://tinyurl.com/9rvj4m&quot;&gt;Pair Programming Tour&lt;/a&gt; had as part of its inspiration a conversation Corey and I had about Paul Erd&amp;amp;#x151;s&amp;#8217; unusual career. Thanks, Corey, for acknowledging me during your tour.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/216';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/216&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 10, 2009  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 10 Jan 2009 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/216</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Please propose sessions for XP 2009 and Agile 2009</title>
      <link>http://jbrains.ca/permalink/217</link>
      <description>&lt;div class='entry posting' id='entry-_posting_217'&gt;
&lt;div class='posting' id='content-_posting_217'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I would like to invite you to submit a proposal for a workshop, tutorial or talk to &lt;a href=&quot;http://xp2009.org&quot;&gt;XP 2009&lt;/a&gt; or &lt;a href=&quot;http://agile2009.org&quot;&gt;Agile 2009&lt;/a&gt;. The deadlines for proposals are in mid-February, so you have a few weeks. Don&amp;#8217;t forget to read &lt;a href=&quot;http://tinyurl.com/7ub2yt&quot;&gt;Kent Beck&amp;#8217;s paper about submitting papers to &lt;span class=&quot;caps&quot;&gt;OOPSLA&lt;/span&gt;&lt;/a&gt; to help you get started.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/217';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/217&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 10, 2009  02:24
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 10 Jan 2009 02:24:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/217</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Agile and innovation</title>
      <link>http://jbrains.ca/permalink/215</link>
      <description>&lt;div class='entry posting' id='entry-_posting_215'&gt;
&lt;div class='posting' id='content-_posting_215'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;A friend who is working towards learning to be a game developer, and whose instructor is exposing him to some agile concepts, asked me this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[O]ne of the problems I see with Agile Development with relation to Game Development is on the &amp;#8216;creative&amp;#8217; end, and with research and development. Researching new technology (speaking in software teams) takes time, usually an undetermined amount of time. But, given the methods used in Agile development, it seems that there is little room for allowing &amp;#8216;creative freedom&amp;#8217; in order to innovate a genre.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I answered this way, which is rough and unedited.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I believe, on the contrary, that agile is one approach that explicitly allows for creative freedom by focusing our energy away from deadlines towards minimum marketable features. I see R&amp;amp;D fueling agile development in a simple way: the ongoing R&amp;amp;D activity uncovers something, which we decide to turn into or add into a product, from which we create stories, then we deliver those stories. Agile focuses on making those stories as lean as possible: maximum business value per unit of effort. A traditional perspective on R&amp;amp;D is that it generates projects or product lines, while an agile perspective is that it generates ideas for features. The difference is batch size.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;One consequence of an agile project&amp;#8217;s heartbeat is that the team delivering stories forgets to spend time innovating because they simply deliver stories. A high-functioning agile team is probably producing enough business value to be able to add slack into their schedule for innovation. Read DeMarco&amp;#8217;s &amp;#8220;Slack: The Myth of Total Efficiency&amp;#8221; for some specific cases. I recommend two kinds of slack: (1) Split the year into 4 quarters, each 13 weeks; spend 12 weeks delivering stories and 1 week doing anything except delivering stories; this follows a natural business rhythm of one release per quarter followed by a solid week of creative time. (2) Within an iteration, spend up to 20% of your time on innovation: exploring technology, exploring business ideas, or just plain gazing into the distance; most teams don&amp;#8217;t do this because they&amp;#8217;re buried under a mountain previously-promised and not-yet-delivered projects; such a team has no slack, whether it does agile or not.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I have taken many of these ideas from well-respected sources of opinion on strategic thinking. Most notably, although I can&amp;#8217;t remember where I read it, I remember reading about spending a half-day per week, a full day per month and a full week per quarter purely on strategic thinking. I wish I did a better job of following this advice myself. I did not mention gold cards, but you should look for &amp;#8220;Innovation and Sustainability with Gold Cards&amp;#8221; by Julian Higman, Tim Mackinnon, Ivan Moore and Duncan Pierce as another source of information on how to save time for innovation in an XP project. I don&amp;#8217;t remember where I first read the 12 weeks/1 week idea. I&amp;#8217;d appreciate a reference in case you read it, too, and remember where.&lt;/p&gt;
&lt;p&gt;[2008-12-18 Tobias Fors brought &lt;a href=&quot;http://tinyurl.com/3teyd3&quot;&gt;this&lt;/a&gt; to my attention, and while I don&amp;#8217;t think that&amp;#8217;s the reference I was thinking of, it&amp;#8217;s a damn fine one. Read it.]&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/215';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/215&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
November 22, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 22 Nov 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/215</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Looking for a Project Manager and Business Analyst (one person) in the Toronto area</title>
      <link>http://jbrains.ca/permalink/213</link>
      <description>&lt;div class='entry posting' id='entry-_posting_213'&gt;
&lt;div class='posting' id='content-_posting_213'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have a friend looking for someone with both Project Manager and Business Analyst skills for a contract position running 9-12 months in the Toronto area. If you&amp;#8217;d like to inquire about this opportunity, please respond to the email address prominently displayed on this page.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/213';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/213&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
November 07, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/employee-rescue&quot;&gt;employee rescue&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 07 Nov 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/213</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>I expect to be in Paris in January...</title>
      <link>http://jbrains.ca/permalink/214</link>
      <description>&lt;div class='entry posting' id='entry-_posting_214'&gt;
&lt;div class='posting' id='content-_posting_214'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&amp;#8230;so if you live there and would like to visit, please email me to let me know that. I&amp;#8217;d enjoy seeing you.&lt;/p&gt;
&lt;p&gt;At the same time, if you know a company in the area* who you believe would benefit from my services and would be interested in hiring me at a greatly reduced price, I would like to explore that possibility, too. I would appreciate an introduction by email.&lt;/p&gt;
&lt;p&gt;As always, send email to the address displayed prominently on this page.&lt;/p&gt;
&lt;p&gt;*By &amp;#8220;in the area&amp;#8221;, we mean someplace within a 4-hour train ride of Paris, so even if your company is not in the city, we can probably work something out. Possible destinations include Frankfurt, Bruxelles, Lyon, Marseille, Bordeaux, Amsterdam and London.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/214';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/214&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
November 06, 2008  23:39
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 06 Nov 2008 23:39:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/214</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>&quot;Failing Quickly&quot; via Productivity501</title>
      <link>http://jbrains.ca/permalink/211</link>
      <description>&lt;div class='entry posting' id='entry-_posting_211'&gt;
&lt;div class='posting' id='content-_posting_211'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I started reading productivity501.com about a year ago and have really liked what I&amp;#8217;ve read to date. Occasionally, I see an article there that relates quite directly to agile software development, so I wanted to share that with you. I hope you start reading productivity501.com and enjoy it.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.productivity501.com/failing-quickly/53/&quot;&gt;Failing Quickly&lt;/a&gt; begins&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Failing can be one of the most productive things you can do.  Most people try to avoid failure. I&#8217;m not saying that this is bad, but in many cases they are just delaying failure to a later point in time.  If something you are doing is going to result in failure you should do your best to make sure it happens sooner rather than later.  With few exceptions, failing now is going to be less expensive (in time, money, mental stress) than failing one year from now.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Enjoy the article.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/211';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/211&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 02, 2008  02:48
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 02 Oct 2008 02:48:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/211</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Call for samples of integration tests</title>
      <link>http://jbrains.ca/permalink/210</link>
      <description>&lt;div class='entry posting' id='entry-_posting_210'&gt;
&lt;div class='posting' id='content-_posting_210'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I need your help.&lt;/p&gt;
&lt;p&gt;At the &lt;a href=&quot;http://sqe.com/agiledevpractices&quot;&gt;Better Software Agile Development Practices&lt;/a&gt; conference in November I will present my tutorial entitled Avoid Integration Defects Without Integration Tests. I will describe and demonstrate the design benefits of reducing your reliance on integration tests (specifically end-to-end tests) to gain confidence in the basic correctness of code. I&amp;#8217;d like to take sample integration or end-to-end tests from the audience and turn them into good, focused object tests, but at a busy conference, few audience members prepare such material in advance.&lt;/p&gt;
&lt;p&gt;Enter you.&lt;/p&gt;
&lt;p&gt;If you have some end-to-end or integration tests that you&amp;#8217;d like to turn into good, focused object tests that help improve your design while offering the same or better confidence in the correctness of your code, then please &lt;a href=&quot;mailto:integration.tests@jbrains.info&quot;&gt;contact me&lt;/a&gt; to receive instructions on how to send me your sample. I will, of course, give you whatever credit you want, or promise not to identify you if you&amp;#8217;d rather remain anonymous. Whether I use the sample in the tutorial, I will work with you to show you how to improve your design through focused, object tests, rather than relying on integration tests.&lt;/p&gt;
&lt;p&gt;Thanks.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/210';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/210&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 01, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-dev-practices-2008&quot;&gt;agile dev practices 2008&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 01 Oct 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/210</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Microtechniques: typing</title>
      <link>http://jbrains.ca/permalink/209</link>
      <description>&lt;div class='entry posting' id='entry-_posting_209'&gt;
&lt;div class='posting' id='content-_posting_209'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I remember Alistair Cockburn presenting a keynote address at XP/Agile Universe 2002 in Chicago. I remember most vividly his comments on microtechniques, a phrase that struck me and has stayed with me since that time. He described how microtechniques enable higher-level improvements by speeding up the rote parts of one&amp;#8217;s work. Put another way, quicker typing buys slack, and since slack compounds, higher-level improvements are significant and inevitable. To write code, we type, and we learn to type by rote. While programming involves much more than typing, programming includes typing, so one can argue convincingly that typing well helps people develop as programmers. I contend that typing combines with knowing your text editor or &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt; well to drastically amplify a programmer&amp;#8217;s skill, which explains the typing test badge attached to this entry. I believe my typing speed helps make me a better programmer.&lt;/p&gt;
&lt;p&gt;At times, though, fast typing gets me into trouble. I do manage to spend too much time typing quickly and not enough time typing thoughtfully. Does this mean, then, that typing quickly really slows me down? I haven&amp;#8217;t measured it closely, so no-one knows the answer; however, I have become conscious of this, which explains why I so easily get up and walk away from the keyboard when things don&amp;#8217;t go well. I know that I need to walk away from the keyboard to avoid letting my quick typing lead me down a rathole and, perhaps more importantly, I know when I come back to the keyboard with better ideas that typing won&amp;#8217;t pose a bottleneck to completing the task. In a sense, I treat typing time as free and feel comfortable taking all the time I need to think. More than anything else, &lt;strong&gt;this&lt;/strong&gt; helps make me a better programmer.&lt;/p&gt;
&lt;p&gt;Would you do well to take a typing class? Perhaps. I suppose if you can afford to spend an hour per day for three months to practise typing and if you plan to type for more than about 10 more years, then you ought to at least consider it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Suppose a full-time programmer sits at the keyboard prepared to type about four hours per day, half of that time actively typing. If you increase your speed from 30 to 40 words per minute, then you&amp;#8217;d reduce typing time from two hours to 90 minutes. An investment of 65 hours (1 hour per day for three months, meaning 250 / 4 &amp;lt; 65 working days) would return 0.5 hours per day * 250 working days per year * 10 years = 1250 hours of saved typing. I count more than 1920% return over 10 years, or 35% return per year compounded annually for 10 years. (1250 / 65 &amp;gt; 19.23 and (1 + 19.23) ^ (1/10) &amp;#8211; 1 &amp;gt; 0.35) The payback period for the 65 hours of investment is approximately 130 days (65 working days * 0.5 hours saved per day) or 7 working months (12 * 130 / 250 &amp;lt; 7). In other words, if you took a three-month typing course for one hour per day that improved your typing speed from 30 to 40 wpm, the decrease in typing effort would return you the investment in 4-10 months (7 +/- 50%). This ignores your increase in effectiveness from spending more time thinking about what you type before you type it! It sounds like a win to me.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://speedtest.10-fast-fingers.com&quot; style=&quot;display: block; width: 300px; height: 100px; background: url('http://speedtest.10-fast-fingers.com/img/badge1.png') no-repeat; padding-top: 50px; padding-left: 60px; color: #009933; font-weight: bold; text-decoration: none; font-family: Times New Roman, Arial, serif; font-size: 40px;&quot;&gt;102 words&lt;/a&gt;&lt;p&gt;&lt;a href=&quot;http://speedtest.10-fast-fingers.com&quot;&gt;Typing Test&lt;/a&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/209';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/209&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 20, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 20 Sep 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/209</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>JUnit: A Starter Guide</title>
      <link>http://jbrains.ca/permalink/208</link>
      <description>&lt;div class='entry posting' id='entry-_posting_208'&gt;
&lt;div class='posting' id='content-_posting_208'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Not long after the Christmas break between 2001 and 2002 I wrote &amp;#8220;JUnit: A Starter Guide&amp;#8221; in response to a flurry of complaints over the lack of a decent JUnit tutorial. I didn&amp;#8217;t know at the time that I would turn this simple tutorial, written somewhat in haste, into &lt;em&gt;JUnit Recipes: Practical Methods for Programmer Testing&lt;/em&gt;, which I completed in 2004. It has surprised me to note that several hundred people continue to read the Starter Guide, so I thought I would include a link to it from here. In order not to deal with differences in &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; formatting, I have decided to link to the document as a &lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt; and keep it mostly for historical purposes. Much has changed since 2002, and I hope the Starter Guide remains a solid introduction to JUnit, test-driven development and software design.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://articles.jbrains.ca/JUnitAStarterGuide.pdf&quot; title=&quot;pdf&quot;&gt;JUnit: A Starter Guide&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/208';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/208&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 19, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 19 Sep 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/208</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Gordon Pask Award: write the future</title>
      <link>http://jbrains.ca/permalink/207</link>
      <description>&lt;div class='entry posting' id='entry-_posting_207'&gt;
&lt;div class='posting' id='content-_posting_207'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;At Agile 2008 I agreed to take the reins of the Gordon Pask Award from Brian Marick, who had stewarded the award through its first four years. Laurent Bossavit and I have agreed to administer the award for the foreseeable future, although I promise Laurent that I will do most of the work. I have quite strong personal feelings about the award, since the committee awarded it to Jim Shore and me in 2005, and I also have some strong feelings about public recognition in general, so I felt it wise to canvas the public a little to find out what &lt;em&gt;they&lt;/em&gt; think about the award. In the past month, a handful of you have responded, and I have organized those responses into a few categories. I wanted to share them with you in the hopes that more of you would provide some input, even if just &amp;#8220;me, too&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Most of the respondents said that the Gordon Pask Award helps them know &lt;strong&gt;whom they should talk to&lt;/strong&gt;. I consider this the primary mission of the award: to shine a light on the people the community ought to pay attention to and even push to greater heights. I also consider this the award&amp;#8217;s greatest strength, and I will encourage the selection committee to keep this point uppermost in its collective mind when it meets to select the 2009 winners. &lt;strong&gt;What problems do you believe this approach will create?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A few respondents said that they look at the award winners as models to emulate. One person said that seeing someone win the award made him think he should &amp;#8220;get off (his) ass and add value.&amp;#8221; Another said that the winners&amp;#8217; actions serve as a model to him. A third said that the award &amp;#8220;breathes new life&amp;#8221; into the community. I consider this to be an important part of the award&amp;#8217;s influence: a kind of call to action to the rest of the community. I felt especially proud of Arlo Belshee&amp;#8217;s call to action: come back to Agile 2009 and tell us what you&amp;#8217;ve invented in the past year. I believe this kind of rallying helps the community grow, although I remain concerned about the award&amp;#8217;s effective on people&amp;#8217;s intrinsic motivation. I have read Kohn&amp;#8217;s &lt;em&gt;Punished By Rewards&lt;/em&gt; and I find it important to dampen the negative effects of the award on the community. I don&amp;#8217;t want people to do things expressly hoping to win the award, and a part of me believes that karma will stop those people from winning, anyway. &lt;strong&gt;What other problems do you believe the award will create?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A couple of respondents pointed out the importance of knowing on what basis people nominated others, and especially on what basis we chose the winners. I understand the desire for transparency, but I fear that if we act too transparently, then we will lose our opportunity to be flexible and dynamic in our choices. Our selection committee meetings take long enough already and as the committee expands to include two more winners, I imagine the complexity will only increase. To add things like precedents and worry about how this group of people who react to choosing Person X over Person Y&amp;#8230; frankly, if that starts to happen, then I will walk away from the program entirely. On the other hand, I do counsel businesses to be uncomfortably transparent, so I don&amp;#8217;t know how to take my own advice here. I don&amp;#8217;t know how to balance transparency with freedom to make choices without undue recrimination from the agile community. &lt;strong&gt;Do you have any advice for us on that front?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Someone suggested we publish a collection of references to the award winners&amp;#8217; work shortly after we present the award as a starting place for learning about the award winners and their work. I really like this idea and I plan to invite Kenji Hiranabe and Arlo Belshee to help me prepare an anthology of sorts for them. &lt;strong&gt;I encourage you to suggest references to their work as well by email.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One person commented about how easily one could see the award winners become a clique, meaning that one would need to belong to an inner circle to win the award. This represents by far my greatest fear for the Gordon Pask Award. Given that the previous winners get together with Brian Marick, Rachel Davies and Big Dave Thomas to select the next winners, and given that the nominating process has progressed somewhat haphazardly so far, I can see the risk of becoming another Old Boys Network. I don&amp;#8217;t know how to deal with this potential problem, except to keep it in mind as the selection committee works towards selecting new winners, as well as working with you to make the nomination process more open. I want desperately to avoid turning the Gordon Pask Award into American Idol! I don&amp;#8217;t want the public the vote and I especially don&amp;#8217;t want to see effects like &amp;#8220;Vote For The Worst&amp;#8221; infiltrate this award. This might mean less transparency, but I remain open to other suggestions. &lt;strong&gt;If you feel concerned about the award winners becoming a closed circle, what might we do to allay your concern?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One person commented that no woman has yet won the award. On this point, I must remain firm. I will influence the selection committee as much as possible against letting issues of gender, religion, sexual orientation, or any similar issues directly affect the choices we make. I do not want to give the award to a woman in 2009, an Eastern European in 2010, then someone fitting some other particular &amp;#8220;type&amp;#8221; in 2011. Anyone can win the award. A diverse group selects the winners, and that group grows more diverse each year. I don&amp;#8217;t see anyone trying to keep the award away from women, gays, or the handicapped. I especially don&amp;#8217;t care to dispute the notion of &amp;#8216;proper terms&amp;#8217; for groups of people. On this basis, &lt;strong&gt;I see no need to encourage the selection committee to consider any particular group of people for the award. We consider anyone and everyone.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;No-one yet has taken the time to tell us that they want us to discontinue the award. If you happen to feel that way, &lt;a href=&quot;mailto:gordonpaskaward@jbrains.ca&quot;&gt;I really want to hear from you&lt;/a&gt;, because those opinions will tend to differ from mine the most. I need those opinions to have a balanced view. Please don&amp;#8217;t hold back.&lt;/p&gt;
&lt;p&gt;Finally, if you have any suggestions related to the questions above, please &lt;a href=&quot;mailto:gordonpaskaward@jbrains.ca&quot;&gt;tell me about them&lt;/a&gt;, otherwise I will simply choose the suggestions I like and change nothing else. Thank you for your time.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/207';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/207&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 12, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/gordon-pask-award-2009&quot;&gt;gordon pask award 2009&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 12 Sep 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/207</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Employee Rescue Wednesday for September 10, 2008</title>
      <link>http://jbrains.ca/permalink/206</link>
      <description>&lt;div class='entry posting' id='entry-_posting_206'&gt;
&lt;div class='posting' id='content-_posting_206'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Act fast! Positions either fill quickly or clients move on. Don&amp;#8217;t waste this opportunity.&lt;/p&gt;
&lt;p&gt;Are you looking for the contract that will let you &lt;strong&gt;take the plunge as an independent contractor&lt;/strong&gt;? We have an opportunity in Des Moines IA that could let you live for a year on only six months&amp;#8217; worth of work. You need to be an expert-level .&lt;span class=&quot;caps&quot;&gt;NET&lt;/span&gt;/C# programmer with at least one professional Java project and who knows Extreme Programming. Give yourself some slack by building up an emergency fund while you &lt;strong&gt;take your first steps towards financial independence&lt;/strong&gt;. &lt;a href=&quot;mailto:desmoines@diasparsoftware.com&quot;&gt;Send your resume and a write-up of your last .&lt;span class=&quot;caps&quot;&gt;NET&lt;/span&gt;/C# project, including how you applied agile concepts to your work!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Are you frustrated&lt;/strong&gt; that your co-workers won&amp;#8217;t listen to your great ideas about how to deliver software? Our New York City-based client wants you to teach them while you work! You need to be a strong Java programmer with agile skills (&lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;, evolutionary design, adaptive planning) who has a desire to teach. &lt;strong&gt;Put your ideas to good use&lt;/strong&gt; and build up slack in your work schedule while you do it. &lt;a href=&quot;mailto:newyorkcity@diasparsoftware.com&quot;&gt;Send your resume and a write-up of the three ideas your co-workers won&amp;#8217;t let you implement!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Looking for your first contract as a programmer? You need to be well-versed in agile practices and have experience with Java technology skills for a project in Columbus OH that will run at least until December. &lt;strong&gt;Earn more than you can as an employee while we pay your living expenses for at least four months&lt;/strong&gt;. &lt;a href=&quot;mailto:columbus@diasparsoftware.com&quot;&gt;Send your resume and a write-up of your experience as an agile programmer today!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Interested to see whether you could live someplace small and inexpensive? Give yourself a chance to live the cheap life and contemplate earlier retirement by house-sitting for six to eight weeks in &lt;a href=&quot;http://tinyurl.com/57as5a&quot;&gt;Dauphin, Manitoba, Canada&lt;/a&gt;. The fastest way to retirement is to live simply: it builds slack in your finances that you can use to learn to become as rich as you want to be. We pay your expenses; you take care of a house and a few cats. &lt;a href=&quot;mailto:housesitting@diasparsoftware.com&quot;&gt;Tell us you&amp;#8217;d like the house-sit starting October 13 until sometime between November 17 or December 8, depending on our travel schedule.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/206';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/206&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 10, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/employee-rescue&quot;&gt;employee rescue&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 10 Sep 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/206</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Employee Rescue Wednesday for September 3, 2008</title>
      <link>http://jbrains.ca/permalink/205</link>
      <description>&lt;div class='entry posting' id='entry-_posting_205'&gt;
&lt;div class='posting' id='content-_posting_205'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Act fast! Positions either fill quickly or clients move on. Don&amp;#8217;t waste this opportunity.&lt;/p&gt;
&lt;p&gt;Are you looking for the contract that will let you &lt;strong&gt;take the plunge as an independent contractor&lt;/strong&gt;? We have an opportunity in Des Moines IA that could let you live for a year on only six months&amp;#8217; worth of work. You need to be an expert-level .&lt;span class=&quot;caps&quot;&gt;NET&lt;/span&gt;/C# programmer with at least one professional Java project and who knows Extreme Programming. Give yourself some slack by building up an emergency fund while you &lt;strong&gt;take your first steps towards financial independence&lt;/strong&gt;. &lt;a href=&quot;mailto:desmoines@diasparsoftware.com&quot;&gt;Send your resume and a write-up of your last .&lt;span class=&quot;caps&quot;&gt;NET&lt;/span&gt;/C# project, including how you applied agile concepts to your work!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Are you frustrated&lt;/strong&gt; that your co-workers won&amp;#8217;t listen to your great ideas about how to deliver software? Our Newark-based client wants you to teach them while you work! You need to be a strong Java programmer with agile skills (&lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;, evolutionary design, adaptive planning) who has a desire to teach. &lt;strong&gt;Put your ideas to good use&lt;/strong&gt; and build up slack in your work schedule while you do it. &lt;a href=&quot;mailto:newark@diasparsoftware.com&quot;&gt;Send your resume and a write-up of the three ideas your co-workers won&amp;#8217;t let you implement!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Looking for your first contract as a programmer? You need to be well-versed in agile practices and have experience with Java technology skills for a project in Columbus OH that will run at least until December. &lt;strong&gt;Earn more than you can as an employee while we pay your living expenses for at least four months&lt;/strong&gt;. &lt;a href=&quot;mailto:columbus@diasparsoftware.com&quot;&gt;Send your resume and a write-up of your experience as an agile programmer today!&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/205';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/205&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 03, 2008  08:38
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/employee-rescue&quot;&gt;employee rescue&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 03 Sep 2008 08:38:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/205</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Story Test-Driven Development: don't start here</title>
      <link>http://jbrains.ca/permalink/204</link>
      <description>&lt;div class='entry posting' id='entry-_posting_204'&gt;
&lt;div class='posting' id='content-_posting_204'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I don&amp;#8217;t want to claim that story test-driven development doesn&amp;#8217;t work, because some of my most respected colleagues teach the practice with success; however, I do want to warn people who might find themselves seduced by &lt;span class=&quot;caps&quot;&gt;STDD&lt;/span&gt;, especially if they think of it as an easy replacement for &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Allow me to clarify the two terms, &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;STDD&lt;/span&gt;. To practice &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;, the programmer begins with a small, well-defined behavior they&amp;#8217;d like to implement. Typically, they design that behavior as a method on a class, although they could get away with doing even less, then brainstorm a list of tests they might write. With such a list in hand, they run through the &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; cycle, illustrated beautifully by Bill Wake&amp;#8217;s &lt;a href=&quot;http://xp123.com/xplor/xp0101/index.shtml&quot;&gt;stoplight analogy&lt;/a&gt;. When the design behaves adequately and correctly, the programmer stops.&lt;/p&gt;
&lt;p&gt;To practice &lt;span class=&quot;caps&quot;&gt;STDD&lt;/span&gt;, the programmer begins with a story and several story tests, which I tend to call &amp;#8220;examples&amp;#8221;. The programmer then selects a story test, watches it fail, then test-drives enough code to make it pass. One by one, the programmer makes each story test pass until they complete the entire story.&lt;/p&gt;
&lt;p&gt;I have been teaching people about &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; and stories for years, and have practiced &lt;span class=&quot;caps&quot;&gt;STDD&lt;/span&gt; most of that time, in one form or another. I find the technique helpful; however, when I have pushed &lt;span class=&quot;caps&quot;&gt;STDD&lt;/span&gt; to its limit, I have found it to guide me in directions I don&amp;#8217;t like, which &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; has generally never done. When I watch others attempt to practice &lt;span class=&quot;caps&quot;&gt;STDD&lt;/span&gt;, especially novices and advanced beginners, I see how they misapply &lt;span class=&quot;caps&quot;&gt;STDD&lt;/span&gt; and lead themselves towards a Big Ball of Mud, despite what the agile community&amp;#8217;s marketing machine says about &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; and stories. I believe the intersection of the two creates problems for those not accustomed to the different goals of &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; and user stories.&lt;/p&gt;
&lt;p&gt;I use examples, the term I use for story tests, to show progress towards delivering a story, or feature. Broadly, I add examples to reflect increasing levels of understanding of the system to design, and as examples pass, that reflects progress towards delivering an ever more powerful system. I use programmer tests, the term I use in place of unit tests, to test my design ideas as they come to me and to help me type code in correctly. Any time all the programmer tests pass, the system works as designed, even if it does not yet do everything the business needs. Any time all the programmer tests pass, I can freely commit changes to the main line of the project&amp;#8217;s design repository.&lt;/p&gt;
&lt;p&gt;More succinctly, examples help us design the right system and programmer tests help us design the system right. (I prefer &amp;#8220;correctly&amp;#8221; there, but then I lose the symmetry.)&lt;/p&gt;
&lt;p&gt;I often see programmers try to use passing examples as an absolute criterion to stop designing. They underestimate, in my opinion, the role of programmer tests to put positive pressure on their design. Examples, especially when written as end-to-end or integration tests (a test whose failure does not isolate the mistake to a single method), simply do not put positive pressure on a design: their high-level nature can&amp;#8217;t constrain a design enough to support careful refactoring. For this reason, I recommend novices and advanced beginners not practice &lt;span class=&quot;caps&quot;&gt;STDD&lt;/span&gt; until they first see or feel for themselves the impact focused, small programmer tests have on their design.&lt;/p&gt;
&lt;p&gt;I want to leave no room for doubt: I do not mean to say that novices should avoid &lt;span class=&quot;caps&quot;&gt;STDD&lt;/span&gt; as an &amp;#8220;advanced practice&amp;#8221;; but rather that a combination of novice tendencies makes &lt;span class=&quot;caps&quot;&gt;STDD&lt;/span&gt; harder than &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; to practice well. Specifically, the novice tends to write examples as end-to-end tests, which provide too much design freedom and exert too little positive pressure on the design to guide refactoring and prevent defects. Instead, I would counsel novices and advanced beginners to focus on &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; and run the examples every hour or so to measure their progress towards delivering the story.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://tinyurl.com/5vklgp&quot;&gt;Read more&lt;/a&gt; about how to practice &lt;span class=&quot;caps&quot;&gt;STDD&lt;/span&gt; well.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/204';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/204&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 02, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/stories&quot;&gt;stories&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 02 Sep 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/204</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Istanbul, Eindhoven, Bled</title>
      <link>http://jbrains.ca/permalink/203</link>
      <description>&lt;div class='entry posting' id='entry-_posting_203'&gt;
&lt;div class='posting' id='content-_posting_203'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;In case you don&amp;#8217;t religiously follow &lt;a href=&quot;http://jbrains.ca/appearing.html&quot;&gt;where I&amp;#8217;m appearing&lt;/a&gt;, I simply wanted to announce that we will visit Istanbul August 21-23, travel from their to Eindhoven, Netherlands August 25-29, and finally on to Bled, Slovenia August 30-September 7. If you live near these places and would like to get together or would like me to speak to a local company or user group, please contact me by email and we will attempt to arrange things. Since I do not drive, you&amp;#8217;d need to provide transportation to and from the event, which could be a pre-paid taxi, a ride from a friend or detailed instructions on using public transport to get there and back.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/203';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/203&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 20, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 20 Aug 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/203</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Gordon Pask Award 2009</title>
      <link>http://jbrains.ca/permalink/202</link>
      <description>&lt;div class='entry posting' id='entry-_posting_202'&gt;
&lt;div class='posting' id='content-_posting_202'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have agreed to administer the Gordon Pask Award starting in 2009. Brian Marick has done a wonderful job, just at the edge of chaos, in starting the program and I hope to be able to continue in his footsteps. Laurent Bossavit has agreed, at least in principle, to co-administer the program and I know I will need his help.&lt;/p&gt;
&lt;p&gt;I have several ideas for improving the mechanics of the award in addition to a personal vision of the award, but I certainly don&amp;#8217;t mind receiving your advice. Since I cannot handle thousands of emails on the topic, I would like you to answer one of these questions regarding the prize, how we award it and how we present it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What does it mean to you to see someone other than you win a Gordon Pask Award?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;What does it mean to you to see someone other than the person you nominated win a Gordon Pask Award?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;All things considered, would you rather we continue the program or abandon it?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Please &lt;a href=&quot;mailto:gordonpaskaward@jbrains.ca&quot;&gt;send me an email&lt;/a&gt; with your thoughts. Write what you will, but please include an answer to at least one of these questions.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/202';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/202&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 12, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/gordon-pask-award-2009&quot;&gt;gordon pask award 2009&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 12 Aug 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/202</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>A review of Agile 2008</title>
      <link>http://jbrains.ca/permalink/201</link>
      <description>&lt;div class='entry posting' id='entry-_posting_201'&gt;
&lt;div class='posting' id='content-_posting_201'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I must admit to some bias in reviewing Agile 2008, because they held it in Toronto, where I lived from 1996 to 2007. I grew up in a Toronto suburb. I can&amp;#8217;t account for what portion of my positive review depends on my great familiarity and comfort with the city. Even so, I can&amp;#8217;t remember having as enjoyable a time at the Agile 200x conference since Agile 2005 in Denver when I received the Gordon Pask Award.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I &lt;span class=&quot;caps&quot;&gt;FELT&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;CONNECTED&lt;/span&gt;.&lt;/strong&gt; I have been particularly concerned about how much the conference has grown in the past few years. Large conventions like Java One do not hold my interest, which explains why I don&amp;#8217;t attend them. As attendance at Agile 200x grew from Denver to Minneapolis to DC I became concerned that I would find myself increasingly lost among the sea of people. I felt deeply connected to people in Toronto and managed even to make a handful of new connections. Even though I believe the conference consists of &amp;#8220;600 of my closest friends and 1000 people I will never meet&amp;#8221;, I must admit that I felt much more connected to the people than I did in Minneapolis and DC. I attribute much of this to the space: there were more open spaces for gathering, and I spent less time in long, narrow hallways. Granted, I found it difficult to navigate through some of the winding paths inside the Sheraton Centre, but overall I felt like I could find people I needed to find and bumped into enough people to keep it interesting. I hope I can feel this way again in Chicago in 2009.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I &lt;span class=&quot;caps&quot;&gt;REALLY&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;LEARNED&lt;/span&gt;.&lt;/strong&gt; I have had some doubt about how much of the program would excite me, and I must say that while none of the sessions intrigued me enough to draw me there, I dropped in to a handful of sessions and the presenters welcomed me in and allowed me to participate even though I sometimes tend to try to take over. I learned from those sessions and even more from hallway conversations with my peers. I hadn&amp;#8217;t felt like I&amp;#8217;d learned much from the last few years, but rather that I&amp;#8217;d spent most of my time teaching. This time I found a good balance. I don&amp;#8217;t know how much of that to attribute to my mindset, to the program, to the people the conference drew and to random chance. No matter: I love the result. I should thank Arlo Belshee for putting the thought in my head that cost estimates might not always matter much. That one will stick with me for a while, I imagine.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I &lt;span class=&quot;caps&quot;&gt;PUSHED&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;THE&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;ENVELOPE&lt;/span&gt; OF &lt;span class=&quot;caps&quot;&gt;EXHAUSTION&lt;/span&gt;.&lt;/strong&gt; I measure the success of a conference experience by my energy level on the last day. When I find myself exhausted, I imagine I rushed too much, committed to too much and wasted too much time getting around. When I find myself lethargic, I imagine I didn&amp;#8217;t care much, didn&amp;#8217;t see the people I wanted to see, didn&amp;#8217;t find much of interest in the program and didn&amp;#8217;t learn anything worthwhile. This time, I felt energized at the tipping point of exhaustion. Perfect! In the words of the great Calvin (the modern one), &lt;a href=&quot;http://tinyurl.com/6qtsyc&quot;&gt;the days were just packed!&lt;/a&gt; I kept my schedule fluid and managed never to spend a moment bored. I imagine my fluid schedule make it difficult for other people to co-ordinate with me, so I apologize to my wife and my friends for their difficulties reaching me throughout the week, but I enjoyed it immensely. By the end, I felt ready for week two of the conference, but it abruptly ended. I call that a success.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;REVIEW&lt;/span&gt; IN A &lt;span class=&quot;caps&quot;&gt;BOX&lt;/span&gt;.&lt;/strong&gt; We stayed at the Hilton across the street, mostly because I forgot to book our room until two weeks ago.&lt;/p&gt;
&lt;table&gt;
	&lt;tr&gt;
		&lt;td&gt;Program&lt;/td&gt;
		&lt;td&gt;B&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;Open Jam&lt;/td&gt;
		&lt;td&gt;B&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;Location&lt;/td&gt;
		&lt;td&gt;A&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;Attendees&lt;/td&gt;
		&lt;td&gt;A&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;Amenities&lt;/td&gt;
		&lt;td&gt;B&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;Expense&lt;/td&gt;
		&lt;td&gt;B&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;Hotel&lt;/td&gt;
		&lt;td&gt;B&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;Overall&lt;/td&gt;
		&lt;td&gt;A-&lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;I had a few minor nits to pick: I didn&amp;#8217;t like the breakfast, which featured cost-cutting pastry over energy-boosting protein and berries; I found it difficult to carry around the large program book, so I would have preferred schedule-on-one-page on a day-by-day basis; I have become a coffee snob, so I never like the coffee anywhere, and the Sheraton fit that pattern.&lt;/p&gt;
&lt;p&gt;As I like to say, if you have no bigger problems than these, then you deserve a vacation. Thank you to Rachel Davies and her crew for doing an excellent job organizing and running this conference. Good luck to Johanna Rothman, as you have big shoes to fill. I feel confident in the result.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/201';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/201&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 12, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile-2008&quot;&gt;agile 2008&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 12 Aug 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/201</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>How are you dealing with Homeland Security confiscating electronics?</title>
      <link>http://jbrains.ca/permalink/200</link>
      <description>&lt;div class='entry posting' id='entry-_posting_200'&gt;
&lt;div class='posting' id='content-_posting_200'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;As a Canadian consultant with many US-based clients, I enter the US quite frequently, and I now know that I face random seizure of my electronics even without reasonable suspicion. I find it difficult to enter the US under these circumstances with my electronics, notably my computer and phone.&lt;/p&gt;
&lt;p&gt;Have you done anything interesting to deal with this problem? I have had to contemplate measures including requiring US clients to provide me with a MacBook Pro when I visit them. Even if I do that, what about my data? How can I guarantee that I have a bootable copy of my hard disk when I cross the border if the &lt;span class=&quot;caps&quot;&gt;TSA&lt;/span&gt; can confiscate my external hard disk?&lt;/p&gt;
&lt;p&gt;The simplest solution is to stop working in the US until the proposed law on the books requiring reasonable suspicion passes, but even then, I run a considerable risk of having materials seized even though I have nothing to hide. I don&amp;#8217;t trust Homeland Security to be reasonable.&lt;/p&gt;
&lt;p&gt;Is shipping hard disks any better? I can&amp;#8217;t risk having material held up in customs. I can&amp;#8217;t rely on internet services, because it takes days to download a 100 GB bootable disk image.&lt;/p&gt;
&lt;p&gt;I would like to know what you do about this, aside from refuse to work in the US.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/200';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/200&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 03, 2008  03:00
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 03 Aug 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/200</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>&quot;Dear XP&quot; with new English lyrics</title>
      <link>http://jbrains.ca/permalink/199</link>
      <description>&lt;div class='entry posting' id='entry-_posting_199'&gt;
&lt;div class='posting' id='content-_posting_199'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Kenji Hiranabe asked me to write new English lyrics for the &amp;#8220;Dear XP&amp;#8221; song, and with his lyrics as a starting point, here is the result:&lt;/p&gt;
&lt;p&gt;&lt;object type=&quot;application/x-shockwave-flash&quot; width=&quot;320&quot; height=&quot;263&quot; id=&quot;FlowPlayer&quot; data=&quot;http://www.archive.org/flv/FlowPlayerWhite.swf&quot;&gt;   &lt;param name=&quot;movie&quot; value=&quot;http://www.archive.org/flv/FlowPlayerWhite.swf&quot;/&gt;   &lt;param name=&quot;scale&quot; value=&quot;noScale&quot;/&gt;   &lt;param name=&quot;wmode&quot; value=&quot;transparent&quot;/&gt;   &lt;param name=&quot;allowScriptAccess&quot; value=&quot;sameDomain&quot;/&gt;   &lt;param name=&quot;quality&quot; value=&quot;high&quot;/&gt;   &lt;param name=&quot;flashvars&quot; value=&quot;config={     loop: false,     autoPlay:false,     autoBuffering:false,     initialScale: 'fit',     videoFile: 'http://www.archive.org/download/DearXPMovieAgile2008/DearXPAgile2008.flv',     splashImageFile: 'http://www.archive.org/download/DearXPMovieAgile2008/DearXPMovieAgile2008.thumbs/DearXPAgile2008_00000003.jpg',   }&quot;/&gt; &lt;/object&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/199';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/199&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 30, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2008&quot;&gt;agile 2008&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 30 Jul 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/199</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Any title would be superfluous</title>
      <link>http://jbrains.ca/permalink/198</link>
      <description>&lt;div class='entry posting' id='entry-_posting_198'&gt;
&lt;div class='posting' id='content-_posting_198'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&lt;img src=&quot;http://media.tumblr.com/FKevS0GRzbwhn5z5Qe7LbEFI_400.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/198';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/198&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 28, 2008  03:00
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 28 Jul 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/198</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Help us nominate David Chelimsky for the Gordon Pask Award</title>
      <link>http://jbrains.ca/permalink/197</link>
      <description>&lt;div class='entry posting' id='entry-_posting_197'&gt;
&lt;div class='posting' id='content-_posting_197'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Once again, nominating season for the Gordon Pask Award has begun. I have so far put my support behind one excellent candidate, David Chelimsky. &lt;a href=&quot;http://www.exampler.com/blog/2008/07/23/2008-gordon-pask-award-for-contributions-to-agile-practice/&quot;&gt;The nominating process has changed&lt;/a&gt; and we would like to garner some additional support for David. If you are interested, then please click the Discuss link for this article (which takes you to &lt;code&gt;reddit&lt;/code&gt;) and write a blurb in the style that the selection committee has asked for. (If you haven&amp;#8217;t already, read the link above.)&lt;/p&gt;
&lt;p&gt;Thank you for helping us show support for David as a significant contributor to agile practice who is well due the recognition of the Gordon Pask Award.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/197';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/197&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 26, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 26 Jul 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/197</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Please nominate someone for the 2008 Gordon Pask Award for contributions to agile practice</title>
      <link>http://jbrains.ca/permalink/196</link>
      <description>&lt;div class='entry posting' id='entry-_posting_196'&gt;
&lt;div class='posting' id='content-_posting_196'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Please nominate someone for the 2008 Gordon Pask Award for contributions to agile practice. &lt;a href=&quot;http://www.exampler.com/blog/2008/07/23/2008-gordon-pask-award-for-contributions-to-agile-practice/&quot;&gt;Read more.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/196';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/196&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 26, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 26 Jul 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/196</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Your &quot;Discuss&quot; links are broken?</title>
      <link>http://jbrains.ca/permalink/195</link>
      <description>&lt;div class='entry posting' id='entry-_posting_195'&gt;
&lt;div class='posting' id='content-_posting_195'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I could use your help, if you have the patience to help me.&lt;/p&gt;
&lt;p&gt;At least one person has reported the &amp;#8220;Discuss&amp;#8221; links are broken for him. They work for me, whether I read postings on the web or through my &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt; reader Net News Wire. If you have trouble with the &amp;#8220;Discuss&amp;#8221; links, I&amp;#8217;d appreciate knowing about them. Please send me email describing the problem so I can diagnose it. Thanks!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/195';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/195&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 10, 2008  08:56
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 10 Jul 2008 08:56:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/195</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>If we are serious about speed...</title>
      <link>http://jbrains.ca/permalink/194</link>
      <description>&lt;div class='entry posting' id='entry-_posting_194'&gt;
&lt;div class='posting' id='content-_posting_194'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have been reading the Cutter IT Journal from March 2003, when they ran a special issue on Critical Chain Project Management. I wanted to share this especially salient point. I don&amp;#8217;t know how to help my clients understand this, particularly because my clients usually find themselves behind the eight-ball and in desperate need of this advice.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If we are serious about speed, we must understand what is required for people to &#8220;go faster.&#8221; We are not asking them to work faster! We are asking them to wait, to rest, and then work at full speed. And then rest again. Our strategy is to remove all the obstacles that cause them delay and to recognize that relay runners don&#8217;t run at full speed all day. They are not &amp;#8220;fully utilized&amp;#8221; because full utilization of resources is inefficient for speed. For our people to do tasks faster, we must reduce their workload and lower their utilization. This is not a sacrifice for the organization, it is the means for substantially greater project throughput. For our people to do tasks faster, we must reduce their workload and lower their utilization.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;How do I help them understand? Click the Discuss link to give me your suggestions.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/194';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/194&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 07, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 07 Jul 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/194</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Find out where I'm appearing</title>
      <link>http://jbrains.ca/permalink/193</link>
      <description>&lt;div class='entry posting' id='entry-_posting_193'&gt;
&lt;div class='posting' id='content-_posting_193'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;To borrow from Garr Reynolds, who has taught me much about &lt;a href=&quot;http://www.presentationzen.com&quot;&gt;presentations&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://presentationzen.blogs.com/.a/6a00d83451b64669e200e552928a0d8833-pi&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;So if you&amp;#8217;d like to know where I plan to appear next, click the link under my photo or subscribe to my appearances calendar:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.google.com/calendar/feeds/p2j53mga3v3e595bkdhfth0o84%40group.calendar.google.com/public/basic&quot;&gt;as an &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt; feed&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.google.com/calendar/ical/p2j53mga3v3e595bkdhfth0o84%40group.calendar.google.com/public/basic.ics&quot;&gt;from your iCal-supported calendar&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;anyway you like with calendar ID @p2j53mga3v3e595bkdhfth0o84@group.calendar.google.com@&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Feel free to invite me anywhere with any amount of notice. You never know what we can work out. Be sure to tell me enough about your invitation to pique my interest!&lt;/p&gt;
&lt;p&gt;See you on the road, which would be a town near you!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/193';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/193&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 07, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 07 Jul 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/193</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Agile Adoption Patterns, the book</title>
      <link>http://jbrains.ca/permalink/192</link>
      <description>&lt;div class='entry posting' id='entry-_posting_192'&gt;
&lt;div class='posting' id='content-_posting_192'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I would like to announce the release of Amr Elssamadisy&amp;#8217;s book &lt;em&gt;Agile Adoption Patterns&lt;/em&gt; on Safari at O&amp;#8217;Reilly. Amr invited me to write a &lt;a href=&quot;http://tinyurl.com/5vc33c&quot;&gt;foreword&lt;/a&gt;, but even if he hadn&amp;#8217;t, I would heartily endorse his book.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/192';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/192&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 03, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 03 Jul 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/192</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>A rare opportunity in September</title>
      <link>http://jbrains.ca/permalink/191</link>
      <description>&lt;div class='entry posting' id='entry-_posting_191'&gt;
&lt;div class='posting' id='content-_posting_191'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Friends, I have been carefully constructing a rather complex travel itinerary for August and September, and one of my prospective clients has gone rather dark on me. As a result, I have ten days of time available that I would like to offer to you at cost. You read that correctly: you can hire me to help your organization between September 1 and September 10 at the unusually low rate of covering reasonable travel costs for Sarah and me. As you might expect, some conditions apply.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;I will be in Amsterdam, Netherlands on August 31 and I need to fly to Chicago, &lt;span class=&quot;caps&quot;&gt;USA&lt;/span&gt; on September 11, so you could hire me in the period in between for up to 9 days, as I&amp;#8217;d prefer to have Monday as slack in our travel schedule.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;I would like to work out a fixed travel budget for our travel expenses, rather than submit receipts.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;We don&amp;#8217;t need a fancy hotel, but prefer someplace with a kitchenette so we can prepare our own meals in the room.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;We need to eat well, so we prefer a hotel near a local market or good-quality grocery store with fresh produce that is either less than a 15-minute walk or easy to reach with public transport.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;I want fun work, which means a multi-disciplinary opportunity, including all aspects of your software delivery system, from the boardroom to the bullpen.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;If prospective client gets back to me by Friday and wants me during this time, then I need to give them priority.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If this interests you, please send email right now to the address in the top-left corner of the page with the subject &amp;#8220;Crazy Joe&amp;#8217;s September 2008 Consulting Special&amp;#8221; or something like that, and I&amp;#8217;ll get back to you.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/191';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/191&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 01, 2008  00:57
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 01 Jul 2008 00:57:40 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/191</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>What I've said so far...</title>
      <link>http://jbrains.ca/permalink/190</link>
      <description>&lt;div class='entry posting' id='entry-_posting_190'&gt;
&lt;div class='posting' id='content-_posting_190'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&amp;#8230;courtesy of &lt;a href=&quot;http://www.wordle.net&quot;&gt;wordle.net&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://wordle.net/gallery/wrdl/28749/jbrains.ca%3A_Can%27t_stop_the_learning%2C_October_2006-June_2008&quot; title=&quot;Wordle: jbrains.ca: Can&amp;#39;t stop the learning, October 2006-June 2008&quot;&gt;&lt;img src=&quot;http://wordle.net/thumb/wrdl/28749/jbrains.ca%3A_Can%27t_stop_the_learning%2C_October_2006-June_2008&quot; style=&quot;padding:4px;border:1px solid #ddd&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/190';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/190&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 25, 2008  03:00
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 25 Jun 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/190</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>On the importance of disciplined software design and the implications of succumbing to poor practice</title>
      <link>http://jbrains.ca/permalink/189</link>
      <description>&lt;div class='entry posting' id='entry-_posting_189'&gt;
&lt;div class='posting' id='content-_posting_189'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&lt;img src=&quot;http://imgs.xkcd.com/comics/goto.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Proceed at your own risk.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/189';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/189&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 24, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 24 Jun 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/189</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Testing the UI: presentation and rendering</title>
      <link>http://jbrains.ca/permalink/188</link>
      <description>&lt;div class='entry posting' id='entry-_posting_188'&gt;
&lt;div class='posting' id='content-_posting_188'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I recently read Jeff Patton&amp;#8217;s column at StickyMinds. &lt;a href=&quot;http://tinyurl.com/44mnmy&quot;&gt;His latest article tells us the secret to automated acceptance tests&lt;/a&gt;. I responded, and I include that response here.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I like this article, Jeff, but I&amp;#8217;d like to point out that programmers can automate more tests in advance without risking a ripple effect when a customer wants to move a field around.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;We know that many designs exhibit high coupling between &amp;#8220;the UI&amp;#8221; and &amp;#8220;the logic&amp;#8221;, and teasing that coupling apart&amp;#8212;mostly moving (business) logic out of the UI&amp;#8212;is one step towards more flexibility, less ripple effect and more valuable automated end-to-end tests. We have all seen it. I invite programmers to take one more step.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Inside &amp;#8220;the UI&amp;#8221; I find two major kinds of code: UI toolkit client code and more general toolkit-neutral code. When I format a monetary amount as &amp;#8220;$12.50&amp;#8221;, I can make that decision without involving the UI toolkit; but when I decide to display the text &amp;#8220;$12.50&amp;#8221; as a label or in a text field, I need to involve the UI toolkit in that decision. I invite programmers to separate their UI into presentation logic (UI toolkit neutral) and rendering logic (UI toolkit specific). If you do this, you will have an &amp;#8220;abstract UI&amp;#8221; or &amp;#8220;presentation layer&amp;#8221; you can test without drawing a real UI. These tests run quickly because they run in memory without having to paint a screen or invoke a UI toolkit component of any kind. You don&amp;#8217;t need end-to-end tests here. When someone decides to move a field around, none of your presentation layer tests need to change, and you avoid the ripple effect. Yes, your end-to-end tests change, but over time you&amp;#8217;ll automate fewer of those, preferring instead to automate the presentation layer tests.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;So programmers, do your worst! Introduce a true presentation layer into your design, starting with the next screen or page. You&amp;#8217;ll thank yourself, and maybe me.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/188';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/188&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 19, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 19 Jun 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/188</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>JUnit Recipes coming soon to Safari Online</title>
      <link>http://jbrains.ca/permalink/187</link>
      <description>&lt;div class='entry posting' id='entry-_posting_187'&gt;
&lt;div class='posting' id='content-_posting_187'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I would like to announce that Manning Publications has begun sending its books to &lt;a href=&quot;http://safari.oreilly.com&quot;&gt;Safari Online, the subscription-based O&amp;#8217;Reilly service&lt;/a&gt;. I have found the service useful over the past three years, particularly after our flood wiped out much of my professional development book collection. If you subscribe to the service, but have not yet read &lt;em&gt;JUnit Recipes&lt;/em&gt;, you will soon have your chance!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/187';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/187&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 18, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/writing&quot;&gt;writing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 18 Jun 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/187</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Fixing Mail.app as it pertains to IMAP and gmail</title>
      <link>http://jbrains.ca/permalink/186</link>
      <description>&lt;div class='entry posting' id='entry-_posting_186'&gt;
&lt;div class='posting' id='content-_posting_186'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I am in the process of making &lt;code&gt;gmail&lt;/code&gt; my One and Only Mail Database. My first tentative steps showed that &lt;code&gt;gmail&lt;/code&gt; filters duplicate emails, which is great, because I have multiple copies of several hundred emails, thanks to &lt;code&gt;POP&lt;/code&gt;. Naively, I just started dragging emails from my other Inboxes to my gmail/&lt;span class=&quot;caps&quot;&gt;IMAP&lt;/span&gt;/personal mail Inbox and letting the messages synchronize on the gmail server. My goal was to make my other &lt;code&gt;Mail.app&lt;/code&gt; accounts empty so I could disable them. This worked well for a while, but for most of today, &lt;code&gt;Mail.app&lt;/code&gt; has been telling me this:&lt;/p&gt;
&lt;pre&gt;Mail has undone actions on some messages
so that you can redo the actions while online.
Mail has saved other messages in mailbox &#8220;INBOX&#8221;
in &#8220;On My Mac&#8221; so that you can complete the 
actions while online.  

Additional information: The attempt to read data 
from the server &#8220;imap.gmail.com&#8221; failed.&lt;/pre&gt;
&lt;p&gt;I read an article or two and figured I&amp;#8217;d overburdened my &lt;code&gt;gmail&lt;/code&gt; server and it was scolding me by limiting my access for a while. When about eight hours passed without any change, I knew I had a problem, and that problem was the same email over and over again. Something about &lt;strong&gt;embroidery&lt;/strong&gt; of all things. Each time the message popped up in my &amp;#8220;On my Mac&amp;#8221; &lt;span class=&quot;caps&quot;&gt;INBOX&lt;/span&gt;, I moved it to Trash, then erased deleted messages&amp;#8230; nothing worked. Finally, out of desperation, I simply pasted the entire message&amp;mdash;you can see it&amp;#8217;s quite long&amp;mdash;into Google.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://forums.macrumors.com/showthread.php?t=396848&quot;&gt;Seek and ye shall find.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The advice there, however, didn&amp;#8217;t impress me. I might not be a &lt;code&gt;Mail.app&lt;/code&gt; developer, but I imagine that if I delete my entire offline cache, I&amp;#8217;ll lose all the emails I moved into my gmail/&lt;span class=&quot;caps&quot;&gt;IMAP&lt;/span&gt;/personal mail inbox. That would be bad, considering it&amp;#8217;s about 10000 messages, many of which matter to me. I thought I should investigate, and fortunately, it wasn&amp;#8217;t too hard to figure out what to do.&lt;/p&gt;
&lt;p&gt;I went to &lt;code&gt;~/Library/Mail/IMAP-[myemailaddress]/.OfflineCache&lt;/code&gt; and saw about 10000 numbered files. I looked at one of them and saw an email. I figured I could &lt;code&gt;grep&lt;/code&gt; to find the offending email, delete it, restart &lt;code&gt;Mail.app&lt;/code&gt;, then all would be well. So I did, and so far it is.&lt;/p&gt;
&lt;p&gt;To be clear, here is what I did:&lt;/p&gt;
&lt;pre&gt;
$ cd ~/Library/Mail/IMAP-****/.OfflineCache
$ ls
1000		1001		1002		1003		1004		1005		1006		1007		1008		1009
1010		1011		1012		1013		1014		1015		1016		1017		1018		1019
1020		1021		1022		1023		1024		1025		1026		1027		1028		1029
....
$ grep -i embroidery *
[...Matched email 854....]
$ rm 854
&lt;/pre&gt;
&lt;p&gt;That worked great. I hope it helps you, too.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/186';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/186&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 11, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/mac&quot;&gt;mac&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/just-to-be-clear&quot;&gt;just to be clear&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 11 Jun 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/186</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Recommended: Pragmatic Screencasts</title>
      <link>http://jbrains.ca/permalink/185</link>
      <description>&lt;div class='entry posting' id='entry-_posting_185'&gt;
&lt;div class='posting' id='content-_posting_185'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I am writing this from a hotel room in Winnipeg on the way to XP 2008 in Limerick, Ireland. Since I live 400 km (that&amp;#8217;s 260 miles for the metric impaired) from Winnipeg and don&amp;#8217;t drive, I typically have to endure a 4.5-hour bus ride at the beginning and end of every trip. You can imagine that I need to keep myself occupied during those stretches, which often involves my trusty iPod Touch. I used this trip to watch my first two &lt;a href=&quot;http://www.pragmatic.tv&quot;&gt;Pragmatic Screencasts&lt;/a&gt; and they impressed me.&lt;/p&gt;
&lt;p&gt;I started to watch a screencast on &lt;a href=&quot;http://expressionengine.com/&quot;&gt;Expression Engine&lt;/a&gt; which I hadn&amp;#8217;t heard of before, but as I get older I find building web sites less interesting, so I am always looking for ways to simplify the task. When I noticed this screencast I thought it would give me an idea whether Expression Engine would interest me as a web site platform. It does. Worse, I wanted to follow along with Ryan Irelan so much that I had to stop the screencast in frustration because I wasn&amp;#8217;t at my computer and connected to the internet. I look forward to returning to that screencast next week, if I can wait that long.&lt;/p&gt;
&lt;p&gt;The other screencast that caught my eye was building a chat system in Erlang. I tried reading the Pragmatic book on Erlang, and while that book receives excellent reviews, I just didn&amp;#8217;t like it. I found it too abstract and didn&amp;#8217;t stick with it. I like the author&amp;#8217;s writing style well enough, but it just felt like I was reading the encyclopedia, rather than a tutorial. I needed an example to follow, and the screencast gave me just that. Kevin Smith builds a tiny chat system before your eyes and does so quite well. I found the screencast very engaging, not just because it illustrated the content and helped me finally begin to understand what Erlang is all about, but also because I found myself wanting to argue with Kevin about coding style, which I always enjoy. I look forward to watch the third episode a little later.&lt;/p&gt;
&lt;p&gt;The quality of the screencasts is high, the production is good and they are a suitable length. Even on the small screen of an iPod Touch I found them easy to follow. I think that Mike Clark has done a very good job so far on both the vision and execution of these screencasts. I hope to do one or two for them sometime soon. (Hint, hint.)&lt;/p&gt;
&lt;p&gt;Go to &lt;a href=&quot;http://www.pragmatic.tv&quot;&gt;http://www.pragmatic.tv&lt;/a&gt; and enjoy. I think you&amp;#8217;ll be very satisfied with the result.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/185';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/185&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 10, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/review&quot;&gt;review&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 10 Jun 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/185</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Mac OS X: choosing the default currency symbol</title>
      <link>http://jbrains.ca/permalink/184</link>
      <description>&lt;div class='entry posting' id='entry-_posting_184'&gt;
&lt;div class='posting' id='content-_posting_184'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;This is just a quick tip for Mac OS X users who might want the symbol &amp;#8220;$&amp;#8221; to represent &lt;em&gt;their&lt;/em&gt; dollar, rather than the US dollar.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve been working on expense reports with Numbers.app and I noticed that my laptop was formatting Canadian and US dollars as &amp;#8220;Can$&amp;#8221; and &amp;#8220;$&amp;#8221;, respectively. While I thought this a tad US-centric, that didn&amp;#8217;t bother me much, so I gave it no real thought until I opened the same spreadsheet on my Mac Mini, where I saw &amp;#8220;$&amp;#8221; and &amp;#8220;US$&amp;#8221; instead. I thought this was neat, except of course that now the columns were the wrong width. I saw the difference, figured there was a difference in the &lt;strong&gt;International&lt;/strong&gt; settings, but no! &lt;a href=&quot;http://www.xs4all.nl/~timkr/chess2/diary_7.htm&quot;&gt;To quote Swiss chess master Gereben&lt;/a&gt;, &amp;#8220;wie ist es m&amp;ouml;glich?!&amp;#8221; The settings are the same, and yet one window has &amp;#8220;Can$&amp;#8221; and the other &amp;#8220;$&amp;#8221;. There is no &amp;#8220;Customize&amp;#8230;&amp;#8221; button, so I can&amp;#8217;t change the number format. What can I do?&lt;/p&gt;
&lt;p&gt;I did what any self-respecting programmer would do: I played around with the settings until it worked. I found out that by switching the currency to something else, then back to &lt;strong&gt;Canadian Dollar&lt;/strong&gt;, I reset the number formatting, and now both computers use &amp;#8220;$&amp;#8221; for real dollars and &amp;#8220;US$&amp;#8221; for the fake kind.&lt;/p&gt;
&lt;p&gt;Now you know.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/184';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/184&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 07, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/mac&quot;&gt;mac&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 07 Jun 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/184</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Death (march) and taxes</title>
      <link>http://jbrains.ca/permalink/183</link>
      <description>&lt;div class='entry posting' id='entry-_posting_183'&gt;
&lt;div class='posting' id='content-_posting_183'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I am late filing my taxes for 2007, which explains why I&amp;#8217;m awake at 5.00 this morning. I&amp;#8217;m not entirely sure how many consecutive mornings I&amp;#8217;ve been waking up earlier and earlier: maybe it&amp;#8217;s six, maybe it&amp;#8217;s seven. My fingers feel a little heavy, I&amp;#8217;ve yawned three times since I opened my computer, and it&amp;#8217;s too dark in here to scan paper, so I decided to write these words.&lt;/p&gt;
&lt;p&gt;Let me tell you a little about my project: I have to file my taxes. Since I have been audited, I no longer trust myself to file my own corporate taxes, so I&amp;#8217;m preparing paperwork for my accountant. My goal is to deliver a &lt;span class=&quot;caps&quot;&gt;DVD&lt;/span&gt; of my data and let my accountant and her staff do a first draft of my taxes while we&amp;#8217;re at XP 2008. When we return, I&amp;#8217;ll be able to answer questions, then I hope to file before June 28 when we have to leave for the next trip. That is the goal, some context and a few constraints, and I think that&amp;#8217;s enough for you to understand me.&lt;/p&gt;
&lt;p&gt;This, dear friends, is a death march. Here is how I know: I have a pile of things to do long enough that I don&amp;#8217;t know how much there is, I don&amp;#8217;t know when I will finish, I don&amp;#8217;t feel like measuring what I&amp;#8217;ve done will help he know how much more time it will take, I have doing this essentially 12-14 hours per day, I have no system for choosing the next task, and I feel like I&amp;#8217;m making up the tasks as I go. As a result of all this, I&amp;#8217;m in here at 5.16 and I don&amp;#8217;t think I&amp;#8217;ll leave here until 22.00, and I need to do this until further notice, and until it&amp;#8217;s done. And oh yes, I can&amp;#8217;t really describe &amp;#8220;done&amp;#8221; precisely, but I&amp;#8217;ll know it when I see it. That all sounds like a death march to me. It&amp;#8217;s not a fun place, so how did I get here?&lt;/p&gt;
&lt;p&gt;A big part of it is fear: I am at the tail end of an audit for the four preceding years, and I don&amp;#8217;t think I&amp;#8217;ve ever felt so much stress in my life. I dealt with my father&amp;#8217;s alcoholic rages better than I&amp;#8217;ve dealt with this audit. I have coped (if you can call it that) mostly by withdrawing from life in general and certainly avoiding anything that looks like financial record-keeping. Of course, I&amp;#8217;ve also spent a lot of time blaming myself for being such a poor accountant, even though my last bit of real accounting training was 1991 in high school. I&amp;#8217;ve been afraid to deal with the audit, and terrified to keep records carefully since about October 2007 or so, and my year end is October 2007. As a result of this fear I have delayed tackling my current taxes, wanting to focus my accountant and tax lawyer on the audit. Only now that the audit is mostly settled have I turned my attention back to the present.&lt;/p&gt;
&lt;p&gt;Another part is incompetence: in 2002 I walked away from my first accountant because I started a full-time job and let my company hibernate indefinitely. On that basis I couldn&amp;#8217;t justify the expense of an accountant. As a result, I hired myself as accountant by default, and while the job wasn&amp;#8217;t very demanding in 2003, I left my full-time job that year to write &lt;em&gt;JUnit Recipes&lt;/em&gt;, which led me to more of the work I&amp;#8217;d wanted to do as an independent, then I started XP Day North America, which introduced me to my current business partner, &amp;#8230; you can see where that&amp;#8217;s headed: more money, more records to keep, more taxes to pay, and more financial information to get wrong. It&amp;#8217;s that incompetence that directly led to the audit and ignorance of a good filing system that has led to the long string of files of paperwork I need to process here. If I were any good at this, not only could I file my taxes sooner, but I probably wouldn&amp;#8217;t have been audited in the first place, and even if I had I would have been confident enough to handle it well.&lt;/p&gt;
&lt;p&gt;As you can see, incompetence and fear play a big role, and not that my incompetence&amp;mdash;at least as far as it has hurt me in this context&amp;mdash;has mostly to do with something I was never trained properly to do! It&amp;#8217;s worth arguing that if I&amp;#8217;d hired someone to do it, I&amp;#8217;d be in better shape, and that &lt;em&gt;that&lt;/em&gt; is the truly incompetent part. I grant that, but part of the reason I didn&amp;#8217;t hire anyone is that I was too ignorant to see that I needed to do it, then once I realized I needed someone, too ashamed of the mistakes I&amp;#8217;d made to let anyone look at them. Fear, incompetence, shame&amp;#8230; I&amp;#8217;m doing really well so far.&lt;/p&gt;
&lt;p&gt;Finally, there are the tangible effects of my fear, incompetence and shame. The audit has contributed to my sinking into a fairly deep depression (and no, not just sadness, believe me), the result of which has been many days spent in bed, rather than taking care of these matters. Every day I went to bed thinking, &lt;em&gt;Tomorrow I&amp;#8217;ll get up, start working on my financial records, and within a couple of weeks, I&amp;#8217;ll have organized everything&lt;/em&gt;, and every morning the first big thought in my head was, &lt;em&gt;Not today!&lt;/em&gt; As a result of this, not only were my 2007 records remaining disorganized, but my incoming paperwork began to create a serious backlog. Even more, I wasn&amp;#8217;t separating the 2007 material from the 2008 material, which is one of the reasons my current work is going so slowly: I first have to figure out whether I need to handle a piece of paper before I handle it. Such waste!&lt;/p&gt;
&lt;p&gt;In addition, as you might expect, I am ignoring my other responsibilities in the name of Getting This Done, but when an urgent request comes up, it completely ruins my flow. My business partner needed me to pay him for some long-outstanding invoices. Nothing huge, but big enough to matter, and because the invoices were months old, I had to wade through old reports, old receipts, and so on, in order to help him. What should have taken 45 minutes took over 3.5 hours and knocked me completely off my rhythm. (I did manage to track down the cause of a $107 credit I had in my books, though: it turns out the credit was my mistake. Big surprise.) Yesterday, after paying him (but not for everything, because I&amp;#8217;m just not that well organized) I had to stop working, even though it was only 17.30, because my mind simply folded up its tent and left. I couldn&amp;#8217;t concentrate at all. I managed to go grocery shopping, but even &lt;em&gt;that&lt;/em&gt; manifested this death march: we usually shop every 2-3 days and carry home 2-4 bags of groceries. Sometimes those bags are pretty heavy, but usually they aren&amp;#8217;t. This time, even though we were leaving the country in 5 days, we carried 5 bags home&amp;mdash;after buying another bag at the store&amp;mdash;and just barely. I don&amp;#8217;t know about Sarah&amp;#8217;s, but my bags were heavy! I was struck by how my work problems were affecting my home life. About the only benefit of staying in my office is that I&amp;#8217;ve mostly avoided working around the contractors finishing up the main floor in our house.&lt;/p&gt;
&lt;p&gt;So it&amp;#8217;s now 5.37 and the sky is brightening despite the rain. Pretty soon I&amp;#8217;ll be able to see enough that I can&amp;#8217;t justify not scanning papers and organizing them. I don&amp;#8217;t know how much I&amp;#8217;ll get done, nor how far along the project that represents, nor when it will be done, nor how to pace myself to finish it. I don&amp;#8217;t yet know whether I&amp;#8217;ll be late and delay my taxes an extra 1-2 weeks as a result, not to mention having this waiting for me when we return from Ireland. I don&amp;#8217;t know much about this project, but I&amp;#8217;m busting my ass on it, and that is what makes it a death march.&lt;/p&gt;
&lt;p&gt;The foregoing is a true story. The names have not been changed. The events are real. I hope you feel a little compassion and even pity for me, even though this is a situation largely of my own creation. I have a question: do you think the causes of your last (or current!) death march are much different? Do you feel compassion and even pity for the people who landed you there?&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/183';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/183&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 04, 2008  12:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/emotional-health&quot;&gt;emotional health&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 04 Jun 2008 12:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/183</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The perfect item for your team room...</title>
      <link>http://jbrains.ca/permalink/182</link>
      <description>&lt;div class='entry posting' id='entry-_posting_182'&gt;
&lt;div class='posting' id='content-_posting_182'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&amp;#8230;if your project is a death march.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://tinyurl.com/53zx64&quot;&gt;&lt;img src=&quot;http://www.blogsmithmedia.com/www.engadget.com/media/2008/05/5-31-08-clock-lighting.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/182';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/182&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 03, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/planning&quot;&gt;planning&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 03 Jun 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/182</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>You're invited! &quot;Test-Driven Enterprise Code&quot; at XP 2008</title>
      <link>http://jbrains.ca/permalink/181</link>
      <description>&lt;div class='entry posting' id='entry-_posting_181'&gt;
&lt;div class='posting' id='content-_posting_181'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Allow me to invite you to &lt;a href=&quot;http://www.xp2008.org&quot;&gt;XP 2008&lt;/a&gt; in Limerick, Ireland on June 11, 2008 at 2 PM local time to join me for &lt;a href=&quot;http://tinyurl.com/3zxxjs&quot;&gt;Test-Driven Enterprise Code&lt;/a&gt;, my long-running tutorial aimed at programmers who want to practise test-driven development in the complicated world of platforms, frameworks, libraries, and more. Stay tuned to this channel for presentation slides, and possibly more.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/181';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/181&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 01, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/xp2008&quot;&gt;xp2008&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 01 Jun 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/181</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Rescuing disk space from Parallels</title>
      <link>http://jbrains.ca/permalink/179</link>
      <description>&lt;div class='entry posting' id='entry-_posting_179'&gt;
&lt;div class='posting' id='content-_posting_179'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I use Parallels to run Windows under my MacBook Pro which has a 93 GiB hard disk. Since I also live a flight away from the nearest authorized Apple reseller, I find it difficult to buy a new hard disk whenever I need one. These reasons form the constraints under which I spent much of a recent afternoon reclaiming disk space, rather than focusing on real work. Since I have more than a neophyte&amp;#8217;s, but less than an expert&amp;#8217;s, knowledge of &lt;span class=&quot;caps&quot;&gt;UNIX&lt;/span&gt;, I needed to look up the command to show me how to ask &lt;span class=&quot;caps&quot;&gt;UNIX&lt;/span&gt; how much disk space folders used. I invoked this command&lt;/p&gt;
&lt;pre&gt;$ du -h -d 1&lt;/pre&gt;
&lt;p&gt;This command tells me how much space each immediate folder (&lt;code&gt;-d 1&lt;/code&gt; means &amp;#8220;depth of one&amp;#8221;) takes up in human-readable (&lt;code&gt;-h&lt;/code&gt;) form. This gave me a report like the following&lt;/p&gt;
&lt;pre&gt;....other folders....
 24M	./Applications
 24K	./bin
7.3M	./Desktop
2.5G	./Documents
....yet other folders....&lt;/pre&gt;
&lt;p&gt;Since I want to focus on the really big folders, I looked for a way to do that. I decided to &lt;code&gt;grep&lt;/code&gt; for a &amp;#8220;G&amp;#8221; in the fourth position.&lt;/p&gt;
&lt;pre&gt;mel:~ jbrains$ du -d 1 -h | grep ^...G.*$
2.5G	./Documents
 20G	./Library
1.0G	./Movies
5.8G	./Music
3.3G	./Pictures
3.3G	./Workspaces
 36G	.&lt;/pre&gt;
&lt;p&gt;Since I plan to use this command frequently, I added it to &lt;code&gt;~/.profile&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;alias find_big_folders=&quot;du -d 1 -h | grep ^...G.*$&quot;&lt;/pre&gt;
&lt;p&gt;I found that &lt;code&gt;Library&lt;/code&gt; took up the most space, and within it &lt;code&gt;Parallels&lt;/code&gt; took up over 20 GiB on its own. I searched the web and learned that Parallels has a &amp;#8220;Compressor Tool&amp;#8221; that compresses hard disk images, but when I tried to use it, it failed, telling me I had snapshots or had enabled &amp;#8220;disk undo&amp;#8221;. Since neither condition held true, I searched further and saw that Parallels has a long-standing defect (back to July 2007 at least) that causes this problem. Fortunately, the same search gave me a solution: &lt;strong&gt;MakeVM&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://tinyurl.com/4tcadw&quot;&gt;MakeVM&lt;/a&gt; creates disk images for Parallels and VMWare, and although it cost &lt;span class=&quot;caps&quot;&gt;USD&lt;/span&gt; 19.99, it appeared to solve my problem, so I decided to try it. I installed it on the Windows XP image running under Parallels and found the &amp;#8220;Custom Clone&amp;#8221; feature ridiculously easy to use. Since I had no experience with this tool and wanted to recover from each step, I did the following&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Back up my entire Parallels virtual machine image by &lt;code&gt;tar&lt;/code&gt;-ing it to an external disk.&lt;/li&gt;
	&lt;li&gt;Back up my second Parallels hard disk image (&lt;code&gt;disk2.hdd&lt;/code&gt;).&lt;/li&gt;
	&lt;li&gt;Choose &amp;#8220;Custom Clone&amp;#8221; under MakeVM to clone my second hard drive (not the &amp;#8220;Virtual Hard Disk&amp;#8221; feature, which wants to clone a hard disk image), writing the clone to my external hard disk, since I had little space on the internal disk. &lt;strong&gt;When asked whether I wanted to compact the cloned disk, I naturally chose &amp;#8220;yes&amp;#8221;.&lt;/strong&gt;&lt;/li&gt;
	&lt;li&gt;Shut down my virtual Windows XP.&lt;/li&gt;
	&lt;li&gt;Edit the Windows XP virtual machine settings, removing the existing &amp;#8220;Hard Disk 2&amp;#8221; image and adding the newly-cloned disk image as &amp;#8220;Hard Disk 2&amp;#8221;. Windows XP should treat these disks as identical.&lt;/li&gt;
	&lt;li&gt;Start my virtual Windows XP and judge the results. Although I had to re-install Java to make Eclipse work, everything else appeared all right.&lt;/li&gt;
	&lt;li&gt;Shut down my virtual Windows XP.&lt;/li&gt;
	&lt;li&gt;Remove the old Hard Disk 2 image from my internal disk and copy the newly-cloned Hard Disk 2 image to my internal disk, updating the virtual machine preferences accordingly.&lt;/li&gt;
	&lt;li&gt;Back up my entire Windows XP virtual machine image again, repeating the rest of the process for Hard Disk 1.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This entire process took about a half day, so it helped that I had another computer in the room on which to continue working. Once I completed the process, my Windows XP virtual machine image folder reduced in size from about 22 GiB to its current 9.2 GiB. That rectified my disk space problems. I now have over 16 GiB of breathing room, which means I don&amp;#8217;t have to upgrade my hard disk, but rather I can wait to upgrade my entire machine. That makes me happy.&lt;/p&gt;
&lt;p&gt;If you have disk space problems, or even if you simply want to save disk space, and you run Parallels or VMWare, I recommend &lt;a href=&quot;http://tinyurl.com/4tcadw&quot;&gt;MakeVM&lt;/a&gt; to safely compact your disk images. I found it well worth the &lt;span class=&quot;caps&quot;&gt;USD&lt;/span&gt; 19.99 I paid for it. If this helps you, then please use the &amp;#8220;Discuss&amp;#8221; link below to comment.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/179';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/179&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 30, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/mac&quot;&gt;mac&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 30 May 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/179</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>A reason for a relative lack of congruence in the world</title>
      <link>http://jbrains.ca/permalink/180</link>
      <description>&lt;div class='entry posting' id='entry-_posting_180'&gt;
&lt;div class='posting' id='content-_posting_180'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Just a little something to think about&amp;#8230;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;From a writer&#8217;s point of view, congruent interactions aren&#8217;t very dramatic; people just act sensibly, are considerate of one another, get their work done, and enjoy what they&#8217;re doing. That kind of behavior might not make as good a soap opera scene as your manager throwing a tantrum and you cringing in the corner, but it definitely makes a better project.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;From Jerry Weinberg, &lt;a href=&quot;http://www.ayeconference.com/beyondblaming/&quot;&gt;Beyond Blaming.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/180';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/180&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 29, 2008  16:07
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 29 May 2008 16:07:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/180</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Mercurial, Python, Mac OS X and duplication</title>
      <link>http://jbrains.ca/permalink/178</link>
      <description>&lt;div class='entry posting' id='entry-_posting_178'&gt;
&lt;div class='posting' id='content-_posting_178'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;As you all know, I&amp;#8217;m not a fan of duplication. When we duplicate code we create safe, warm places for defects to hide. The more we duplicate, the more things go wrong, the harder they are to debug and, most importantly, &lt;strong&gt;the more we need to know in order to find the root cause of the problem&lt;/strong&gt;. (In particular, we need to know we&amp;#8217;ve duplicated something and where it is duplicated.) Just to emphasize that this is not some arcane theoretical notion about programming, allow me to share with you an adventurous half-hour I just spent trying to get &lt;code&gt;mercurial&lt;/code&gt; (or &lt;code&gt;hg&lt;/code&gt;, if you like) to play nicely between my MacBook Pro and my Mac Mini.&lt;/p&gt;
&lt;p&gt;I have a working copy of a Mercurial forest in the same place on two different computers, one is my MacBook Pro and the other is my Mac Mini. When I have to do book-keeping work, I often use the laptop for handling paper and my desktop for running QuickBooks. This helps me avoid overworking either computer and that slowing me down. At least, this is my &lt;em&gt;intent&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Since I&amp;#8217;m using &lt;code&gt;hg&lt;/code&gt;, by its nature a decentralized version control system, I have to be sure to keep my two working copies synchronized. This means periodic &lt;code&gt;push&lt;/code&gt; operations from the laptop to the desktop or &lt;code&gt;pull&lt;/code&gt; operations to the desktop from the laptop, depending on which keyboard happens to be in front of me at the moment. Since &lt;code&gt;push&lt;/code&gt; from here to there and &lt;code&gt;pull&lt;/code&gt; from here to there are essentially the same operation, it stands to reason that I should be able to do either one equally well.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://tinyurl.com/ywdnoe&quot; title=&quot;Not so fast, mah littel pink frend&quot; alt=&quot;Not so fast, mah littel pink frend&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I could &lt;code&gt;push&lt;/code&gt; from the laptop, but not &lt;code&gt;pull&lt;/code&gt; from the desktop. I was getting this error:&lt;/p&gt;
&lt;pre&gt;hobbes:Operations jbrains$ hg incoming ssh://mel.local/Workspaces/DiasparSoftwareServices/Operations
remote: Traceback (most recent call last):
remote:   File &quot;/usr/local/bin/hg&quot;, line 11, in &amp;lt;module&amp;gt;
remote:     from mercurial import demandimport; demandimport.enable()
remote: ImportError: No module named mercurial
abort: no suitable response from remote hg!&lt;/pre&gt;
&lt;p&gt;After some searching, I came across an article that suggested I had an &lt;code&gt;ssh&lt;/code&gt; problem, and since I hadn&amp;#8217;t swapped keys from the desktop to the laptop yet, I did that, hoping it would magically solve the problem. It did not. It saved me typing my password for each &lt;code&gt;pull&lt;/code&gt; or &lt;code&gt;incoming&lt;/code&gt; operation, but &lt;a href=&quot;http://tinyurl.com/49oa9w&quot;&gt;what other value it has, I don&amp;#8217;t know.&lt;/a&gt; I had to search on.&lt;/p&gt;
&lt;p&gt;After a few more minutes, I found &lt;a href=&quot;http://tinyurl.com/4t2j9p&quot;&gt;this article&lt;/a&gt;, which suggested to me that my &lt;code&gt;PYTHONPATH&lt;/code&gt; or &lt;code&gt;PATH&lt;/code&gt; was wrong. I compared the environment variables on both computers and that wasn&amp;#8217;t the problem. I compared the locations of Mercurial on both computers with a quick &lt;code&gt;which hg&lt;/code&gt; and they were the same. I was beginning to think that I just didn&amp;#8217;t know enough about installing Python packages to make this work, but then I asked each computer to &lt;code&gt;locate mercurial&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Aha!&lt;/p&gt;
&lt;p&gt;The laptop answered &lt;code&gt;/usr/local/lib/python2.5/site-packages&lt;/code&gt; and the desktop answered &lt;code&gt;/Library/Python/2.5/site-packages&lt;/code&gt; and &lt;strong&gt;there it is&lt;/strong&gt;: the two environments expect Python packages in different places. I bet some symbolic links will do the trick.&lt;/p&gt;
&lt;p&gt;On the desktop, I did this:&lt;/p&gt;
&lt;pre&gt;/usr/local/lib jbrains$ sudo ln -s /Library/Python/2.5 python2.5&lt;/pre&gt;
&lt;p&gt;Now when someone looks for Python packages in the usual &lt;span class=&quot;caps&quot;&gt;UNIX&lt;/span&gt; place (&lt;code&gt;/usr/local/lib/python2.5), the file system points them to the usual Mac OS place (&lt;/code&gt;/Library/Python/2.5@). I&amp;#8217;m not thrilled about two different conventions, but as long as I can make one be like the other, it&amp;#8217;s all good.&lt;/p&gt;
&lt;p&gt;On the laptop, however, I found a defect as a result of duplication. I found Python libraries both in &lt;code&gt;/usr/local/lib/python2.5&lt;/code&gt; and in &lt;code&gt;/Library/Python/2.5&lt;/code&gt;. It&amp;#8217;s a wonder anything Python works correctly in that environment. &lt;strong&gt;This is the defect I fixed today&lt;/strong&gt;. I moved the Python libraries into the usual Mac OS place (&lt;code&gt;/Library/Python/2.5&lt;/code&gt;) before adding the same symbolic link that I&amp;#8217;d added on the desktop.&lt;/p&gt;
&lt;p&gt;And yes, folks, now it all just works. Mostly because now there&amp;#8217;s only one place for Python libraries to live on each computer.&lt;/p&gt;
&lt;p&gt;If you remove duplication, you don&amp;#8217;t just improve the design, but you remove places defects can hide.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/178';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/178&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 29, 2008  03:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/mac&quot;&gt;mac&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 29 May 2008 03:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/178</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>If you defer the decision long enough...</title>
      <link>http://jbrains.ca/permalink/177</link>
      <description>&lt;div class='entry posting' id='entry-_posting_177'&gt;
&lt;div class='posting' id='content-_posting_177'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&amp;#8230;then someone might implement the feature for you. In surfing around, I recently found out about creating &amp;#8220;subreddits&amp;#8221;, which are subdomains of &lt;code&gt;reddit.com&lt;/code&gt;. I learned this when I saw Joel Spolsky&amp;#8217;s weblog had a &amp;#8220;Discuss&amp;#8221; link that submitted the item to &lt;code&gt;joel.reddit.com&lt;/code&gt; instead of hosting comments on his own weblog. I think this is a good idea, so you&amp;#8217;ll notice that I&amp;#8217;ve done the same here. This is especially helpful, given that in order to add comments to this weblog, I either have to build the feature myself or migrate my content to TextPattern or one of its ilk.&lt;/p&gt;
&lt;p&gt;The next time someone insists you need a doubtful feature, ask them to choose something more important first. By the time you get to the doubtful feature, you might have discovered that someone&amp;#8217;s built it for you!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/177';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/177&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 07, 2008  05:39
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 07 May 2008 05:39:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/177</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The post-iteration demo: practice or anti-pattern?</title>
      <link>http://jbrains.ca/permalink/176</link>
      <description>&lt;div class='entry posting' id='entry-_posting_176'&gt;
&lt;div class='posting' id='content-_posting_176'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;The standard, universal data processing answer is &amp;#8220;it depends&amp;#8221;. Specifically, it depends on the ongoing participation of your stakeholders.&lt;/p&gt;
&lt;p&gt;If the development team is demonstrating the application at the end of the iteration to the stakeholders, then that&amp;#8217;s an anti-pattern. If you&amp;#8217;re not getting any constructive criticism from the stakeholders about the demonstration, then the stakeholders are likely not engaged by the demonstration, and it&amp;#8217;s a waste of time. If your stakeholders are engaged, then they&amp;#8217;re likely giving a sizable amount of constructive criticism, the result of which is re-working a substantial number of stories in the next iteration. Of course, you could just be &lt;em&gt;that&lt;/em&gt; good, but I haven&amp;#8217;t met that team yet.&lt;/p&gt;
&lt;p&gt;The last time I worked with a team in this situation, they held demonstrations once per iteration, which for them meant every two weeks. They expressed to me that they were not getting feedback soon enough, so I asked them whether they thought weekly demonstrations would work better. They did, they asked the stakeholders to make at least two people available every Friday afternoon, and that worked. After a while, they added a Wednesday morning demonstration just before lunch. The next step would be daily demonstrations, then finally continuous stakeholder participation. The secret was to sneak up on the daily demonstrations.&lt;/p&gt;
&lt;p&gt;Rather than ask your stakeholder to go from hands-off to daily meetings, hold demonstrations once per iteration. When they point out how much feedback causes rework, suggest having a mid-iteration demonstration to avoid so much rework. You might be able to fix a small problem or two right in front of the stakeholders, and if you can, then do. (It looks impressive.) Once you&amp;#8217;ve established that you can fix some problems without putting the stakeholders to sleep, they&amp;#8217;re more likely to want to work directly with you. Each time they notice a demonstration leads to substantial rework, suggest doubling the frequency of the demonstrations. Eventually you&amp;#8217;ll arrive at the right amount of stakeholder participation for your project. The key is to &lt;strong&gt;let your stakeholders notice the problem of not enough feedback&lt;/strong&gt;, because if it&amp;#8217;s their problem, they might look for solutions, but if it&amp;#8217;s your problem, they&amp;#8217;re less likely to care. If they can&amp;#8217;t see it&amp;#8217;s their problem, then look for subtle, non-destructive ways to make it their problem.&lt;/p&gt;
&lt;p&gt;My goal is for a key stakeholder and the development team to demonstrate the product &lt;em&gt;together&lt;/em&gt; to any and all interested parties. This is an important step towards the &lt;strong&gt;whole team&lt;/strong&gt; approach to building software that I find so incredibly effective.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/176';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/176&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 30, 2008  15:36
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 30 Apr 2008 15:36:05 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/176</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>When you're the bottleneck...</title>
      <link>http://jbrains.ca/permalink/175</link>
      <description>&lt;div class='entry posting' id='entry-_posting_175'&gt;
&lt;div class='posting' id='content-_posting_175'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I remember being a technical lead, believing that it was my job to make sure everything was doing correctly and as quickly as possible. The result was predictable: I made myself a bottleneck because I was afraid to delegate important tasks to other people, for fear that they&amp;#8217;d do it poorly and have to redo it, or even simply because it would take me less time to do it than to explain to someone else how to do it. I know now that letting myself be a bottleneck is a bad idea, but I wasn&amp;#8217;t able to explain why very well until just a moment ago when a long-awaited neural connection finally happened. I almost felt the crackle in my brain at the point of impact.&lt;/p&gt;
&lt;p&gt;Tim Ottinger wrote about &lt;a href=&quot;http://www.butunclebob.com/ArticleS.TimOttinger.SoonerNotFaster&quot;&gt;Sooner, Not Faster&lt;/a&gt;, which I describe to people frequently in my work as a consultant. My goal in teaching test-driven development is not to help programmers write code more quickly, but rather to help them deliver solid code sooner. The time-saving techniques include being clear about what to build before trying to build it (write a failing test first), building only what you need (write just enough code to pass the test), stopping when you&amp;#8217;ve built enough (continue until you can&amp;#8217;t think of more failing tests to write), and keeping the code clean as you go to avoid building up inventory of uncompleted necessary work (&amp;#8220;clean the kitchen&amp;#8221; refactoring). Not all these techniques involve thinking or typing more quickly. Some involve thinking more to type less and knowing what&amp;#8217;s enough then stopping. In general, I help teams by focusing on how to deliver a satisfactory result sooner, no matter how fast or slow the individual tasks are completed.&lt;/p&gt;
&lt;p&gt;Now I wish I&amp;#8217;d thought that way as a technical lead. If I have a backlog of 10 tasks that take a total of 4 weeks to complete, but I could delegate some of those tasks to others, then even if they take 5 times as long as I do to complete those tasks, I could delegate any task up to 3 days in length and, as a group, we could be done in 3 weeks, even if we spend more total time working. The alternative is to keep those tasks for myself, then have the others do busywork to avoid looking idle. You might think this is a false alternative, but how many people on your team are working on its top three priorities, and how many are working on other things? The other things are busywork!&lt;/p&gt;
&lt;p&gt;Had I thought this way, I could have benefited dramatically. More important work would have been completed, I&amp;#8217;d have learned how to delegate effectively, and I would have felt (and probably now feel) less stress.&lt;/p&gt;
&lt;p&gt;If only.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/175';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/175&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 28, 2008  15:22
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 28 Apr 2008 15:22:13 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/175</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>New review of JUnit Recipes</title>
      <link>http://jbrains.ca/permalink/174</link>
      <description>&lt;div class='entry posting' id='entry-_posting_174'&gt;
&lt;div class='posting' id='content-_posting_174'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;It&amp;#8217;s nice to see that nearly five years after I started writing &lt;a href=&quot;http://tinyurl.com/4p3vp8&quot;&gt;&lt;em&gt;JUnit Recipes&lt;/em&gt;&lt;/a&gt;, &lt;a href=&quot;http://tinyurl.com/42f8w3&quot;&gt;people continue to read and review it&lt;/a&gt;. I imagined it would have become obsolete by now, especially with the proliferation of Java 5, Java 6 and JUnit 4.&lt;/p&gt;
&lt;p&gt;The review ends with &amp;#8220;If you use JUnit as your test tool and if you do any of the &#8216;things&#8217; covered in the contents list of recipes then I recommend getting hold of this book.&amp;#8221; I appreciate it.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/174';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/174&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 20, 2008  16:05
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/review&quot;&gt;review&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 20 Apr 2008 16:05:04 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/174</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Quick guideline for using experimentation as an aid for decision making</title>
      <link>http://jbrains.ca/permalink/173</link>
      <description>&lt;div class='entry posting' id='entry-_posting_173'&gt;
&lt;div class='posting' id='content-_posting_173'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;An anonymous person at &lt;code&gt;blog.isnotworking.com&lt;/code&gt; whose name I could not find on the site has written a &lt;a href=&quot;http://blog.isnotworking.com/2008/03/quick-guideline-for-using.html&quot;&gt;short piece&lt;/a&gt; on helping teams avoid getting stuck arguing over different solutions to a given problem. It was inspired by my November/December 2007 article in &lt;span class=&quot;caps&quot;&gt;IEEE&lt;/span&gt; Software Magazine.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.isnotworking.com/2008/03/quick-guideline-for-using.html&quot;&gt;http://blog.isnotworking.com/2008/03/quick-guideline-for-using.html&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/173';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/173&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 20, 2008  15:57
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 20 Apr 2008 15:57:33 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/173</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Five Mistakes New Agile Teams Make</title>
      <link>http://jbrains.ca/permalink/172</link>
      <description>&lt;div class='entry posting' id='entry-_posting_172'&gt;
&lt;div class='posting' id='content-_posting_172'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I recently had the honor of speaking at the &lt;a href=&quot;http://www.phillyemergingtech.com/&quot;&gt;Emerging Technologies for the Enterprise Conference&lt;/a&gt;, where I renewed some friendships, made some new acquaintances, and spoke about something I enjoy: failures.&lt;/p&gt;
&lt;p&gt;Last summer I debuted &lt;a href=&quot;http://tinyurl.com/2hl6zv&quot;&gt;&lt;em&gt;XP: My Greatest Misses 2000-2007&lt;/em&gt;&lt;/a&gt;, which became popular due to its honesty and directness. (See &lt;a href=&quot;http://tinyurl.com/yspy9v&quot;&gt;an example&lt;/a&gt; of the response to it.) I followed this theme of reflecting on failures to gather some mistakes I have seen people make as they make the transition from work group in chaos to agile team. It&amp;#8217;s important to note that I didn&amp;#8217;t talk about the five biggest mistakes, the five most common, nor the five most dangerous; but rather, simply about five mistakes that came to my head. As you&amp;#8217;d expect, once I&amp;#8217;d written my five in &lt;a href=&quot;http://articles.jbrains.ca/FiveMistakesNewAgileTeamsMake-handout.pdf&quot;&gt;the notes&lt;/a&gt;, I found a number more, especially as I sat in my fellow presenters&amp;#8217; sessions. Even when they weren&amp;#8217;t describing mistakes at all, they triggered a number of memories&amp;mdash;so many that I could easily have written the &lt;strong&gt;20&lt;/strong&gt; mistakes new agile teams make.&lt;/p&gt;
&lt;p&gt;Please enjoy &lt;a href=&quot;http://articles.jbrains.ca/FiveMistakesNewAgileTeamsMake-handout.pdf&quot;&gt;Five Mistakes New Agile Teams Make&lt;/a&gt;, and if you&amp;#8217;d like me to visit your user group, please contact me at the prominently-displayed e-mail address on this site. You should also consider contacting the &lt;a href=&quot;http://www.agilealliance.org&quot;&gt;Agile Alliance&lt;/a&gt; to find out how to qualify for funding to bring out-of-town speakers to your user group or event.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/172';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/172&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 01, 2008  16:52
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 01 Apr 2008 16:52:44 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/172</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>A clear violation of the Single Responsibility Principle</title>
      <link>http://jbrains.ca/permalink/171</link>
      <description>&lt;div class='entry posting' id='entry-_posting_171'&gt;
&lt;div class='posting' id='content-_posting_171'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;(From &lt;a href=&quot;http://xkcd.com/387&quot;&gt;&lt;span class=&quot;caps&quot;&gt;XKCD&lt;/span&gt;&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://imgs.xkcd.com/comics/advanced_technology.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Should a class be a factory for itself?&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/171';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/171&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
February 25, 2008  22:27
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 25 Feb 2008 22:27:12 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/171</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>McCabe Complexity and Design</title>
      <link>http://jbrains.ca/permalink/170</link>
      <description>&lt;div class='entry posting' id='entry-_posting_170'&gt;
&lt;div class='posting' id='content-_posting_170'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Another in the Enerjy TV series. This time, the question is &amp;#8220;How do you believe McCabe Complexity helps programmers?&amp;#8221;&lt;/p&gt;
&lt;p&gt;&lt;embed src=&quot;http://blip.tv/play/Aai1Lg&quot; type=&quot;application/x-shockwave-flash&quot; width=&quot;480&quot; height=&quot;360&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/170';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/170&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
February 11, 2008  19:44
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 11 Feb 2008 19:44:04 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/170</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Is excellent design &quot;too Eastern&quot; for us?</title>
      <link>http://jbrains.ca/permalink/169</link>
      <description>&lt;div class='entry posting' id='entry-_posting_169'&gt;
&lt;div class='posting' id='content-_posting_169'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have spent the last two days with &lt;a href=&quot;http://www.poppendieck.com&quot;&gt;Mary and Tom Poppendieck&lt;/a&gt; at one of their Practitioners Courses, and I find myself inspired. Among the interesting moments for me was a point at which I reached an unsettling notion: are we &amp;#8220;too Western&amp;#8221; to design software well?&lt;/p&gt;
&lt;p&gt;I came to this question while watching course attendees talk about the problems in their organization. As they explored the flow of value through their IT organizations, I kept hearing about managers interrupting the flow and of centralized decision-makers as bottlenecks, when it occurred to me: I&amp;#8217;ve heard about these problems in code before.&lt;/p&gt;
&lt;p&gt;Specifically, I heard the word &amp;#8220;manager&amp;#8221; and my mind wandered towards thinking of &lt;code&gt;Manager&lt;/code&gt; classes in a code base, rather than flesh-and-blood managers. In that wandering instant I saw a connection between the two kinds of managers: human managers have mostly commonly been trained over the last century to micro-manage, make important decisions and direct their people; and &lt;code&gt;Manager&lt;/code&gt; classes do essentially the same thing in code. Now, while our ideas of management have changed in the past 50 years, mostly due to the work coming out of Toyota, we are still over-run by micro-managers whose effectiveness is limited.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s quite similar with code. In spite of the object-oriented design movement and the advance of test-driven development with its emphasis on simple design, procedural thinking dominates, even in code bases that use object-oriented languages. Most programmers approach code with Procedural Mind, even when they believe they want to design with objects. Even when I teach people how their can arrive at excellent designs by following four simple rules, Procedural Mind dominates.&lt;/p&gt;
&lt;p&gt;So I wonder: given the parallels between tactical, command-and-control management and highly procedural code where important decisions are centralized in these &lt;code&gt;Manager&lt;/code&gt; classes, and given that our most common human management style is a relic of western military thinking, and given that it perpetuates in part due to culturally-entrenched ideas about managing people, are Western programmers conditioned against excellent design? Are we mostly doomed to gather our code in &lt;code&gt;Manager&lt;/code&gt; classes, rather than distribute responsibilities evenly and focus on object interaction?&lt;/p&gt;
&lt;p&gt;Are those notions simply too Eastern for us?&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/169';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/169&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 17, 2008  01:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/personality-types&quot;&gt;personality types&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 17 Jan 2008 01:00:41 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/169</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Backpack helps me change my habits</title>
      <link>http://jbrains.ca/permalink/168</link>
      <description>&lt;div class='entry posting' id='entry-_posting_168'&gt;
&lt;div class='posting' id='content-_posting_168'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I use &lt;a href=&quot;http://tinyurl.com/28c9u6&quot;&gt;Backpack&lt;/a&gt; to help me change my habits for the better, and I wanted to share this little technique with you.&lt;/p&gt;
&lt;p&gt;The programmer in me values version control systems because they allow me to keep an indefinite record of what I&amp;#8217;ve done. If something goes wrong while I&amp;#8217;m working, then I can go back to an old version of a file and continue working. This is why I use Mercurial every day.&lt;/p&gt;
&lt;p&gt;The entrepreneur in me values off-site backups because if a fire destroys my office, then all I need is any computer and an internet connection and I can get back to work. This is why I use Amazon S3 every day.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;http://tinyurl.com/242oel&quot;&gt;scanner&lt;/a&gt; in me values &lt;a href=&quot;http://tinyurl.com/2jdbbb&quot;&gt;getting things done&lt;/a&gt;, because when commitments start to sneak up on me, I have my commitments, actions and priorities in one place, and I can get back on track. This is why I use &lt;a href=&quot;http://www.omnigroup.com/applications/omnifocus/&quot;&gt;OmniFocus&lt;/a&gt; every day.&lt;/p&gt;
&lt;p&gt;What I&amp;#8217;ve noticed, though, is that my tasks aren&amp;#8217;t really getting done. For me, most tasks require building or changing some key assets. Sometimes that&amp;#8217;s code, or expense receipts, or drafts of an article. It&amp;#8217;s not good enough to write the article, I want to put it into version control and know it&amp;#8217;s backed up off site. It&amp;#8217;s natural for me to end a coding session by committing changes to Mercurial, but it&amp;#8217;s not yet natural for me to end a non-coding work session the same way. I need to remind myself to do this.&lt;/p&gt;
&lt;p&gt;Whenever I hear myself think or say, &amp;#8220;I need to remind myself&amp;#8230;&amp;#8221; I immediately log in to &lt;a href=&quot;http://tinyurl.com/28c9u6&quot;&gt;Backpack&lt;/a&gt;, because it does such a great job of reminding me of things. Today, I added a reminder that reads&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A task isn&amp;#8217;t done until the assets are safe: under version control and backed up&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I set the reminder for tomorrow, and every day after that, until the idea is burned into my brain and becomes second nature. I&amp;#8217;m not sure how long that&amp;#8217;ll take, but by this time next month, I should be able to switch that reminder to every month, just to make sure it doesn&amp;#8217;t fall completely off my radar.&lt;/p&gt;
&lt;p&gt;This is how &lt;a href=&quot;http://tinyurl.com/28c9u6&quot;&gt;Backpack&lt;/a&gt; helps me move away from bad habits and move towards better habits.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/168';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/168&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 04, 2008  17:22
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/planning&quot;&gt;planning&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/being-a-scanner&quot;&gt;being a scanner&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/emotional-health&quot;&gt;emotional health&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 04 Jan 2008 17:22:41 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/168</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Forget velocity</title>
      <link>http://jbrains.ca/permalink/167</link>
      <description>&lt;div class='entry posting' id='entry-_posting_167'&gt;
&lt;div class='posting' id='content-_posting_167'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;What does velocity measure?&lt;/p&gt;
&lt;p&gt;First, let&amp;#8217;s be clear: by velocity, I mean story points delivered per iteration over time. Of course, that means we need more definitions, so let me get those out of the way now.&lt;/p&gt;
&lt;p&gt;&amp;#8220;A story point&amp;#8221; is a unit that programmers invent solely to make it easier to estimate the work it takes to deliver a story. A story point is however big the programmers decide it is, no more, and no less. Story points are useful to the extent that they help programmers compare the effort required to deliver different stories, so that the team can decide how many stories to commit to delivering in a given iteration. Although story points necessarily fluctuate in value, one hopes that over a sufficiently short span of time &amp;#8211; say the length of a release &amp;#8211; the fluctuation is small enough that a constant approximation of velocity is helpful enough to plan the release.&lt;/p&gt;
&lt;p&gt;&amp;#8220;Delivered&amp;#8221; means realizing (in the accounting sense) the value the customer intended to realize by asking the team to work on the story. A story is not delivered until it either reduces cost or generates revenue.&lt;/p&gt;
&lt;p&gt;&amp;#8220;Iteration&amp;#8221; means equal-length time boxes the goal of which is to provide natural breaks in daily work to reconsider the plan and stop work from expanding indefinitely. On teams that have less trouble stopping when they&amp;#8217;ve done enough, iterations are less important.&lt;/p&gt;
&lt;p&gt;&amp;#8220;Over time&amp;#8221; refers to the trend of spot measurements over at least the length of a release.&lt;/p&gt;
&lt;p&gt;I hope that makes it crystal clear what I mean by velocity. Now that I&amp;#8217;ve clarified the meaning of velocity, what does it measure? It simply aggregates past estimates of effort of a set of stories the team selected to complete in the last several iterations. That doesn&amp;#8217;t sound like much, does it? There&amp;#8217;s more. Here are some things that velocity does not measure:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;productivity&lt;/li&gt;
	&lt;li&gt;efficiency&lt;/li&gt;
	&lt;li&gt;value&lt;/li&gt;
	&lt;li&gt;suitability to re-hire or retain&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;#8230;and, of course, past performance does not guarantee future results. Read your prospectus before investing. If velocity is so meaningless, then why measure it? Well, it turns out that:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;It is a good approximation (accurate about 2 times in 3, we think) of what the team can commit to in the next iteration&lt;/li&gt;
	&lt;li&gt;It is a good approximation (we think) of what the team can commit to over the next handful of iterations (say 4-6)&lt;/li&gt;
	&lt;li&gt;It is a good approximation of when the current stack of work we&amp;#8217;ve identified will be done, as long as the stack of work isn&amp;#8217;t too large (up to about 4-6 iterations&amp;#8217; worth)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have just witnessed a conversation on the &lt;code&gt;extremeprogramming&lt;/code&gt; Yahoo! group that illustrates the knots in which we tie ourselves when we allow ourselves to be too imprecise about what a measurement measures. The whole thing puts me in mind of personal financing and when budgets don&amp;#8217;t work.&lt;/p&gt;
&lt;p&gt;Think about budgeting your expenses at home: you know how much you actually pay for some expenses, like car payments, mortgage or rent, insurance&amp;#8230; the amounts you owe are usually spread out over such a long period that you can anticipate what you&amp;#8217;ll owe next month with certainty. Moreover, you know that it takes concerted effort on someone&amp;#8217;s part, or human error, to change the amount you owe on a mortgage, car loan or your home insurance. Changes in those amounts, at least correct ones, generally don&amp;#8217;t sneak up on you.&lt;/p&gt;
&lt;p&gt;There are other expenses that vary from month to month: food, clothing, entertainment, communications&amp;#8230; the amounts you owe usually depend on how much of a given resource you consume, such as how much you eat, how much you talk on the phone and how stressful your work is that month. You can budget these amounts fairly accurately, because the variation is low enough and mostly under your control: you can choose to eat less, take better care of your clothes, read more library books and rent fewer movies. Not only is it easier to guess what you&amp;#8217;ll spend in a given month, but if you start spending too much, you can easily correct course to spend less.&lt;/p&gt;
&lt;p&gt;There are still other expenses that you just can&amp;#8217;t foresee. You are injured in an accident and rack up $20k in hospital bills; this is the year out of the last ten that you finally need new shingles on the roof; you find out your son needs braces. You might buy insurance as a way of smoothing out the costs over time, but they are generally big expenses that you know are coming in the larger sense, but which arrives without warning and needs to be paid immediately.&lt;/p&gt;
&lt;p&gt;These are the expenses that make budgeting not work, because they prove that there&amp;#8217;s no such thing as a typical month. This is also why you cannot rely on velocity to plan far ahead: there is no such thing as a typical project or even a typical iteration. If velocity doesn&amp;#8217;t bring a project under control, then what might? For an answer, I invite you to consider personal finance again.&lt;/p&gt;
&lt;p&gt;I read &lt;a href=&quot;http://tinyurl.com/2sclhd&quot;&gt;Your Money or Your Life&lt;/a&gt; to help me bring my personal finances under control and become financially free. One of the key exercises the book asked me to perform was to track all money coming in and out of our household for several months. This exercise is designed to call attention to our spending habits, so we can decide what to do about them. In particular, we identified those expenses we valued and those we didn&amp;#8217;t value, so we could stop spending money on things we don&amp;#8217;t value. This tactic, spending money only on things we value, doesn&amp;#8217;t necessarily make one rich, but it ensures that one is not wasting money on things one doesn&amp;#8217;t actually value. You&amp;#8217;d be surprised how much money we were throwing away on things that didn&amp;#8217;t ultimately make our lives any better, and you&amp;#8217;d be amazed at the results when we stopped: we used that money as capital to generate passive income, and within five years, we&amp;#8217;ve become financially free. But I digress. The point is what we measured, then how we analyzed it.&lt;/p&gt;
&lt;p&gt;We measured actual spending, rather than estimated future spending or even estimated past spending. When we had the numbers, we didn&amp;#8217;t start slashing expenses we cared about, and we didn&amp;#8217;t start looking for cheaper alternatives to all our expenditures. Instead, we simply looked for those expenses we did not value, then cut them off. In some cases, this required investment of money: we bought a coffee grinder, an AeroPress, then started brewing coffee at home, rather than spending $2 per on coffee at our local coffee shop. In some cases, this required investment of time: we reviewed our work commitments and changed the way we work so that we wouldn&amp;#8217;t be so tired so often, which meant we no longer &amp;#8220;needed&amp;#8221; to order dinner in as often as we did. We measured our actual spending, we looked at those numbers to identify waste, then we eliminated it. We did not waste effort staring at our budget, wondering how accurate it was, wondering how realistic it was, desperately trying to spread not enough money over too many expenses. We didn&amp;#8217;t have to: we had actual expense numbers and could decide which items we valued and which we didn&amp;#8217;t. More to the point, this exercise was far more instructive and effective than budgeting ever was.&lt;/p&gt;
&lt;p&gt;Does your company value the areas where your software team spends its money? Do you know how to measure the value of what your team produces? How much money (time, energy, or actual cash) does your team spend on things no-one values? Could you pick three such wastes and eliminate them? What would you do with the recovered time, energy, or cash? How would you know that things got any better?&lt;/p&gt;
&lt;p&gt;Forget velocity for the time being. Measure it and report it to whoever still wants it, but just between you and me, forget velocity and focus on these key questions. Try it for a few months. Share with us what happens. I&amp;#8217;d love to hear from you.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/167';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/167&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 03, 2008  00:08
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/stories&quot;&gt;stories&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/planning&quot;&gt;planning&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/emotional-health&quot;&gt;emotional health&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 03 Jan 2008 00:08:56 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/167</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Happy New Year</title>
      <link>http://jbrains.ca/permalink/166</link>
      <description>&lt;div class='entry posting' id='entry-_posting_166'&gt;
&lt;div class='posting' id='content-_posting_166'&gt;
&lt;div style='text-align: justify'&gt;
&lt;pre&gt;
describe &quot;Year 2008&quot; do
    it &quot;should be happy&quot; do
        Date.new(2008, 1, 1).year.should be_happy
    end
end
&lt;/pre&gt;
&lt;p&gt;Best wishes to all my readers for a happy 2008!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/166';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/166&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 02, 2008  03:33
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/adventures-in-RSpec&quot;&gt;adventures in RSpec&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/emotional-health&quot;&gt;emotional health&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 02 Jan 2008 03:33:27 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/166</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Stub your worries away</title>
      <link>http://jbrains.ca/permalink/165</link>
      <description>&lt;div class='entry posting' id='entry-_posting_165'&gt;
&lt;div class='posting' id='content-_posting_165'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I recently came across this question on the &lt;code&gt;testdrivendevelopment&lt;/code&gt; Yahoo! group.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hi everyone,&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d like some advice/opinions on how to test some existing code. It&amp;#8217;s a web&lt;br /&gt;
application using Spring and struts.&lt;/p&gt;
&lt;p&gt;I have a class called the ProcessedFilesManager which contains a number of&lt;br /&gt;
methods used by Struts Action classes. This manager communicates with five&lt;br /&gt;
different DAOs to get the information that some of the Struts actions are&lt;br /&gt;
interested in. Now, I want to test this manager class&lt;br /&gt;
(ProcessedFilesManager). The way I&amp;#8217;ve started doing it is stubbing up each&lt;br /&gt;
of the five DAOs, however, this is proving to be quite painful. I didn&amp;#8217;t&lt;br /&gt;
want to use a mocking approach, nor did I want to use a DB solution like&lt;br /&gt;
Hypersonic, but now I&amp;#8217;m open to suggestions.&lt;/p&gt;
&lt;p&gt;Seeing as there a number of approaches I could use, what do you think would&lt;br /&gt;
be best for this situation?&lt;/p&gt;
&lt;p&gt;It feels wrong to stub the DAOs because what if I&amp;#8217;m introducing behaviour in&lt;br /&gt;
there that differs from the actual DAOs? My tests will not be accurate.&lt;/p&gt;
&lt;p&gt;Any advice/comments would be much appreciated.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://tech.groups.yahoo.com/group/testdrivendevelopment/message/27079&quot;&gt;Read the thread&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I used to have this fear, and I do something now that has eliminated that fear.&lt;/p&gt;
&lt;p&gt;When I stub a &lt;span class=&quot;caps&quot;&gt;DAO&lt;/span&gt; method, I make an assumption about what that &lt;span class=&quot;caps&quot;&gt;DAO&lt;/span&gt; method does. I used to be worried about making the wrong assumption, but now I have a contract test for the &lt;span class=&quot;caps&quot;&gt;DAO&lt;/span&gt; interface that tests for the assumption I&amp;#8217;m making in my Service test. The contract test gives me confidence that any implementation of the &lt;span class=&quot;caps&quot;&gt;DAO&lt;/span&gt; method passes the same tests, so every implementation of that &lt;span class=&quot;caps&quot;&gt;DAO&lt;/span&gt; method behaves the way I assume it does. Once I have this, I feel comfortable stubbing that &lt;span class=&quot;caps&quot;&gt;DAO&lt;/span&gt; method that way in a Service test.&lt;/p&gt;
&lt;p&gt;A contract test is a test for an interface. I describe contract tests in some detail in &lt;a href=&quot;http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;amp;location=http%3A%2F%2Fwww.amazon.com%2FJUnit-Recipes-Practical-Methods-Programmer%2Fdp%2F1932394230%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1199051730%26sr%3D8-1&amp;amp;tag=masterprogram-20&amp;amp;linkCode=ur2&amp;amp;camp=1789&amp;amp;creative=9325&quot;&gt;JUnit Recipes&lt;/a&gt;, recipe 2.6, although back then I called them &amp;#8220;abstract test cases&amp;#8221; because I hadn&amp;#8217;t yet discovered the better name &amp;#8220;contract test&amp;#8221;. If you prefer, I&amp;#8217;ve provided a diagram showing some contract tests for a typical &lt;span class=&quot;caps&quot;&gt;DAO&lt;/span&gt; class.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/StubYourWorriesAway/ContractTests.jpg&quot; style=&quot;width: 100%; align: center;&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Since classes inherit methods from their superclasses, the &lt;code&gt;Hibernate Customer DAO Test&lt;/code&gt; will inherit the &lt;em&gt;contract tests&lt;/em&gt; from its superclass, as will the &lt;code&gt;JDBC Customer DAO Test&lt;/code&gt;. This means that each implementation has to pass not only its own tests (like &lt;code&gt;testClosesSession()&lt;/code&gt; or &lt;code&gt;testClosesResultSet()&lt;/code&gt;) but also the tests inherited from &lt;code&gt;Customer DAO Contract Test Template&lt;/code&gt;. (I call it a &amp;#8220;template&amp;#8221; because it plays the role of template in the Template Method design pattern.) When you test-drive a new implementation of &lt;code&gt;Customer DAO&lt;/code&gt;, simply make the new test extend the contract test template and you&amp;#8217;ll automatically inherit its contract tests. This way, I have confidence that any implementation of &lt;code&gt;Customer DAO&lt;/code&gt; behaves the way I&amp;#8217;d expect any &lt;code&gt;Customer DAO&lt;/code&gt; to behave.&lt;/p&gt;
&lt;p&gt;Returning to our example, these contract tests give me confidence to stub the &lt;span class=&quot;caps&quot;&gt;DAO&lt;/span&gt; when I test-drive the Service, and that confidence brings with it a happy side effect. I am confident that &lt;code&gt;findAllWithPendingOrders()&lt;/code&gt; only returns customers with pending orders, so I don&amp;#8217;t have to worry about that issue at all when I design the Service that reports all customers with pending orders. Now that I notice it, &lt;code&gt;Report All Customers With Pending Orders Service&lt;/code&gt; is really just a &lt;code&gt;Report on Customers Service&lt;/code&gt; that needs a &lt;code&gt;Customer Filter&lt;/code&gt;, which could be a &lt;code&gt;Pending Orders Customer Filter&lt;/code&gt;. I don&amp;#8217;t think I would have felt comfortable with this level of generalization if I weren&amp;#8217;t so confident in the way I&amp;#8217;ve separated the responsibilities.&lt;/p&gt;
&lt;p&gt;The next time you want to avoid stubbing a method because you&amp;#8217;re worried you&amp;#8217;ll make a wrong assumption about what the method does, try writing enough contract tests to give you the confidence you need. I think you&amp;#8217;ll like the results.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/165';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/165&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 30, 2007  22:37
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 30 Dec 2007 22:37:25 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/165</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Interested in what interests me?</title>
      <link>http://jbrains.ca/permalink/164</link>
      <description>&lt;div class='entry posting' id='entry-_posting_164'&gt;
&lt;div class='posting' id='content-_posting_164'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I&amp;#8217;m starting to tag more stuff with del.icio.us, so if you think you might find interesting what I find interesting, then add &lt;a href=&quot;http://del.icio.us/rss/jbrains762&quot;&gt;http://del.icio.us/rss/jbrains762&lt;/a&gt; to your favorite &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt; feed reader.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/164';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/164&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 30, 2007  20:57
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 30 Dec 2007 20:57:04 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/164</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Why are companies slow to adopt metrics programs?</title>
      <link>http://jbrains.ca/permalink/163</link>
      <description>&lt;div class='entry posting' id='entry-_posting_163'&gt;
&lt;div class='posting' id='content-_posting_163'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Another in the series of videos from Enerjy in which my fellow conference speakers and I answered the question, &amp;#8220;Why are companies slow to adopt metrics programs?&amp;#8221;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;&lt;OBJECT WIDTH=&quot;400&quot; HEIGHT=&quot;255&quot;&gt;&lt;PARAM NAME=&quot;movie&quot; VALUE=&quot;http://blip.tv/scripts/flash/showplayer.swf?enablejs=true&amp;amp;file=http%3A//blip.tv/rss/flash/569926&amp;amp;feedurl=http%3A//enerjy.blip.tv/rss/&amp;amp;autostart=false&amp;amp;brandname=Enerjy%20TV&amp;amp;brandlink=http%3A//enerjy.blip.tv/&quot;&gt;&lt;br /&gt;
&lt;PARAM NAME=&quot;quality&quot; VALUE=&quot;best&quot;&gt;&lt;OBJECT WIDTH=&quot;400&quot; HEIGHT=&quot;255&quot;&gt;&lt;PARAM NAME=&quot;movie&quot; VALUE=&quot;http://blip.tv/scripts/flash/showplayer.swf?enablejs=true&amp;amp;file=http%3A//blip.tv/rss/flash/569926&amp;amp;feedurl=http%3A//enerjy.blip.tv/rss/&amp;amp;autostart=false&amp;amp;brandname=Enerjy%20TV&amp;amp;brandlink=http%3A//enerjy.blip.tv/&quot;&gt;&lt;br /&gt;
&lt;PARAM NAME=&quot;quality&quot; VALUE=&quot;best&quot;&gt;&lt;EMBED src=&quot;http://blip.tv/scripts/flash/showplayer.swf?enablejs=true&amp;amp;file=http%3A//blip.tv/rss/flash/569926&amp;amp;feedurl=http%3A//enerjy.blip.tv/rss/&amp;amp;autostart=false&amp;amp;brandname=Enerjy%20TV&amp;amp;brandlink=http%3A//enerjy.blip.tv/&quot; WIDTH=&quot;400&quot; HEIGHT=&quot;255&quot; TYPE=&quot;application/x-shockwave-flash&quot;&gt;&lt;/EMBED&gt;&lt;p&gt;&lt;/OBJECT&gt;&lt;/notextile&gt;&lt;/p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/163';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/163&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 30, 2007  18:34
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 30 Dec 2007 18:34:09 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/163</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Which agile practice most benefits programmers?</title>
      <link>http://jbrains.ca/permalink/162</link>
      <description>&lt;div class='entry posting' id='entry-_posting_162'&gt;
&lt;div class='posting' id='content-_posting_162'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Thanks to Richard Sharpe for interviewing me at Agile Development Practices Conference 2007 in Orlando, Florida. This is the first in a series of short videos about agile software practice.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;&lt;OBJECT WIDTH=&quot;400&quot; HEIGHT=&quot;255&quot;&gt;&lt;PARAM NAME=&quot;movie&quot; VALUE=&quot;http://blip.tv/scripts/flash/showplayer.swf?enablejs=true&amp;amp;file=http%3A//blip.tv/rss/flash/536952&amp;amp;feedurl=http%3A//enerjy.blip.tv/rss/&amp;amp;autostart=false&amp;amp;brandname=Enerjy%20TV&amp;amp;brandlink=http%3A//enerjy.blip.tv/&quot;&gt;&lt;br /&gt;
&lt;PARAM NAME=&quot;quality&quot; VALUE=&quot;best&quot;&gt;&lt;EMBED src=&quot;http://blip.tv/scripts/flash/showplayer.swf?enablejs=true&amp;amp;file=http%3A//blip.tv/rss/flash/536952&amp;amp;feedurl=http%3A//enerjy.blip.tv/rss/&amp;amp;autostart=false&amp;amp;brandname=Enerjy%20TV&amp;amp;brandlink=http%3A//enerjy.blip.tv/&quot; WIDTH=&quot;400&quot; HEIGHT=&quot;255&quot; TYPE=&quot;application/x-shockwave-flash&quot;&gt;&lt;/EMBED&gt;&lt;/OBJECT&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/162';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/162&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 29, 2007  00:13
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 29 Dec 2007 00:13:14 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/162</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>&quot;Agile People Still Don't Get It&quot;?</title>
      <link>http://jbrains.ca/permalink/159</link>
      <description>&lt;div class='entry posting' id='entry-_posting_159'&gt;
&lt;div class='posting' id='content-_posting_159'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I ran across C&amp;eacute;dric Beust&amp;#8217;s article &lt;a href=&quot;http://beust.com/weblog/archives/000392.html&quot;&gt;Agile People Still Don&amp;#8217;t Get It&lt;/a&gt; again, and I just wanted to point one little thing out for you, for him, for everyone. He writes about a presentation he attended that illustrated why agile people still don&amp;#8217;t get it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One of the first slides that deeply troubled me claimed the following: Tests are (executable) specs; (and) If it&amp;#8217;s not testable, it&amp;#8217;s useless.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;C&amp;eacute;dric went on to show a number of examples of algorithms that aren&amp;#8217;t worth test-driving and useful code that isn&amp;#8217;t testable. All very good, all understood, all makes sense; but all in his acerbic, off-putting style.&lt;/p&gt;
&lt;p&gt;C&amp;eacute;dric, I love you like a brother, but this Bileblog nonsense is wearing thin. We&amp;#8217;re not 21 any more; and it&amp;#8217;s time to reach a wider audience of more thoughtful people through sensible and reasonable discourse. I&amp;#8217;m afraid that, in this case, your conclusion does not at all follow from the hypothesis.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s true that there is a steady supply of agile evangelists out there that push agile like a religion, but not only is none of this is news, but it&amp;#8217;s a natural part of the evolution of any idea. I went through my proselytizing phase. It was at a time when my primary concern was getting to practice agile, and I thought that if more people liked it, more people would give me the chance to practice it. Instead, I started taking myself more seriously as a business person, &lt;a href=&quot;http://www.weliveherenow.net&quot;&gt;made more money&lt;/a&gt;, and that has translated to more free time to practice whatever I want to practice. This allowed me to feel more secure about my own agile practice and my own effectiveness as both a practitioner and consultant. Not everyone takes the lead in their careers like I did, so when you see someone lashing out, proselytizing, don&amp;#8217;t hate them, but help them. There&amp;#8217;s something missing in their lives, and it&amp;#8217;s worth offering them a chance to find out what it is and fill the void. People did that for me, and I&amp;#8217;m willing to do that for others. Are you?&lt;/p&gt;
&lt;p&gt;On the question of the agile religion, you might think &lt;a href=&quot;http://tinyurl.com/2b7rug&quot;&gt;Bob Martin&lt;/a&gt; is one of the High Priests of Agile, but as early as 2002 (!) he warned us about this behavior, and I take away two key points from his message. I believe it was at a dinner talk at XP/Agile Universe 2002 that he invited us &lt;strong&gt;not to make absolute statements about agile&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Those absolute statements served us well to rile up the visionaries (in the &lt;a href=&quot;http://tinyurl.com/23ceak&quot;&gt;Crossing the Chasm&lt;/a&gt; sense), but as we reach the mainstream, statements like these hurt more than they help. I prefer to tell people that the more they test, the better their features are; and the more testable their features are, the more easily maintained they are. They seem to respond to that, especially when I &lt;strong&gt;show&lt;/strong&gt; them how that is. I still astonish people, as &lt;a href=&quot;http://tinyurl.com/3e4dbg&quot;&gt;unexpectedness is a key component of a sticky message&lt;/a&gt;, but I prefer not to use divisive, absolute rhetoric to do that. I use different techniques for that now.&lt;/p&gt;
&lt;p&gt;I believe it&amp;#8217;s become more important to be less overtly provocative, and instead be clearer with our advice. I don&amp;#8217;t think most thoughtful agilists will claim that they write production code the way they teach others to do it; but this is not a simple case of &amp;#8220;do as I say, but not as I do&amp;#8221;, but rather a case of the student needing to learn the lessons by following some useful rules before leaning too much on under-developed judgment. Not everyone agrees that we should give &lt;a href=&quot;http://tinyurl.com/2j4o66&quot;&gt;novice rules&lt;/a&gt; to novices, but it works well for me, so I do it. This means that I sometimes tell people &amp;#8220;delete that code because it isn&amp;#8217;t tested&amp;#8221; or &amp;#8220;stop and refactor the code until it&amp;#8217;s testable&amp;#8221;. I find it an effective way to help them learn and develop judgment, the skills I believe will serve them best. I tell my students directly:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Do I take tiny steps like this every time I write code? No. Do I think you should take tiny steps like this when you write code? Yes. Why? Not because it&amp;#8217;s the best way to write software, but because you learn a lot when you do it and, more importantly, when it&amp;#8217;s 2 AM, you&amp;#8217;ve been called back from vacation, you&amp;#8217;re performing surgery on a production system that&amp;#8217;s losing $100,000 per hour of downtime, you&amp;#8217;ll be glad you can work in such small steps.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;More succinctly, I&amp;#8217;m more up-front with people about the pedagogical aspects of what I do. They seem to respond well to that, rather than patting them on the head and saying, &amp;#8220;No, trust me, just write the tests. You&amp;#8217;ll learn.&amp;#8221; &lt;em&gt;I&amp;#8217;m sure there are plenty of trainers out there, agile and otherwise, who treat their students like children, rather than adults.&lt;/em&gt; They make absolute statements of the type that C&amp;eacute;dric is right to complain about. I just wish he wouldn&amp;#8217;t make it seem like a uniquely agile problem, and I wish he wouldn&amp;#8217;t lump us all in one bucket. I suppose it&amp;#8217;s convenient to do that, but it&amp;#8217;s not true.&lt;/p&gt;
&lt;p&gt;In fact, it feels downright religious to do so.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/159';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/159&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 28, 2007  14:59
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/writing&quot;&gt;writing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/personality-types&quot;&gt;personality types&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/emotional-health&quot;&gt;emotional health&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 28 Dec 2007 14:59:45 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/159</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>A user-friendly tool for Mercurial?</title>
      <link>http://jbrains.ca/permalink/158</link>
      <description>&lt;div class='entry posting' id='entry-_posting_158'&gt;
&lt;div class='posting' id='content-_posting_158'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;This is an open request for help. I&amp;#8217;ve started using Mercurial as my version control system of choice, and I&amp;#8217;d like to start sharing controlled documents with a business user. Now this person is relatively sophisticated as a business user, but he&amp;#8217;s not a programmer, so I sense he wouldn&amp;#8217;t be comfortable using the &lt;code&gt;hg&lt;/code&gt; command-line tool. I&amp;#8217;ve asked him, but in the interim, I&amp;#8217;m looking for a potential solution to a problem I anticipate having. Can anyone recommend a tool that wraps around &lt;code&gt;hg&lt;/code&gt; suitable for a business user? Something with buttons that don&amp;#8217;t say &amp;#8220;update&amp;#8221;, &amp;#8220;commit&amp;#8221;, &amp;#8220;push&amp;#8221;, and &amp;#8220;pull&amp;#8221;, but sensible business user equivalents? I would prefer not to build one myself, so if someone out there wants a nice exercise, I have one for them!&lt;/p&gt;
&lt;p&gt;I appreciate any help. Write to us at info &lt;strong&gt;anAtSign&lt;/strong&gt; diasparsoftware &lt;strong&gt;possiblyADot&lt;/strong&gt; com.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/158';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/158&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 24, 2007  10:19
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 24 Dec 2007 10:19:29 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/158</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Dynamic test doubles and brittle tests</title>
      <link>http://jbrains.ca/permalink/157</link>
      <description>&lt;div class='entry posting' id='entry-_posting_157'&gt;
&lt;div class='posting' id='content-_posting_157'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Just a quick one. I&amp;#8217;ll write the proof later.&lt;/p&gt;
&lt;p&gt;People commonly complain to me that when they try to test-drive code with test doubles (say with JMock), they end up with brittle tests: when the code changes, all these tests change. I understand, because it used to be that way for me, too. Nowadays, it doesn&amp;#8217;t cause me a problem, and I believe it&amp;#8217;s because my interfaces tend to stabilize quickly, and I believe &lt;em&gt;that&lt;/em&gt; happens because my interfaces tend to be minimal with appropriately-distributed behaviors. How did I get to design so well?&lt;/p&gt;
&lt;p&gt;When JMock told me my tests were brittle, I changed my design so that the tests were more robust. The result, as a side effect, was smaller, more cohesive interfaces and less coupling between classes and their collaborators.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/157';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/157&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 19, 2007  19:02
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 19 Dec 2007 19:02:09 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/157</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>(Omni)Focus on what matters now!</title>
      <link>http://jbrains.ca/permalink/156</link>
      <description>&lt;div class='entry posting' id='entry-_posting_156'&gt;
&lt;div class='posting' id='content-_posting_156'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p style=&quot;float:left;&quot;&gt;&lt;img src=&quot;http://images.jbrains.ca/OmniFocus/GroupByPurpose.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 5px;&quot;&gt;In the process of learning to use &lt;a href=&quot;http://tinyurl.com/3yrfjb&quot;&gt;OmniFocus&lt;/a&gt; to &lt;a href=&quot;http://tinyurl.com/27553n&quot;&gt;Get Things Done&lt;/a&gt;, I have changed the way I group projects into folders. I started by grouping projects by purpose. I later realized why OmniFocus doesn&amp;#8217;t have task priority: it has project priority built in, just by moving projects around in the Projects view.&lt;/p&gt;
&lt;p style=&quot;float:right;&quot;&gt;&lt;img src=&quot;http://images.jbrains.ca/OmniFocus/GroupByUrgency.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p style=&quot;margin: 5px;&quot;&gt;This made me think that I should throw away most of my task due dates, which I&amp;#8217;ve done, and replace &amp;#8220;which task to do next&amp;#8221; with &amp;#8220;what are the next actions in my projects&amp;#8221;. This encourages me to prioritize projects, rather than simply dump them into the Projects view and, perhaps, collect them by related purpose. Now, I group projects by &amp;#8220;urgency&amp;#8221;, which I happen to measure in how happy they make me: do they take care of me? do they generate more passive income? do they help me spend more time with cool people?&lt;/p&gt;
&lt;p&gt;Incidentally, notice that I wanted to hide some of the information in the &amp;#8220;urgency&amp;#8221; picture, but not in the &amp;#8220;purpose&amp;#8221; picture. That&amp;#8217;s a clue in itself about what I should really be working on: the stuff I don&amp;#8217;t want you to know about until I release it. :)&lt;/p&gt;
&lt;p&gt;So if you have found that your projects list has grown out of control, maybe you should re-prioritize your projects and group them by urgency, rather than purpose. You could even hide the &amp;#8220;not important, not urgent&amp;#8221; projects and look at them only during a periodic review.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/156';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/156&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 18, 2007  15:25
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/planning&quot;&gt;planning&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/personality-types&quot;&gt;personality types&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/being-a-scanner&quot;&gt;being a scanner&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/emotional-health&quot;&gt;emotional health&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 18 Dec 2007 15:25:09 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/156</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>How I got Rails working on Leopard</title>
      <link>http://jbrains.ca/permalink/155</link>
      <description>&lt;div class='entry posting' id='entry-_posting_155'&gt;
&lt;div class='posting' id='content-_posting_155'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I hope this helps someone. After installing Leopard, I had some repair work to do. Here is a summary of what I&amp;#8217;ve done.&lt;/p&gt;
&lt;p&gt;First, &lt;code&gt;ruby&lt;/code&gt; and &lt;code&gt;gem&lt;/code&gt; both worked, which made me happy.&lt;/p&gt;
&lt;p&gt;Next, I re-created the usual directories in &lt;code&gt;/usr/local&lt;/code&gt; to install software there. My intention &lt;em&gt;was&lt;/em&gt; to install &lt;code&gt;ruby&lt;/code&gt; there by building it from source, but I ran into problems I just didn&amp;#8217;t feel like trying to solve, so instead, I decided to stick with the stuff that Apple shipped with Leopard.&lt;/p&gt;
&lt;p&gt;I use PostgreSQL, so I needed to re-build and re-install that. Since my TextDrive server uses v8.0.x, I decided to install a version from the same minor release level, which was 8.0.14. I downloaded that from &lt;a href=&quot;http://www.postgresql.org/ftp/source/v8.0.14&quot;&gt;here&lt;/a&gt; and installed it with the usual commands:&lt;/p&gt;
&lt;pre&gt;
./configure
make
sudo make install
&lt;/pre&gt;
&lt;p&gt;This installed PostgreSQL into &lt;code&gt;/usr/local/pgsql/*&lt;/code&gt;. I then added some configuration to &lt;code&gt;/etc/profile&lt;/code&gt; to make PostgreSQL available on the system path.&lt;/p&gt;
&lt;pre&gt;
PGHOME=/usr/local/pgsql
export PATH=/usr/local/bin:/usr/local/sbin:$PGHOME/bin:$PATH
export PGDATA=$PGHOME/data
&lt;/pre&gt;
&lt;p&gt;After re-starting my shell, I could use the PostgreSQL utilities, so I then initialized the data directory. Since I use the user &lt;code&gt;postgres&lt;/code&gt; to manage my databases, I initialized&lt;/p&gt;
&lt;pre&gt;
sudo mkdir /usr/local/pgsql/data
sudo chown -R postgres /usr/local/pgsql/data
su - postgres
initdb /usr/local/pgsql/data
exit
&lt;/pre&gt;
&lt;p&gt;Next on the list was installing the &lt;code&gt;postgres&lt;/code&gt; gem, which I learned how to do &lt;a href=&quot;http://blog.invisible.ch/2007/10/28/rails-stack-on-leopard/&quot;&gt;here&lt;/a&gt;. With that done, I could try running one of my Rails applications again. Of course, I couldn&amp;#8217;t do that as my normal user &lt;code&gt;jbrains&lt;/code&gt; because of this&lt;/p&gt;
&lt;pre&gt;
mel:jbrains.info jbrains$ createdb weblog_development
createdb: could not connect to database template1: FATAL:  user &quot;jbrains&quot; does not exist
&lt;/pre&gt;
&lt;p&gt;I want to be able to drop and create databases as &lt;code&gt;jbrains&lt;/code&gt; to make it easier to run tests through &lt;code&gt;rake&lt;/code&gt;, so I added the user in PostgreSQL.&lt;/p&gt;
&lt;pre&gt;
su - postgres
mel:~ postgres$ createuser -a -d -P jbrains
Enter password for new user: 
Enter it again: 
CREATE USER
exit
&lt;/pre&gt;
&lt;p&gt;Next I created my Rails development database and migrated it to the current schema version. Finally, I could run the legacy tests and my new specs.&lt;/p&gt;
&lt;pre&gt;
createdb weblog_development
rake db:migrate
rake test
rake spec
&lt;/pre&gt;
&lt;p&gt;In the process, &lt;code&gt;rake&lt;/code&gt; identified some missing gems, which I installed and froze to the project. After that, I could resume work on my Rails projects. I&amp;#8217;m keeping an eye on &lt;a href=&quot;http://codefluency.com/2007/10/27/some-leopard-ruby-notes&quot;&gt;this space&lt;/a&gt; for instructions on building Ruby on Leopard.&lt;/p&gt;
&lt;p&gt;I would like to thank heartily all the people who published instructions to help me get back to this point relatively quickly. I don&amp;#8217;t know what I&amp;#8217;d do without you guys. If you ever meet me, remind me that I owe you a beer.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/155';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/155&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 11, 2007  05:56
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 11 Dec 2007 05:56:27 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/155</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>JUnit is just opinionated software</title>
      <link>http://jbrains.ca/permalink/154</link>
      <description>&lt;div class='entry posting' id='entry-_posting_154'&gt;
&lt;div class='posting' id='content-_posting_154'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;In the process of discussing the TestNG/JUnit distinction with Willem van den Ende, I came to the realization that JUnit is simply another example of opinionated software. If JUnit had been released in 2006, after Rails had made opinionated software fashionable, I doubt there would be the same kind of backlash. More people might have been prepared to try to learn the lessons JUnit tries to teach.&lt;/p&gt;
&lt;p&gt;Again, I want to be clear: I don&amp;#8217;t care whether you use JUnit or TestNG. I merely wish to point out that I let JUnit and my &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; practice teach me a few things about design that have served me very well in the intervening seven years.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/154';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/154&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 09, 2007  15:24
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 09 Dec 2007 15:24:08 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/154</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Definitely not a book review: Next Generation Java Testing</title>
      <link>http://jbrains.ca/permalink/153</link>
      <description>&lt;div class='entry posting' id='entry-_posting_153'&gt;
&lt;div class='posting' id='content-_posting_153'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I want to be clear: I have not yet read &lt;a href=&quot;http://tinyurl.com/yrl7uv&quot;&gt;Next Generation Java Testing&lt;/a&gt;, C&amp;eacute;dric Beust&amp;#8217;s book about TestNG. I am not writing this to make a comment about the quality of C&amp;eacute;dric&amp;#8217;s book one way or the other; however, the first reader&amp;#8217;s comment put me in mind of a conversation I had at Better Software&amp;#8217;s Agile Development Practices conference about TestNG v. JUnit, C&amp;eacute;dric v. J. B., and all that good stuff. In that conversation I reached what I felt at the time was an insightful conclusion. This might be obvious to some, but it&amp;#8217;s significant to me. I now firmly believe I know the source of our differences, between JUnit and TestNG, between C&amp;eacute;dric and me.&lt;/p&gt;
&lt;p&gt;TestNG is about testing. JUnit is about design.&lt;/p&gt;
&lt;p&gt;Once I reached this conclusion, any notion of one tool being better than the other has absolutely no relevance. A while ago, I proposed that TestNG and JUnit were complementary in the sense that TestNG was more about end-to-end testing and JUnit was more about object testing. I now see that as a false division. If you write tests to do primarily validation or verification, then maybe you should use TestNG, because its features fit better for a testing focus. If you write tests in order to explore design ideas concretely, then maybe you should use JUnit, because its features fit better for a design focus. (Of course, since &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; is &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; done well with less cognitive load to the learner, Java people doing &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; could use JUnit if they didn&amp;#8217;t mind calling them &amp;#8220;fixtures&amp;#8221; and &amp;#8220;tests&amp;#8221;.)&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/153';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/153&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 09, 2007  15:04
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 09 Dec 2007 15:04:06 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/153</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Book review: Behind Closed Doors</title>
      <link>http://jbrains.ca/permalink/152</link>
      <description>&lt;div class='entry posting' id='entry-_posting_152'&gt;
&lt;div class='posting' id='content-_posting_152'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I&amp;#8217;ve never been a manager, but if I became one, I know where I&amp;#8217;d turn for advice. Johanna Rothman and Esther Derby&amp;#8217;s excellent new book, &lt;em&gt;Behind Closed Doors&lt;/em&gt; is the first management guide I&amp;#8217;ve read that makes me feel like I could learn to be an excellent manager. It even makes me want to try to be a manager, something I swore I&amp;#8217;d never undertake. I have spent most of my career seeing managers as an obstacle to doing good work, but Johanna and Esther have painted me a picture of a manager that is an ally, not an obstacle. If nothing else, &lt;em&gt;Behind Closed Doors&lt;/em&gt; gives me hope for managers and their reports everywhere. But it&amp;#8217;s not just a fairy tale&amp;#8212;it&amp;#8217;s a practical guide to manager/report harmony.&lt;/p&gt;
&lt;p&gt;One important step &lt;em&gt;Behind Closed Doors&lt;/em&gt; takes is to both show respect for managers and hold them accountable for their own performance. Rather than simply advocating for managers as unappreciated people, it identifies what good managers ought to do, then guides the reader to do it. Instead of siding with managers against &amp;#8220;those annoying reports&amp;#8221;, Johanna and Esther emphasize what their readers can do to develop better working relationships with everyone around them. When I think about the managers I have respected throughout my career, I realize that they already do some of the important things that &lt;em&gt;Behind Closed Doors&lt;/em&gt; recommends.&lt;/p&gt;
&lt;p&gt;The authors also make the point of using systems thinking to solve problems. Not only is this approach highly effective, but it encourages managers to view their environment holistically, rather than focusing on their direct reports, their manager, their turf, and nothing else. It encourages the managers to be better citizens at work, and this can only rub off on the people around them, creating lasting positive change. That&amp;#8217;s quite an accomplishment, compared to other books for managers.&lt;/p&gt;
&lt;p&gt;Most helpful are the 35 pages of specific guidelines and techniques the reader can start using right away to improve their communication, to both plan and manage their projects and to bring spiraling problems back under control. There are even plenty of examples of what &lt;em&gt;not&lt;/em&gt; to do, which are effective teaching in their own right. No management book can promise to make managing easy, but &lt;em&gt;Behind Closed Doors&lt;/em&gt; certainly makes it look possible to me, and that&amp;#8217;s about as high praise as I can imagine giving a book on the subject.&lt;/p&gt;
&lt;p&gt;Some gems from &lt;em&gt;Behind Closed Doors&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Evaluations are different from feedback&lt;/li&gt;
	&lt;li&gt;People don&amp;#8217;t know unless you tell them&lt;/li&gt;
	&lt;li&gt;Don&amp;#8217;t blame the other person for wanting what they want&lt;/li&gt;
	&lt;li&gt;Management exists to organize purposefully&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/152';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/152&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 04, 2007  17:51
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/review&quot;&gt;review&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 04 Dec 2007 17:51:37 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/152</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Why I don't miss anything anymore</title>
      <link>http://jbrains.ca/permalink/151</link>
      <description>&lt;div class='entry posting' id='entry-_posting_151'&gt;
&lt;div class='posting' id='content-_posting_151'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I used to be the type of person to miss meetings and deadlines like crazy. This happened to me primarily because I tried to keep everything in my head. I have tried a bunch of little techniques for reminders, and nothing really worked until I started using &lt;a href=&quot;http://backpackit.com/?referrer=BPB6JZ9&quot;&gt;Backpack&lt;/a&gt;. Here are the things I tried.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;I tried writing things in a pocket-sized notebook, believing that writing things down increased my chances of remembering them. This didn&amp;#8217;t work, either because I forgot to look at the notebook every day or, quite simply, I&amp;#8217;d lose the notebook.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;I tried writing things on index cards, since I used index cards effectively as part of my software practices. This didn&amp;#8217;t work because I wouldn&amp;#8217;t carry the cards around with me enough nor look at them enough to recall appointments.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;I tried a PocketPC, but frankly that became little more than a way to keep myself entertained while waiting for the bus. My subconscious recognized how useless it was for me and helped me leave it &amp;#8220;by accident&amp;#8221; on a flight from Philadelphia to Toronto.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;I tried calendar software on my computer, but found it hard to get appointments onto the calendar, because I didn&amp;#8217;t always have my computer handy. I tried a workflow that involved index cards that I later transcribed to computer&amp;#8230; and it just didn&amp;#8217;t work, so I abandoned it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now I use &lt;a href=&quot;http://backpackit.com/?referrer=BPB6JZ9&quot;&gt;Backpack&lt;/a&gt;, a service from the nice folks at 37signals. Backpack reminders are flexible, simple and quick to use. I set up reminders for tasks that don&amp;#8217;t have a definite due date, but as a &amp;#8220;tickler&amp;#8221; in the Getting Things Done sense of the term. I have reminders set five years into the future on Backpack as a testament to how much I believe I&amp;#8217;ll be using the service in the years to come. While I tend to use Backpack mainly for reminders, I also use the Writeboard to share composition space with friends and family.&lt;/p&gt;
&lt;p&gt;So if you&amp;#8217;re looking to get re-organized, I recommend reading &lt;a href=&quot;http://tinyurl.com/2y4662&quot;&gt;Getting Things Done&lt;/a&gt;, grabbing a copy of &lt;a href=&quot;http://tinyurl.com/3yrfjb&quot;&gt;OmniFocus&lt;/a&gt; (you are a Mac user, aren&amp;#8217;t you?) and subscribing to &lt;a href=&quot;http://backpackit.com/?referrer=BPB6JZ9&quot;&gt;Backpack&lt;/a&gt;. You&amp;#8217;ll be glad you did.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/151';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/151&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 02, 2007  19:34
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/planning&quot;&gt;planning&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/personality-types&quot;&gt;personality types&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/emotional-health&quot;&gt;emotional health&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 02 Dec 2007 19:34:02 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/151</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Presenting &quot;Refactoring: Where Do I Start?&quot; in Orlando</title>
      <link>http://jbrains.ca/permalink/150</link>
      <description>&lt;div class='entry posting' id='entry-_posting_150'&gt;
&lt;div class='posting' id='content-_posting_150'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;This is just a reminder that I am presenting &lt;a href=&quot;http://www.sqe.com/agiledevpractices/Concurrent/Default.aspx?Day=Thursday#T5&quot;&gt;Refactoring: Where Do I Start?&lt;/a&gt; at Better Software&amp;#8217;s Agile Development Practices conference in Orlando on December 6 at 10:00 AM. I&amp;#8217;ll spend about 20 minutes talking about refactoring, about 40 minutes doing it and about 30 minutes answering your questions. If you&amp;#8217;re unsure how to refactor code, how to begin to learn about refactoring or which part of your system to attack first, this presentation is for you. I hope you see you there.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/150';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/150&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 02, 2007  19:08
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 02 Dec 2007 19:08:57 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/150</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Tutorial &quot;Evolutionary Design in Practice in Java&quot; in Orlando</title>
      <link>http://jbrains.ca/permalink/149</link>
      <description>&lt;div class='entry posting' id='entry-_posting_149'&gt;
&lt;div class='posting' id='content-_posting_149'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;This is just a reminder that I&amp;#8217;m presenting &lt;a href=&quot;http://www.sqe.com/AgileDevPractices/Tutorials/Default.aspx?Day=Monday#MP&quot;&gt;Evolutionary Design in Practice in Java&lt;/a&gt; at Better Software&amp;#8217;s Agile Development Practices conference in Orlando on December 3 at 1:00 PM. I hope you&amp;#8217;ll be able to join us to experience hardcore evolutionary design. Don&amp;#8217;t write any unnecessary code! See you there.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/149';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/149&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 02, 2007  19:06
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 02 Dec 2007 19:06:33 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/149</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Tutorial &quot;Test-Driven Enterprise Code&quot; in Orlando</title>
      <link>http://jbrains.ca/permalink/148</link>
      <description>&lt;div class='entry posting' id='entry-_posting_148'&gt;
&lt;div class='posting' id='content-_posting_148'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;This is just a reminder that I am presenting &lt;a href=&quot;http://www.sqe.com/AgileDevPractices/Tutorials/Default.aspx?Day=Monday#MJ&quot;&gt;Test-Driven Enterprise Code&lt;/a&gt; at Better Software&amp;#8217;s Agile Development Practices conference in Orlando on Monday, December 3 at 8:30 AM. I hope you&amp;#8217;ll take the chance to join us to learn how to tackle enterprise applications test first.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/148';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/148&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 02, 2007  19:02
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 02 Dec 2007 19:02:03 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/148</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>How Getting Things Done is helping me</title>
      <link>http://jbrains.ca/permalink/147</link>
      <description>&lt;div class='entry posting' id='entry-_posting_147'&gt;
&lt;div class='posting' id='content-_posting_147'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have recently become a Getting This Done disciple. I hesitate to use that term a little, but I am a disciple in the true sense: I have devoted myself to learn &lt;span class=&quot;caps&quot;&gt;GTD&lt;/span&gt; for a while and I don&amp;#8217;t really know what I&amp;#8217;m doing yet, so I&amp;#8217;m mostly following the rules and observing the results. The nicest result I&amp;#8217;ve noticed so far is the way that &lt;span class=&quot;caps&quot;&gt;GTD&lt;/span&gt; helps me focus on work or play, whichever I&amp;#8217;m doing at the moment. This makes work go more smoothly and play be, well, more fun!&lt;/p&gt;
&lt;p&gt;Since I don&amp;#8217;t much have to worry about remembering to do things, I don&amp;#8217;t have to worry about work while I&amp;#8217;m playing, in whatever form that takes. Also, since I know what I need to do in a given day and I break things down to mostly 30-minute tasks, I can easily focus on the current task, get it done, then take a 10-minute break before continuing. It&amp;#8217;s like being at a meeting where everyone gets to be heard: people listen and focus, rather than merely waiting for their turn to speak.&lt;/p&gt;
&lt;p&gt;Thanks to David Allen, the &lt;span class=&quot;caps&quot;&gt;GTD&lt;/span&gt; community and the nice folks who build OmniFocus for their help.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/147';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/147&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 02, 2007  18:57
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/emotional-health&quot;&gt;emotional health&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 02 Dec 2007 18:57:37 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/147</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The Curse of the Serial Master</title>
      <link>http://jbrains.ca/permalink/146</link>
      <description>&lt;div class='entry posting' id='entry-_posting_146'&gt;
&lt;div class='posting' id='content-_posting_146'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/curse-serial-master.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is probably why I stayed so depressed for so long. To learn about the personality types of Scanners like the Serial Master, read &lt;a href=&quot;http://tinyurl.com/38dh9j&quot;&gt;Refuse to Choose&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/146';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/146&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
November 27, 2007  16:41
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/being-a-scanner&quot;&gt;being a scanner&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/emotional-health&quot;&gt;emotional health&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 27 Nov 2007 16:41:30 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/146</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>With whom, exactly, are you arguing?</title>
      <link>http://jbrains.ca/permalink/145</link>
      <description>&lt;div class='entry posting' id='entry-_posting_145'&gt;
&lt;div class='posting' id='content-_posting_145'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have been reading a bit more about the Satir Interaction Model, which describes how we understand the way we interact with people. I find this model helps me communicate more effectively with people, at work and at home. In Dale Emery&amp;#8217;s &lt;a href=&quot;http://www.dhemery.com/articles/untangling_communication.html&quot;&gt;Untangling Communication&lt;/a&gt;, he shares this story about giving significance to a conversation.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I was once in a meeting with Larry, the product manager for whom I had worked for several years, and six engineers. We were trying to decide whether to make our proprietary thread package available to customers through our public &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;, as a key potential customer had requested. Larry thought that making the threading functions available was a good idea. I was adamantly against it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Larry and I were unable to reach consensus. The meeting ended with everyone feeling frustrated and spent. Tom, one of the engineers at the meeting, visited me in my office, and said, &amp;#8220;Wow, you sure were angry in that meeting!&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;#8220;No, I wasn&amp;#8217;t angry,&amp;#8221; I said. &amp;#8220;I just think it would be a mistake to expose such a low-level interface.&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;#8220;Well,&amp;#8221; he said, &amp;#8220;You sure sounded angry to me.&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;As I drove home that night, I slowly began to realize that Tom had been right. Though I had been unaware of it during the meeting, I had been not just angry, but furious. Later, as I tossed and turned trying to sleep, I realized that the topic of the meeting, the decision about exposing the thread package, had played only a small role in my anger. What I had been really furious about were the many &amp;#8220;similar&amp;#8221; situations over the previous few years in which Larry had made design decisions over my strong objections. Though I had not been consciously aware of it, I had come to resent these decisions. My resentment had contaminated this meeting and a number of others.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The next morning, I met with Larry to talk about what I had learned. We still disagreed about the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;, but we were able to express our disagreement much more calmly and to understand each other&amp;#8217;s point of view much more compassionately.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I had given this conversation much greater significance than it warranted. For me, the conversation was not just a single decision about an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;, but a symbol of all of the unresolved issues in my relationship with Larry.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&amp;#8217;s this last bit that hits home for me. I have trained myself to treat every argument as though it were about my entire relationship history with the other people involved, and not just the current topic. This helps me understand better when I react strongly to something, what that&amp;#8217;s about. When someone asks me, &amp;#8220;What&amp;#8217;s going on for you right now?&amp;#8221; I know that what&amp;#8217;s going on goes back weeks, months, years, well before this conversation ever started. By being on the lookout for such things, I find I&amp;#8217;m better equipped to handle the current conversation without letting it fly off the rails too quickly. I recommend it to you, too.&lt;/p&gt;
&lt;p&gt;When you are arguing with someone, stop and ask yourself what past transgression, disagreement or problem is coming up for you at that moment, beyond just the issue before you.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;[Here is a comment from Don Gray.]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Your post title &amp;#8220;With whom, exactly, are you arguing?&amp;#8221; wonderfully juxtapositions with Virginia Satir&amp;#8217;s original writing &amp;#8220;With Whom Am I Having the Pleasure?&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;When a conversation includes information that doesn&amp;#8217;t fit the current situation, I use &amp;#8220;Them, there, then&amp;#8221; and &amp;#8220;Us, here, now&amp;#8221; to see if that helps explain why the energy level seems mismatched with the context.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Virginia said &amp;#8220;We come together through our similarities, we grow through our differences.&amp;#8221; Arguing contains negative meaning for me. It feels like a cross between the super-reasonable and blaming coping stances. I&amp;#8217;ll call it &amp;#8220;super-blaming&amp;#8221;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;For me to be right, you have to be wrong. It&amp;#8217;s a common position. I&amp;#8217;m watching it play out in an on line discussion group. On person said &amp;#8220;&lt;span class=&quot;caps&quot;&gt;XXX&lt;/span&gt; isn&amp;#8217;t suited for automated regression testing.&amp;#8221; Others rejoined &amp;#8220;Oh yes &lt;span class=&quot;caps&quot;&gt;XXX&lt;/span&gt; is.&amp;#8221; It&amp;#8217;s been going on for four days.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;If we chose to be congruent, and hear the difference as a learning opportunity, it changes the dynamic from argument to cooperation. The hard part is catching the initial fight/flight adrenalin rush. The cool part is the other person doesn&amp;#8217;t have to agree not to argue. Changing what you ask, and how you ask it transforms the conversation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/145';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/145&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
November 24, 2007  13:02
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 24 Nov 2007 13:02:16 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/145</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Ask a Question for Agile Dev Practices</title>
      <link>http://jbrains.ca/permalink/144</link>
      <description>&lt;div class='entry posting' id='entry-_posting_144'&gt;
&lt;div class='posting' id='content-_posting_144'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;[This comes from Better Software, hosts of the Agile Development Practices conference at which I will appear in December.]&lt;/p&gt;
&lt;p&gt;Have you ever wanted to ask an industry expert a particular question? Well, here is your chance: the Agile Development Practices Live Podcast. The conference staff is giving you, a chance to submit a question you want answered by an industry expert. StickyMinds.com editors will select some of the submitted questions to ask the experts during the live recordings. The selected questions will be credited back to you! Your questions must be submitted by Wednesday, Nov. 28 to be considered for these live interviews.&lt;/p&gt;
&lt;p&gt;Submit your questions to &lt;a href=&quot;mailto:editors@stickyminds.com&quot;&gt;editors@stickyminds.com&lt;/a&gt; to have your question considered.&lt;/p&gt;
&lt;p&gt;Hurry, All questions are due by Wednesday, November 28, 2007, 5:00 PM &lt;span class=&quot;caps&quot;&gt;EST&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;What information is needed to submit your question?&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Your name (and how to pronounce it)&lt;/li&gt;
	&lt;li&gt;Your question and which expert it should be directed to (see the experts listed below)&lt;/li&gt;
	&lt;li&gt;Your email address and location (state/province and country)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://www.sqe.com/go?adp07podsubmit&quot;&gt;Learn More&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Hear from some of the best in the business&amp;#8230;&lt;/p&gt;
&lt;p&gt;Featured Speakers Include:&lt;/p&gt;
&lt;p&gt;J.B. Rainsberger &lt;br /&gt;
&lt;del&gt;-&lt;/del&gt;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;-&lt;br /&gt;
Joe is a programmer, coach, mentor, and author. His book, &amp;#8220;JUnit Recipes&amp;#8221;, which has become &amp;#8220;the bible of JUnit,&amp;#8221; is a manual for Java programmers to improve their programming skills through programmer testing. Beyond helping programmers learn how to test, Joe teaches teams about XP, teamwork, and object-oriented design. He is a dynamic presenter who likes to teach by example. Read his blog at &lt;a href=&quot;http://jbrains.ca&quot;&gt;http://jbrains.ca&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Linda Rising &lt;br /&gt;
&lt;del&gt;-&lt;/del&gt;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;-&lt;br /&gt;
Linda has a Ph.D. from Arizona State University in the field of object-based design metrics and a background that includes university teaching and industry work in telecommunications, avionics, and strategic weapons systems. An internationally known presenter on topics related to patterns, retrospectives, and the change process, Linda is the author of &amp;#8220;Design Patterns in Communications Software&amp;#8221;, &amp;#8220;The Pattern Almanac 2000&amp;#8221;, &amp;#8220;The Patterns Handbook&amp;#8221;, and co-author with Mary Lynn Manns of &amp;#8220;Fearless Change: Patterns for Introducing New Ideas&amp;#8221;. Find more information about Linda at &lt;a href=&quot;http://www.lindarising.org&quot;&gt;http://www.lindarising.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Jean Tabaka&lt;br /&gt;
&lt;del&gt;-&lt;/del&gt;&amp;#8212;&amp;#8212;&amp;#8212;&amp;#8212;&lt;br /&gt;
Jean is an agile mentor and coach with Rally Software Development. In addition to being a certified Scrum trainer and practitioner, she is also a certified professional facilitator. Her unique blend of passions and skills has been applied in a variety of organizations&amp;mdash;large and small, co-located and distributed&amp;mdash;eager to adopt the best of agile and bring out the best in their teams. Author of the Agile Software Development series book &amp;#8220;Collaboration Explained&amp;#8221;, Jean holds a Masters in Computer Science from Johns Hopkins University.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.sqe.com/go?adp07podsubmit&quot;&gt;Learn More&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Submit your questions to &lt;a href=&quot;mailto:editors@stickyminds.com&quot;&gt;editors@stickyminds.com&lt;/a&gt; now! At each of the three interview sessions, one person will be selected from all those who have submitted questions to receive a StickyMinds.com Prize Pack! You must be present to win.&lt;/p&gt;
&lt;hr /&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/144';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/144&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
November 16, 2007  16:56
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 16 Nov 2007 16:56:48 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/144</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Book review: Test-Driven</title>
      <link>http://jbrains.ca/permalink/142</link>
      <description>&lt;div class='entry posting' id='entry-_posting_142'&gt;
&lt;div class='posting' id='content-_posting_142'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;On a recent trip, I read Lasse Koskela&amp;#8217;s &lt;a href=&quot;http://www.manning.com/koskela&quot;&gt;&lt;em&gt;Test-Driven&lt;/em&gt;&lt;/a&gt;, one of Manning&amp;#8217;s latest releases. I opened it with the preconceived notion that there was nothing left for me to learn about Test-Driven Development, but Lasse presents the topic with a fresh perspective that I admire. Introductory text books tend to go stale, even after only a few years, and while Kent Beck&amp;#8217;s &lt;em&gt;Test-Driven Development: By Example&lt;/em&gt; remains a classic, &lt;em&gt;Test-Driven&lt;/em&gt; provides a much-needed update to the literature. Koskela goes beyond the basics to give the reader a valuable overview of today&amp;#8217;s &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; landscape, including an extensive section on &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; at the story level, current information on tools and more recent examples of test-driving Enterprise Java components and applications.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Test-Driven&lt;/em&gt;&amp;#8216;s overview is quite extensive; any reader is sure to be satisfied by its reach. It was an ambitious project, not one I think I would have undertaken, but Lasse has come through it gracefully. The result is a solid addition to the literature that &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; practitioners can heartily recommend to their novice colleagues. While I don&amp;#8217;t agree with some of Lasse&amp;#8217;s test design style, he has plenty of great things to say about &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; and designing Java code, and readers will benefit from his experience.&lt;/p&gt;
&lt;p&gt;Lasse&amp;#8217;s writing is engaging, his examples illustrate his points well and he doesn&amp;#8217;t beat around the bush. If you like directness of approach and of exposition, then &lt;em&gt;Test-Driven&lt;/em&gt; is for you. I give it 4/5 on the &lt;a href=&quot;http://www.amazon.com&quot;&gt;amazon.com&lt;/a&gt; scale and plan to add it to the bibliographies of my &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;-related seminars and courses.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/142';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/142&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
November 14, 2007  08:26
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/review&quot;&gt;review&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 14 Nov 2007 08:26:43 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/142</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Trying a new Subversion client</title>
      <link>http://jbrains.ca/permalink/141</link>
      <description>&lt;div class='entry posting' id='entry-_posting_141'&gt;
&lt;div class='posting' id='content-_posting_141'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Until now, my Subversion client has been Eclipse. Unfortunately, both it and my primary repository have grown so much that Eclipse is no longer a viable Subversion client for me. I have tried &lt;a href=&quot;http://svnx.lachoseinteractive.net/&quot;&gt;svnX&lt;/a&gt;, but I don&amp;#8217;t find it quite ready for prime time. Specifically, it can&amp;#8217;t handle &lt;span style=&quot;white-space: nowrap;&quot;&gt;&lt;code&gt;svn revert --recursive&lt;/code&gt;&lt;/span&gt;, which I needed last night. I don&amp;#8217;t want to criticize *svnX*&amp;#8217;s maintainer. I just can&amp;#8217;t use it yet, and I don&amp;#8217;t have the energy to help the project out. I need something to work and do everything I need, which is why I&amp;#8217;m now trying out &lt;a href=&quot;http://www.syncrosvnclient.com&quot;&gt;syncroSvnClient&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This new client is not free, so I&amp;#8217;m using a 30-day trial licence for now. I&amp;#8217;m writing this while I use syncroSvnClient for the first time, so you&amp;#8217;re getting my (mostly) unedited first impressions.&lt;/p&gt;
&lt;p&gt;Installing the software was not as straightforward as I would have liked. I&amp;#8217;m used to just dragging the &lt;code&gt;.app&lt;/code&gt; file to &lt;code&gt;Applications&lt;/code&gt;, but that didn&amp;#8217;t work. Instead, I was supposed to drag the entire &lt;code&gt;syncroSvnClient&lt;/code&gt; directory to &lt;code&gt;Applications&lt;/code&gt;. Not the end of the world.&lt;/p&gt;
&lt;p&gt;Getting a trial licence was straightforward. I had one by e-mail in moments and was able to use it easily.&lt;/p&gt;
&lt;p&gt;I linked to a repository easily enough. The experience is very much like Eclipse&amp;#8217;s Subversion client in this respect. Of course, I realize now that I should have added a &lt;strong&gt;working copy&lt;/strong&gt;, and not a repository. Doing that was less obvious, as there is no icon that immediately suggests &amp;#8220;add&amp;#8221; or &amp;#8220;link to&amp;#8221;. The icon I wanted is a little wrench. A minor annoyance, but I&amp;#8217;m past it.&lt;/p&gt;
&lt;p&gt;So I linked to the working copy I use to develop this site. That was quick and easy. My next test for this client is how easily it lets me ignore files. This is something &lt;strong&gt;svnX&lt;/strong&gt; doesn&amp;#8217;t seem to support yet. I want to ignore the log files, like &lt;code&gt;development.log&lt;/code&gt; and &lt;code&gt;test.log&lt;/code&gt;. That was easy: select, right-click&amp;#8230; hey, this looks &lt;em&gt;exactly&lt;/em&gt; like Subclipse! If I can have the benefit of Subclipse without the bulk of Eclipse, that would be cool.&lt;/p&gt;
&lt;p&gt;In fact, that&amp;#8217;s good enough for now. I&amp;#8217;m temporarily sold. I&amp;#8217;m going to keep using it for the 30 days, then decide what to do after that. I don&amp;#8217;t want to claim I&amp;#8217;m ready to buy it, but I like what I see so far.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/141';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/141&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
November 11, 2007  15:06
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/mac&quot;&gt;mac&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 11 Nov 2007 15:06:30 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/141</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>&quot;Please change your free service&quot;, part deux</title>
      <link>http://jbrains.ca/permalink/140</link>
      <description>&lt;div class='entry posting' id='entry-_posting_140'&gt;
&lt;div class='posting' id='content-_posting_140'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Not long ago, I stood up for my friend, Reg Braithwaite-Lee. You can read about that &lt;a href=&quot;http://www.jbrains.ca/permalink/139&quot;&gt;here&lt;/a&gt;. With the benefit of some distance, and at the prompting of a response I read &lt;a href=&quot;http://use.perl.org/comments.pl?sid=37391&amp;amp;cid=58690&quot;&gt;here&lt;/a&gt;, I would like to say a little more about this situation.&lt;/p&gt;
&lt;p&gt;First, let me be clear: I stand by my statement. I find it arrogant to ask someone for more free stuff without offering something in return. (There&amp;#8217;s a &lt;a href=&quot;http://dictionary.reference.com/browse/mooching&quot;&gt;special word&lt;/a&gt; for that.) This might just be a rule I have, but it has at least a kernel of truth. I don&amp;#8217;t apologize for feeling this way.&lt;/p&gt;
&lt;p&gt;I do, however, regret being unclear. I didn&amp;#8217;t want to say that one should always offer &lt;em&gt;money&lt;/em&gt; for a customized experience; however, I believe one should always offer &lt;em&gt;something&lt;/em&gt; the requester finds valuable. Something the requester would want others to offer him. Now, people with a strong bond of trust can ask each other for anything and expect to get it, mainly because the trust is built on only asking for what&amp;#8217;s truly important when it&amp;#8217;s truly needed; but in all other relationships, it&amp;#8217;s merely polite to offer something. Money, sincere gratitude, helping out, &lt;em&gt;something&lt;/em&gt;. I inferred from Reg&amp;#8217;s reaction that his requesters did not offer him much.&lt;/p&gt;
&lt;p&gt;I must grant that I assumed that, based solely on Reg&amp;#8217;s reaction. It&amp;#8217;s entirely possible that his requesters were polite, showed tremendous gratitude, and thought they were helping their fellow &lt;strong&gt;raganwald&lt;/strong&gt; readers, but I find it a safe guess that if they had, Reg wouldn&amp;#8217;t have considered taking away some of the free stuff he&amp;#8217;s giving us. A mother rarely threatens to take away a child&amp;#8217;s toys because the child does something nice. Still, if I wanted to be sure, I should have asked Reg. Sorry, Reg, if I over-reacted and embarrassed you. I don&amp;#8217;t think I did, because you didn&amp;#8217;t tell me I did, but I apologize all the same.&lt;/p&gt;
&lt;p&gt;So that&amp;#8217;s all I have to say about that. If you lost respect for me over this, then I invite you to let me earn it back.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/140';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/140&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
November 09, 2007  08:11
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 09 Nov 2007 08:11:31 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/140</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>&quot;Please change your free service&quot; (updated)</title>
      <link>http://jbrains.ca/permalink/139</link>
      <description>&lt;div class='entry posting' id='entry-_posting_139'&gt;
&lt;div class='posting' id='content-_posting_139'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I prefer not to rant on this weblog, because I don&amp;#8217;t find ranting very becoming; however, there are a few hot-button issues that I want to rant about, and so here it is. I promise it will be brief.&lt;/p&gt;
&lt;p&gt;I know, like and respect Reg Braithwaite-Lee, who writes &lt;a href=&quot;http://weblog.raganwald.com/&quot;&gt;here&lt;/a&gt;. Frankly, I don&amp;#8217;t understand everything Reg writes about, but I love his enthusiasm and I often learn from him. All the more reason, then, for this to annoy me. Recently, he wrote:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have now received my second request for an &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt; feed that does not include a daily summary of links I find relevant to this weblog. So I&#8217;m thinking about dropping them outright.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I&#8217;m not thinking about offering three feeds (one just links, one just posts, and one blended). I&#8217;m not even thinking about offering two feeds. There is one feed for this weblog; the question I am asking myself is whether it should contain my words or whether it should contain my words and a daily summary of interesting links.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To be blunt for a moment, this chaps my ass. To the two people who made this request to Reg, did you read your own e-mail before you sent it? This is what you&amp;#8217;re asking Reg:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I know you offer us a lot of useful information and opinion, and I know I don&amp;#8217;t have to pay a dime for it, but would you please customize my experience by doubling your effort so I can avoid having to press &lt;code&gt;Delete&lt;/code&gt;?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You want a custom experience? Offer to pay for it. If you can&amp;#8217;t hit delete once &lt;em&gt;per day&lt;/em&gt; because you don&amp;#8217;t find Reg&amp;#8217;s &lt;code&gt;del.icio.us&lt;/code&gt; links interesting, that&amp;#8217;s fine; but if you expect Reg to rearrange his writing for you, then you should offer to pay him. &lt;strong&gt;I find it the height of arrogance to ask someone to do more work without offering him something in return.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If I were Reg, I would, after calming down, politely decline the request. If I were to act without calming down, I would think along the lines Reg is thinking, and reduce my output to the lowest common denominator. And my readers would likely lose, on the whole.&lt;/p&gt;
&lt;p&gt;So Reg, to hell with those two people. I find 90% of your &lt;code&gt;del.icio.us&lt;/code&gt; links to be a waste of time, but every week or so I read something I&amp;#8217;m glad I read. Funny&amp;#8230; it&amp;#8217;s like I &lt;a href=&quot;http://tinyurl.com/2qga3o&quot;&gt;read something about that somewhere recently&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Updated November 9, 2007&lt;/em&gt;. Read more about this &lt;a href=&quot;http://jbrains.ca/permalink/140&quot;&gt;here&lt;/a&gt;]&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/139';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/139&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 27, 2007  21:49
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/writing&quot;&gt;writing&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 27 Oct 2007 21:49:56 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/139</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>A call for code for &quot;Refactoring: Where Do I Start?&quot;</title>
      <link>http://jbrains.ca/permalink/138</link>
      <description>&lt;div class='entry posting' id='entry-_posting_138'&gt;
&lt;div class='posting' id='content-_posting_138'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I am running a session entitled &lt;em&gt;Refactoring: Where Do I Start?&lt;/em&gt; at the first &lt;a href=&quot;http://www.sqe.com/agiledevpractices&quot;&gt;Agile Development Practices&lt;/a&gt; conference. Although I plan to speak for a few minutes, I&amp;#8217;d like to spend most of the time answering your questions and refactoring some real code on stage. As a result, &lt;strong&gt;I&amp;#8217;d like your code&lt;/strong&gt;! I have a sample code base to refactor, but I&amp;#8217;d rather refactor your code, to show everything that goes into refactoring: learning a code base, making some initial small refactorings, then envisioning how they can collect into something bigger and more significant. I put out the challenge to you, then: give me your code and I&amp;#8217;ll refactor it!&lt;/p&gt;
&lt;p&gt;Here are the guidelines:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Java or Ruby, please. I&amp;#8217;ll look at other code bases, but this session is not the time for me to be learning the finer points of a language.&lt;/li&gt;
	&lt;li&gt;If it&amp;#8217;s Java code, it must compile. If you want to take a small section of your code base out, put back enough libraries or stubs to make it compile.&lt;/li&gt;
	&lt;li&gt;It must do something useful to someone. It can have bugs, but it can&amp;#8217;t be a total mess. I don&amp;#8217;t want to spend most of the time getting your code to do something, anything. If a refactoring uncovers a possible bug, that&amp;#8217;s cool.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A request: if you can send the code to me as an Eclipse project, that would be great. It&amp;#8217;s not absolutely required, but it would help. If I can&amp;#8217;t get the code compiling and running in Eclipse within 15 minutes, I&amp;#8217;ll probably give up and move on.&lt;/p&gt;
&lt;p&gt;If you have a code base you&amp;#8217;d like to send me, please e-mail me at &lt;code&gt;refactoring&lt;/code&gt; &lt;strong&gt;the beautiful at sign&lt;/strong&gt; &lt;code&gt;diasparsoftware&lt;/code&gt; &lt;strong&gt;the dazzling dot&lt;/strong&gt; &lt;code&gt;com&lt;/code&gt; and I&amp;#8217;ll give you instructions where to send the code. Thanks!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/138';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/138&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 27, 2007  17:11
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 27 Oct 2007 17:11:44 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/138</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Having trouble explaining refactoring?</title>
      <link>http://jbrains.ca/permalink/137</link>
      <description>&lt;div class='entry posting' id='entry-_posting_137'&gt;
&lt;div class='posting' id='content-_posting_137'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I just read &lt;a href=&quot;http://michael-mccracken.net/wp/2007/10/09/the-editing-pass/&quot;&gt;this&lt;/a&gt; and it seems to describe refactoring almost exactly. I don&amp;#8217;t know why I hadn&amp;#8217;t thought of it before. Excellent.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/137';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/137&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 11, 2007  00:33
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 11 Oct 2007 00:33:04 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/137</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Another way TDD reduces design complexity</title>
      <link>http://jbrains.ca/permalink/136</link>
      <description>&lt;div class='entry posting' id='entry-_posting_136'&gt;
&lt;div class='posting' id='content-_posting_136'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I read this at worsethanfailure.com, and it sparked something in me. It is a quote of Michael A. Jackson from &lt;em&gt;Principles of Program Design&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Programmers&#8230; often take refuge in an understandable, but disastrous, inclination towards complexity and ingenuity in their work. Forbidden to design anything larger than a program, they respond by making that program intricate enough to challenge their professional skill.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I find this interesting, because I &lt;strong&gt;want&lt;/strong&gt; to write simple programs. I find the simplicity comforting and safe. The less complex it is, the less likely I&amp;#8217;ll screw it up. Still, I do recognize my own tendency to add complexity as a challenge, rather than when it&amp;#8217;s truly called for. I think practising &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; has helped with that. &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; itself is enough of a technical challenge that I don&amp;#8217;t need to add unnecessary complexity to feel challenged. Perhaps that represents another of its benefits.&lt;/p&gt;
&lt;p&gt;Try this at work: the next time someone tells you &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; is a waste of time, frame &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; as a design challenge. Say it&amp;#8217;s a way to find the minimally complex design for a given problem. Maybe that will intrigue that someone. Maybe not, but it&amp;#8217;s worth a shot. Looking back, I&amp;#8217;m pretty sure that &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; helped me feel challenged when writing software that was otherwise mostly easy.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/136';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/136&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 25, 2007  22:03
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 25 Sep 2007 22:03:56 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/136</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>I wrote JUnit Recipes; Vince wrote JUnit in Action</title>
      <link>http://jbrains.ca/permalink/135</link>
      <description>&lt;div class='entry posting' id='entry-_posting_135'&gt;
&lt;div class='posting' id='content-_posting_135'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I&amp;#8217;m not sure why it keeps happening, because I don&amp;#8217;t notice it much with other authors and their books. A number of times, I have seen people confuse Vincent Massol&amp;#8217;s excellent book &lt;em&gt;JUnit in Action&lt;/em&gt; with my book &lt;em&gt;JUnit Recipes&lt;/em&gt;. Most recently, I found the error in &lt;a href=&quot;http://safari.oreilly.com/9780596510237&quot;&gt;Checking Java Programs&lt;/a&gt; by Ian Darwin, although his &lt;a href=&quot;http://cjp.darwinsys.com/&quot;&gt;web site&lt;/a&gt; correctly refers to &lt;em&gt;JUnit Recipes&lt;/em&gt;. I imagine that means that Ian knows about the error, but wasn&amp;#8217;t able to fix it in time for his e-book. Shame.&lt;/p&gt;
&lt;p&gt;Don&amp;#8217;t get me wrong: I&amp;#8217;m happy for the reference, but I feel bad for Vince when someone attributes his book to me. Please get it right, folks.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/135';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/135&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 16, 2007  01:32
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/review&quot;&gt;review&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 16 Sep 2007 01:32:58 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/135</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Safari woes: Tidy to blame</title>
      <link>http://jbrains.ca/permalink/134</link>
      <description>&lt;div class='entry posting' id='entry-_posting_134'&gt;
&lt;div class='posting' id='content-_posting_134'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I like Safari; however, for about two months, it hadn&amp;#8217;t been working. Since it&amp;#8217;s easy to blame someone who isn&amp;#8217;t around to defend himself, I yelled at Safari each time it didn&amp;#8217;t work. It turns out that Safari wasn&amp;#8217;t entirely to blame. In the interest of providing some Google bait, here are some details.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;. When I started Safari 3.0 Beta 2 or Beta 3, the browser window would not launch without my expressly choosing it (with &lt;code&gt;Command+1&lt;/code&gt;, for example). Also, Safari would not load any pages. No matter which page I tried to browse to, Safari would response &amp;#8220;page failed to load&amp;#8221;. I had asked Google a few times to find me a cause, and it couldn&amp;#8217;t; but finally, I insisted, and after searching Apple&amp;#8217;s support forums for a few minutes, I found &lt;a href=&quot;http://tinyurl.com/2l3e6x&quot;&gt;this article&lt;/a&gt;, which suggested that the Tidy plugin was to blame. I tried their suggested solution of removing the Tidy-related folder from &lt;code&gt;~/Library/InputManagers&lt;/code&gt;, and Safari now works! And a cool browser it is.&lt;/p&gt;
&lt;p&gt;I hope this helps someone out there.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/134';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/134&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 01, 2007  02:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/mac&quot;&gt;mac&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 01 Sep 2007 02:00:21 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/134</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The electronic to-do list, revisited</title>
      <link>http://jbrains.ca/permalink/133</link>
      <description>&lt;div class='entry posting' id='entry-_posting_133'&gt;
&lt;div class='posting' id='content-_posting_133'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Since I have been spec-driving Rails code, and since I have very limited table space at home right now, I have been experimenting with something I&amp;#8217;d never liked before: an electronic test and refactoring list. So far, it&amp;#8217;s not too bad.&lt;/p&gt;
&lt;p&gt;Like many people, I like to avoid keeping lists in my head, since I tend to forget things. Normally, I use an index card and write tests from the top and refactorings from the bottom, crossing each out as I perform them. It works well. So well, in fact, that I generally question anyone who attempts to use an electronic system, rather than a paper system. The idea, of course, is that we tend to fixate on electronic systems, whereas we use paper systems simply and quickly. Using the computer for anything that doesn&amp;#8217;t benefit from automation seems counterproductive to me. Still, since we&amp;#8217;re low on table space, I&amp;#8217;ve had to try something else, and RSpec gives me the opportunity to maintain a test list without having to implement multiple failing tests (or specs) at once.&lt;/p&gt;
&lt;p&gt;With RSpec, one can describe a test with prose without implementing it, simply by invoking &lt;code&gt;it&lt;/code&gt; without a block.&lt;/p&gt;
&lt;pre&gt;
describe &quot;The thing I'm spec-driving&quot; do
  it &quot;should do something important&quot;
  it &quot;should do something else important&quot;
  it &quot;should do this third, equally important, thing&quot;
end
&lt;/pre&gt;
&lt;p&gt;When it&amp;#8217;s time to implement the spec, add the corresponding block. In the meantime, RSpec reports the other specs as &amp;#8220;pending&amp;#8221;, rather than attempting to execute them. I had never thought it was a good idea, before, but I&amp;#8217;ve been trying it recently, and I&amp;#8217;m less annoyed by it than I used to be. That might be because I&amp;#8217;m more comfortable spec-driving than I was years ago when I started; but it might just be because my personal taste has changed. I can&amp;#8217;t say. What I &lt;em&gt;can&lt;/em&gt; say is that I haven&amp;#8217;t managed to get lost yet, and it takes little extra effort to describe a handful of specs up front. If it starts bothering me, I&amp;#8217;ll be sure to describe my experience.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/133';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/133&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 31, 2007  22:45
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/adventures-in-RSpec&quot;&gt;adventures in RSpec&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 31 Aug 2007 22:45:34 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/133</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The smartest thing I've read in a long time</title>
      <link>http://jbrains.ca/permalink/132</link>
      <description>&lt;div class='entry posting' id='entry-_posting_132'&gt;
&lt;div class='posting' id='content-_posting_132'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&lt;a href=&quot;http://agileproductdesign.com/jeff_patton.html&quot;&gt;Jeff Patton&lt;/a&gt; is one seriously smart guy. I really need to pay much more attention to what he writes. While reading his older blog entries, I came across this nugget in &lt;a href=&quot;http://www.agileproductdesign.com/blog/acurate_estimate_red_herring.html&quot;&gt;an article attacking the myth of bad estimates sinking agile projects&lt;/a&gt;. Even entirely out of context, it&amp;#8217;s great:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Treat estimates as solution budgets and focus on solving the original problem&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Suppose the programmers estimate a story at 1 point, which happens to be around 3 days&amp;#8217; work on this project. Now suppose the team starts writing customer tests for this story and the story balloons into 2 weeks&amp;#8217; work. What should we do? Here are some options.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Let it be 2 weeks&amp;#8217; work, then re-plan and re-prioritize.&lt;/li&gt;
	&lt;li&gt;Work overtime in an attempt to squeeze 2 weeks&amp;#8217; work into 3 days.&lt;/li&gt;
	&lt;li&gt;Yell at each other over it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Sadly, I see the teams take the last option more often than the others. They might yell subtly at each other, but they yell all the same. If the programmers have the upper hand in the relationship, they insist it&amp;#8217;s 2 weeks&amp;#8217; work and they force the customer to re-prioritize and re-plan. If the customers have the upper hand in the relationship, they insist it be done in 3 days, and the programmers &amp;#8220;knuckle down&amp;#8221; to try to do it. In each of these cases, the result is not good.&lt;/p&gt;
&lt;p&gt;Now there is another option I didn&amp;#8217;t give earlier. &lt;strong&gt;Split the story into smaller pieces, the most urgent of which we hope is only 1 point.&lt;/strong&gt; This is usually more effective, but  I have &lt;a href=&quot;http://jbrains.ca/permalink/5&quot;&gt;already written&lt;/a&gt; about how difficult this is to do well. I wish I had read Jeff&amp;#8217;s words before I wrote what I did, because Jeff&amp;#8217;s advice provides a concrete goal for splitting this exploding story beyond &amp;#8220;it&amp;#8217;s a good thing to do&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn128b97fe4b9eff57c7928c44ef0b5bc731bea6c1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&amp;#8221;. Combining Jeff&amp;#8217;s advice with mine, we arrive at something better.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Find the most urgent part of the story that costs only 1 point, then split the rest into less urgent parts that the customer can put back in the backlog.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This way, the customer gets the essence of what she wanted when she chose this story as the next one to build; but the programmers aren&amp;#8217;t asked to do the impossible. It seems like a good outcome to me. Thanks, Jeff, for helping me justify my advice.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn128b97fe4b9eff57c7928c44ef0b5bc731bea6c1&quot;&gt;&lt;sup&gt;1&lt;/sup&gt; I haven&amp;#8217;t found much success justifying my advice to software people with &amp;#8220;trust me; it&amp;#8217;s good for you&amp;#8221;. I&amp;#8217;m constantly on the lookout for a better answer.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/132';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/132&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 27, 2007  01:11
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/stories&quot;&gt;stories&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/planning&quot;&gt;planning&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 27 Aug 2007 01:11:36 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/132</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Patching RedCloth: unique footnote hyperlinks</title>
      <link>http://jbrains.ca/permalink/131</link>
      <description>&lt;div class='entry posting' id='entry-_posting_131'&gt;
&lt;div class='posting' id='content-_posting_131'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Recently, I integrated Textile into this blog via &lt;a href=&quot;http://whytheluckystiff.net/ruby/redcloth&quot;&gt;RedCloth&lt;/a&gt;. As I started to write articles in my Adventures in RSpec series, I found I wanted to use footnotes. Since Textile supports them, I figured I was in luck; however, I soon found a hyperlink collision when two fragments of Textile markup appear on the same page, each with the same-numbered footnote. RedCloth simply generates a hyperlink to target &lt;code&gt;fn1&lt;/code&gt; for footnote #1, so if there are two footnote #1s on the same page, they both link to target &lt;code&gt;fn1&lt;/code&gt;, making it the equivalent of a race condition.&lt;/p&gt;
&lt;p&gt;I looked for guidance to the &lt;a href=&quot;http://www.textpattern.com&quot;&gt;Textpattern&lt;/a&gt; folks. A certain Mary told me that Textile has fixed this problem, but likely RedCloth has not. After some investigation, I agreed that this was the case. I looked through the Textile source, to the extent I can understand &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt;, and saw their fix was simple: keep a table of footnote numbers to unique IDs, then use the unique ID in place of the number in the hyperlink and target. I figured that I could do that.&lt;/p&gt;
&lt;p&gt;It took a couple of hours, and I&amp;#8217;ll spare you the details. Here is what I wrote:&lt;/p&gt;
&lt;pre&gt;
require 'digest/sha1'

class UniqueFootnoteIdGeneratingRedCloth &amp;lt; RedCloth
  def initialize(markup)
    @footnote_ids_by_number = {}
    super(markup)
  end

  def next_footnote_id
    # SHA1 isn't significant; I just figured it'd make a good unique ID
    Digest::SHA1.hexdigest(rand(2**64).to_s)
  end

  def to_html(*rules)
    self.scan( /\b\[([0-9]+?)\](\s)?/ ) do |match|
      @footnote_ids_by_number[$1] = next_footnote_id
    end
    
    super
  end
  
  private

  def footnote_ref(text)
    text.gsub!( /\b\[([0-9]+?)\](\s)?/ ) do |match|
      &quot;&amp;lt;sup&amp;gt;&amp;lt;a href=\&quot;#fn#{@footnote_ids_by_number[$1]}\&quot;&amp;gt;#{$1}&amp;lt;/a&amp;gt;&amp;lt;/sup&amp;gt;#{$2}&quot;
    end
  end

  def textile_fn_( tag, num, atts, cite, content )
    atts &amp;lt;&amp;lt; &quot; id=\&quot;fn#{ @footnote_ids_by_number[num] }\&quot;&quot;
    content = &quot;&amp;lt;sup&amp;gt;#{ num }&amp;lt;/sup&amp;gt; #{ content }&quot;
    atts = shelve( atts ) if atts
    &quot;\t&amp;lt;p#{ atts }&amp;gt;#{ content }&amp;lt;/p&amp;gt;&quot;
  end
end
&lt;/pre&gt;
&lt;p&gt;I ended up copy/pasting more code than I wanted to, so I&amp;#8217;ll have to submit something to &lt;a href=&quot;http://whytheluckystiff.net/&quot;&gt;why&lt;/a&gt; for his perusal. Perhaps this will make it into a future version of RedCloth.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/131';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/131&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 26, 2007  04:20
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/rails&quot;&gt;rails&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/adventures-in-RSpec&quot;&gt;adventures in RSpec&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 26 Aug 2007 04:20:58 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/131</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Don't mock the clock</title>
      <link>http://jbrains.ca/permalink/130</link>
      <description>&lt;div class='entry posting' id='entry-_posting_130'&gt;
&lt;div class='posting' id='content-_posting_130'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I just read &lt;a href=&quot;http://www.mockobjects.com/2007/04/test-smell-i-need-to-mock-object-i-cant.html&quot;&gt;this&lt;/a&gt; while cleaning up my unread blog subscriptions. This is an old topic for me. I once participated in a mailing list discussion that led to &lt;a href=&quot;www.nusco.org/docs/virtual_clock.pdf&quot;&gt;this paper&lt;/a&gt;. Since 2003 I have come across this question many times, and after trying a few different designs, I have come to this conclusion: parameterize the time; don&amp;#8217;t mock the clock.&lt;/p&gt;
&lt;p&gt;Looking at the example from &lt;a href=&quot;http://www.mockobjects.com/2007/04/test-smell-i-need-to-mock-object-i-cant.htm&quot;&gt;mockobjects.com&lt;/a&gt;, rather than passing in a &lt;code&gt;Clock&lt;/code&gt; interface to &lt;code&gt;Receiver&lt;/code&gt;, I would change the design of &lt;code&gt;acceptRequest()&lt;/code&gt; to accept an instant in time&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn153c01f9fd8a14c72411f7c24787c257abf6da24&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; as a parameter. I would end up with this:&lt;/p&gt;
&lt;pre&gt;
public boolean acceptRequestAsOf(Request request, Instant requestInstant) {
  Date requestInstantAsDate = requestInstant.toDate();
  if (dateOfFirstRequest == null) {
   dateOfFirstRequest = requestInstantAsDate;
  } else if (firstDateIsDifferentFrom(requestInstantAsDate)) {
   return false;
  }
  // process the request
  return true;
}
&lt;/pre&gt;
&lt;p&gt;This leaves me with two options: add &lt;code&gt;acceptRequest&lt;/code&gt; to delegate to &lt;code&gt;acceptRequestAsOf&lt;/code&gt;, specifying the current time &lt;em&gt;or&lt;/em&gt; push the responsibility for choosing &amp;#8220;now&amp;#8221; up a layer in the design. I favor the latter option, because that option is more likely to introduce design tension, signaling inappropriate layering or a missing abstraction. My experience tells me that would push me in the direction that the mockobjects.com article moves: raising the talking level of the code by introducing the notion of a request expiring. It turns out that we&amp;#8217;d end up at the same place anyway: someone has to instantiate the &lt;code&gt;SameDayChecker&lt;/code&gt; with either a clock or the current day. I think it&amp;#8217;s clear which I&amp;#8217;d choose.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn153c01f9fd8a14c72411f7c24787c257abf6da24&quot;&gt;&lt;sup&gt;1&lt;/sup&gt; You can use &lt;code&gt;java.util.Calendar&lt;/code&gt;, &lt;code&gt;java.util.Date&lt;/code&gt; or the &lt;code&gt;joda-time&lt;/code&gt; package; that&amp;#8217;s hardly the point here.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/130';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/130&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 25, 2007  01:52
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 25 Aug 2007 01:52:38 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/130</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Breaking the unconscious will to implement too early</title>
      <link>http://jbrains.ca/permalink/129</link>
      <description>&lt;div class='entry posting' id='entry-_posting_129'&gt;
&lt;div class='posting' id='content-_posting_129'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;(From the &lt;code&gt;testdrivendevelopment&lt;/code&gt; Yahoo! group.)&lt;/p&gt;
&lt;p&gt;At the story level, I look for a concrete (all constants, no variables) &lt;br /&gt;
example of the story I&amp;#8217;m trying to implement. That forces me to hardcode &lt;br /&gt;
values in the production code. Then, at each step of the way, I change a &lt;br /&gt;
value to force me to generalize in each direction as I go. Once I&amp;#8217;m done &lt;br /&gt;
identifying values that need to change, I&amp;#8217;m done writing examples.&lt;/p&gt;
&lt;p&gt;At the code level, I do much the same thing. Once I have a design &lt;br /&gt;
sketch, I just pick one object, one method, then write a concrete test &lt;br /&gt;
with constant input and constant expected result. Once that passes, I &lt;br /&gt;
look again for directions in which to generalize.&lt;/p&gt;
&lt;p&gt;I like what you wrote: at the object/method level, if you can&amp;#8217;t identify &lt;br /&gt;
the &lt;em&gt;single thing&lt;/em&gt; the method needs to do, then write a concrete &lt;br /&gt;
example, identify the first constant whose value needs to change, and &lt;br /&gt;
&lt;em&gt;that&lt;/em&gt; is the first &lt;em&gt;single thing&lt;/em&gt; a method needs to do. Lather, rinse, &lt;br /&gt;
repeat.&lt;/p&gt;
&lt;p&gt;Any way you slice it, the key part of the technique for me is writing a &lt;br /&gt;
concrete example with real numbers, words and people. No variables. Even &lt;br /&gt;
when you think you know exactly what to do, start with a concrete &lt;br /&gt;
example. Doing this enough times will help you start thinking in terms &lt;br /&gt;
of examples/tests, rather than in terms of implementation code you need &lt;br /&gt;
to check with tests. At that point, the tests really drive the &lt;br /&gt;
production code.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/129';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/129&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 17, 2007  08:51
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 17 Aug 2007 08:51:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/129</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Live Preview with RSpec on Rails</title>
      <link>http://jbrains.ca/permalink/128</link>
      <description>&lt;div class='entry posting' id='entry-_posting_128'&gt;
&lt;div class='posting' id='content-_posting_128'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Today I&amp;#8217;m waiting at Cos&amp;igrave; Cafe for our train to Washington DC for Agile 2007, so it&amp;#8217;s time to add the next part of the &amp;#8220;preview&amp;#8221; feature. I have an internet connection, so I can afford to be a little more aggressive with the story I tackle next, because Google knows all. I think I&amp;#8217;ll try to build the real-time preview I imagined earlier this morning. Now I don&amp;#8217;t think I can spec-drive the real-time aspect of the preview, but I can certainly spec-drive showing the preview in a nearby window while I&amp;#8217;m typing in the posting content text area. To get a sense for how that would look, I do some quick UI design.&lt;/p&gt;
&lt;p&gt;In order to make room, I shrink the &amp;#8220;content&amp;#8221; text area and put the live preview, as it&amp;#8217;s called, below it. This looks reasonable to me. In the process, I make one design decision: the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; that contains the live preview text has the ID &lt;code&gt;content-live-preview&lt;/code&gt;, which I&amp;#8217;ll need to spec-drive the &lt;span class=&quot;caps&quot;&gt;RJS&lt;/span&gt; I&amp;#8217;ll have to write.&lt;/p&gt;
&lt;p&gt;Speaking of spec-driving &lt;span class=&quot;caps&quot;&gt;RJS&lt;/span&gt;, I have no idea how to do that, so I need to read a little about that before I get started.&lt;/p&gt;
&lt;p&gt;Unfortunately, after reading &lt;em&gt;Rails Recipes&lt;/em&gt;, I&amp;#8217;m convinced that I need to implement this first before I can learn how to spec-drive it for next time. I find this happens a lot with Rails: it&amp;#8217;s almost &lt;em&gt;too&lt;/em&gt; simple. I paste an implementation into my view and inspect it manually. When I do that, it becomes clear that I need an action to handle the live preview, so although I didn&amp;#8217;t drive the controller behavior with an automated test or spec, I&amp;#8217;m certain I need something. Now I think I can spec-drive the controller behavior. Since this is familiar territory, this should go smoothly. Let&amp;#8217;s see.&lt;/p&gt;
&lt;p&gt;According to &lt;em&gt;Rails Recipes_, all I need to do in my action is render the default template without a layout, which means I will need to move the live preview markup to a new @live&lt;/em&gt;preview.rhtml@ template. I&amp;#8217;ll do that first, to make sure it will be wired together properly.&lt;/p&gt;
&lt;p&gt;After a few false starts, I have these specs:&lt;/p&gt;
&lt;pre&gt;describe &quot;Live Preview for weblog postings&quot; do
  it &quot;should have a section to display the live preview&quot; do
    assigns[:posting] = Posting.new(:content =&amp;gt; &quot;Some @textile@ content.&quot;)
    render &quot;/postings/live_preview&quot;
    
    response.should have_tag(&quot;div#content-live-preview&quot;)
  end
  
  it &quot;should be able to handle nil content&quot; do
    assigns[:posting] = Posting.new(:content =&amp;gt; nil)
    render &quot;/postings/live_preview&quot;
    
    response.should have_tag(&quot;div#content-live-preview&quot;)
  end
end
&lt;/pre&gt;
&lt;p&gt;This is the &lt;code&gt;live_preview.rhtml&lt;/code&gt; template:&lt;/p&gt;
&lt;pre&gt;&amp;lt;div id=&quot;content-live-preview&quot; class=&quot;entry&quot;&amp;gt;
	&amp;lt;%= textilize(@posting.content) if @posting.content %&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;
&lt;p&gt;That decidedly doesn&amp;#8217;t work. When I consult &lt;em&gt;Rails Recipes&lt;/em&gt;, I realize I should display the request parameter &lt;code&gt;posting[content]&lt;/code&gt; and not the Ruby object &lt;code&gt;@posting.content&lt;/code&gt;. For this, I need to learn how to stub the request parameters in the view. Evidently this is as simple as assigning to a &lt;code&gt;params&lt;/code&gt; Hash. I fix the specs to match this new information.&lt;/p&gt;
&lt;pre&gt;describe &quot;Live Preview for weblog postings&quot; do
  it &quot;should have a section to display the live preview&quot; do
    params[:posting] = { :content =&amp;gt; &quot;Some @textile@ content.&quot; }
    render &quot;/postings/live_preview&quot;
    
    response.should have_tag(&quot;div#content-live-preview&quot;)
  end
  
  it &quot;should be able to handle nil content&quot; do
    params[:posting] = { :content =&amp;gt; nil }
    render &quot;/postings/live_preview&quot;
    
    response.should have_tag(&quot;div#content-live-preview&quot;)
  end
end&lt;/pre&gt;
&lt;p&gt;I&amp;#8217;m on a green bar, but the UI doesn&amp;#8217;t work. Firebug tells me that my controller &lt;code&gt;live_preview&lt;/code&gt; method works, but the corresponding &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; is not updating. I don&amp;#8217;t know how to spec-drive this, so I need to hack for a while. It&amp;#8217;s 14.44; let&amp;#8217;s see how long I need to hack.&lt;/p&gt;
&lt;p&gt;Fortunately, only about five minutes. I had one &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; too many.&lt;/p&gt;
&lt;p&gt;After fixing that, and making a few small changes, it looks like I&amp;#8217;m done. I would have preferred to spec-drive the &lt;code&gt;observe_field&lt;/code&gt; code, but at least I have less untested code than I used to. Now I can remove the preview button and the code that went with it. It served its purpose; now it can go to its rest.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/128';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/128&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 12, 2007  19:52
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/rails&quot;&gt;rails&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/adventures-in-RSpec&quot;&gt;adventures in RSpec&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 12 Aug 2007 19:52:04 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/128</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Getting Started with RSpec</title>
      <link>http://jbrains.ca/permalink/127</link>
      <description>&lt;div class='entry posting' id='entry-_posting_127'&gt;
&lt;div class='posting' id='content-_posting_127'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I decided, at last, to investigate &lt;a href=&quot;http://rspec.rubyforge.org/&quot;&gt;RSpec&lt;/a&gt; in the course of my work in Rails. I should be clear about something: I&amp;#8217;m not writing Rails code for profit, only for fun and the experience, so I&amp;#8217;m learning slowly and not really pushing the envelope the way I would on the job. Read this series with that in mind.&lt;/p&gt;
&lt;p&gt;Here is the story I want to implement next: &amp;#8220;Preview postings&amp;#8221;. That story is for this very weblog. When I add an entry, I want to be able to preview it without publishing it. Of course, now that I write that, I realize that I might also want to preview edits to existing entries, but that&amp;#8217;s another story. I suppose this story is &amp;#8220;Preview new postings&amp;#8221;. It&amp;#8217;s good to know that I can still negotiate scope with myself!&lt;/p&gt;
&lt;p&gt;Not being a big RSpec user yet, rather than get stuck writing a story test, I thought I&amp;#8217;d do my bit of design, dive in, then RSpec-drive my model&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fnc1be1a7787074fc5251a6dd0321219461031f192&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;First, I had to install RSpec and RSpec on Rails. That wasn&amp;#8217;t too hard. I followed &lt;a href=&quot;http://rspec.rubyforge.org/documentation/rails/install.html&quot;&gt;these instructions&lt;/a&gt; and issued these commands in the root of my Rails project:&lt;/p&gt;
&lt;pre&gt;
ruby script/plugin install -x svn://rubyforge.org/var/svn/rspec/tags/CURRENT/rspec
ruby script/plugin install -x svn://rubyforge.org/var/svn/rspec/tags/CURRENT/rspec_on_rails
ruby script/generate rspec
&lt;/pre&gt;
&lt;p&gt;After a few seconds, I could run my specs using the new Rake tasks in my project, like &lt;code&gt;spec&lt;/code&gt;. When I run my specs, of course I have none, but I do see weird &lt;span class=&quot;caps&quot;&gt;ANSI&lt;/span&gt; codes in my output. I&amp;#8217;ve &lt;a href=&quot;http://railsforum.com/viewtopic.php?id=8677&quot;&gt;asked a question&lt;/a&gt; about that, and when I get an answer, I&amp;#8217;ll let you know what I found out.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s time to write a spec. My design has a class &lt;code&gt;Posting&lt;/code&gt;, so I figured I would add the notion of &amp;#8220;publishing&amp;#8221; a posting, so that I could save a posting without publishing it. This would allow me to preview it. For this, I decided to add a &lt;code&gt;published_at&lt;/code&gt; timestamp. For that, I wrote this spec:&lt;/p&gt;
&lt;pre&gt;
describe Posting do
  it &quot;should not yet be published&quot; do
    Posting.new.should_not be_published
  end
end	
&lt;/pre&gt;
&lt;p&gt;What I find neat and disturbing at the same time is that RSpec magically looks for a method &lt;code&gt;published?&lt;/code&gt; on &lt;code&gt;Posting&lt;/code&gt; because I&amp;#8217;ve used the &amp;#8220;should&amp;#8230; be&amp;#8221; syntax. I think it&amp;#8217;s neat, but what disturbs me is that I have to know where the underscores go. I expect to write that as &lt;code&gt;Posting.new.should not_be_published&lt;/code&gt; or &lt;code&gt;Posting.new.should_not_be published&lt;/code&gt;. Not exactly &amp;#8220;least surprise&amp;#8221; for me&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn895b7fa041ffda46fd18338d2e27693a6e2e2ba1&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;I satisfy this spec by adding a &lt;code&gt;published?&lt;/code&gt; method than answers &lt;code&gt;false&lt;/code&gt; and move to the next spec.&lt;/p&gt;
&lt;pre&gt;
describe WeblogController do
  it &quot;should be published when it has a published timestamp&quot; do
    new_posting = Posting.new(:published_at =&amp;gt; DateTime.now)
    new_posting.should be_published
  end
end
&lt;/pre&gt;
&lt;p&gt;To satisfy this spec, I add the column &lt;code&gt;published_at&lt;/code&gt; to the &lt;code&gt;postings&lt;/code&gt; table. When I migrate, though, I should mark all the current postings as published, so I make them published as of the time they were created. It&amp;#8217;s not perfectly accurate, but it will do. I haven&amp;#8217;t been tracking the last updated at timestamp. Here is the migration I wrote:&lt;/p&gt;
&lt;pre&gt;
class EnablePreviewForPostings &amp;lt; ActiveRecord::Migration
  def self.up
    add_column :postings, :published_at, :datetime, :default =&amp;gt; nil

    Posting.find(:all).each { | each |
      each.update_attribute(:published_at, each.created_at)
    }
  end

  def self.down
    remove_column :postings, :published_at
  end
end
&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;When I migrate the database, I see that all is well. Now I can implement &lt;code&gt;published?&lt;/code&gt; like so:&lt;/p&gt;
&lt;pre&gt;
class Posting &amp;lt; ActiveRecord::Base
  def published?
    !self.published_at.nil?
  end
end
&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m green, so I can continue&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fndd71eb46739f12fb65776c1bcae27fb7cec60ecd&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;. The essence of preview is that I can save the entry, display it, but not include it in the published entries. To that end, I need to retrospec the method that grabs all the postings so it&amp;#8217;ll exclude unpublished ones. This is the first time I&amp;#8217;m spec-ing a controller, so I&amp;#8217;ll learn something. I create my new spec at &lt;code&gt;$RAILS_ROOT/spec/controllers/posting_controller_spec.rb&lt;/code&gt; and write this:&lt;/p&gt;
&lt;pre&gt;
describe WeblogController do
  fixtures :postings

  it &quot;should only select published entries when browsing&quot; do
    get 'browse'

    postings = assigns[:postings]
    postings.size.should == 3   # 4 articles, 3 published
  end
end
&lt;/pre&gt;
&lt;p&gt;Unfortunately, this doesn&amp;#8217;t find my existing &lt;code&gt;postings&lt;/code&gt; fixture. I get this rude answer:&lt;/p&gt;
&lt;pre&gt;
No such file or directory - /Users/jbrains/Workspaces/dauphin/jbrains.info/spec/fixtures/postings
&lt;/pre&gt;
&lt;p&gt;(I should note that that&amp;#8217;s not the exact output, but the exact output tripped some security filter at TextDrive, so I couldn&amp;#8217;t paste it in. That only cost me a half hour to figure out. Thanks, TextDrive.)&lt;/p&gt;
&lt;p&gt;So what does Google have to say about this? Curiously, one article says &lt;a href=&quot;http://blog.webinforem.com/2007/07/30/lose-the-fixtures-with-rspec/&quot;&gt;Lose the fixtures with rSpec&lt;/a&gt;, which I like, so I&amp;#8217;m inclined to try it. I change my spec to this:&lt;/p&gt;
&lt;pre&gt;
describe WeblogController do
  it &quot;should only select published entries when browsing&quot; do
    Posting.create!(
      :published_at =&amp;gt; nil,
      :title =&amp;gt; &quot;Irrelevant detail&quot;, :content =&amp;gt; &quot;Irrelevant detail&quot;
    )

    get 'browse'

    postings = assigns[:postings]
    Posting.find(:all).size.should == 1
    postings.size.should == 0
  end
end
&lt;/pre&gt;
&lt;p&gt;I don&amp;#8217;t like the irrelevant details, but when I try to switch to test doubles, it&amp;#8217;s a dead end, so I stick with this spec and try to satisfy it. By adding the condition &lt;code&gt;published_at is not null&lt;/code&gt;, I get the job done. The problem, though, is that there are two code paths in my &lt;code&gt;browse&lt;/code&gt; method, depending on whether the &lt;span class=&quot;caps&quot;&gt;URI&lt;/span&gt; is &lt;code&gt;/browse&lt;/code&gt; or &lt;code&gt;/browse/12&lt;/code&gt;. The latter means &amp;#8220;show only articles in category 12&amp;#8221;, which supports my entry tags. I wrote this before I knew about custom routes, so I &lt;em&gt;could&lt;/em&gt; consider refactoring to a custom route and simplifying &lt;code&gt;browse&lt;/code&gt;, but that&amp;#8217;s more work than I&amp;#8217;m willing to take on at 01.25, so I&amp;#8217;ll leave a &lt;code&gt;REFACTOR&lt;/code&gt; comment and add a spec for the &lt;code&gt;/browse/12&lt;/code&gt; case.&lt;/p&gt;
&lt;pre&gt;
describe WeblogController do
  it &quot;should only select published entries when browsing within a single category&quot; do
    category = Category.create!(:name =&amp;gt; &quot;Irrelevant detail&quot;)
    Posting.create!(
      :published_at =&amp;gt; nil,
      :title =&amp;gt; &quot;Irrelevant detail&quot;, :content =&amp;gt; &quot;Irrelevant detail&quot;
    ).categories &amp;lt;&amp;lt; category

    get 'browse', :id =&amp;gt; category.id

    postings = assigns[:postings]
    Posting.find(:all).size.should == 1
    postings.size.should == 0
  end
end
&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;That spec is violated, so I satisfy it. After some refactoring, &lt;code&gt;browse&lt;/code&gt; looks like this:&lt;/p&gt;
&lt;pre&gt;
class WeblogController &amp;lt; ApplicationController
  def browse
    if params[:id].nil?
      @postings_pages, @postings = paginate :postings, :order_by =&amp;gt; default_order, :conditions =&amp;gt; [published_condition], :per_page =&amp;gt; 5
    else
      # REFACTOR Move this to a custom route
      @postings_pages, @postings = paginate_collection(:per_page =&amp;gt; 5, :page =&amp;gt; params[:page]) {
        Posting.find_by_sql([
          %Q(
            select * from postings where postings.id =
            any (select posting_id from tags where category_id = ?)
            and (#{published_condition})
            order by #{default_order}
          ), params[:id]
        ])
      }
    end
  end

  private

  def published_condition
    &quot;published_at is not null&quot;
  end
end	
&lt;/pre&gt;
&lt;p&gt;I&amp;#8217;m pretty happy with that, and I can&amp;#8217;t think of another spec that might be violated, so I move on to the &amp;#8220;preview&amp;#8221; action. I imagine this is as simple as adding a &amp;#8220;preview&amp;#8221; button to the form where I add a posting which creates the entry without publishing it, then display it a new window. This way I can close the window, go back, then press &amp;#8220;save&amp;#8221; when I&amp;#8217;m ready. I might even rename &amp;#8220;save&amp;#8221; to &amp;#8220;publish&amp;#8221; to emphasize the fact that I&amp;#8217;d be publishing the entry. I need to do some more retrospec-ing (&amp;#8220;retrospecking&amp;#8221;?) to prepare for that.&lt;/p&gt;
&lt;pre&gt;
describe PostingsController do
  it &quot;should not publish a new entry when I preview it&quot; do
    post 'preview'

    new_posting = assigns[:posting]
    new_posting.should_not be_published
  end
end	
&lt;/pre&gt;
&lt;p&gt;I can satisfy that easily enough.&lt;/p&gt;
&lt;pre&gt;
def preview
  @posting = Posting.new(params[:posting])
  @posting.save
  redirect_to :action =&amp;gt; &quot;read&quot;, :id =&amp;gt; @posting
end
&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Rather than pop up a window, I&amp;#8217;ll just remember to use the &amp;#8220;Back&amp;#8221; button. My customer side wants a real-time preview, and it&amp;#8217;s now 01.54, so since I&amp;#8217;m not prepared to do that now, my programmer side will ship the simplest thing that could work, get feedback, then add the cool Web 2.0 crap. The next step is to add my preview button, but the scaffold code doesn&amp;#8217;t directly handle two submits for the same form, so I need to do some research. The best solution I find is to add a &lt;code&gt;name&lt;/code&gt; attribute to my buttons and &amp;#8220;&lt;code&gt;case&lt;/code&gt;&amp;#8221; on the name in my controller method. Not pretty, but adequate. I refactored my new entry form to prepare for that, and when I did, I noticed I couldn&amp;#8217;t see any new entries. Of course, that&amp;#8217;s because &lt;code&gt;create&lt;/code&gt; doesn&amp;#8217;t publish. I was hoping to do that later, but I guess I need to do it now. Since I&amp;#8217;m on a green bar, I can retrospec &lt;code&gt;create&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;
describe PostingsController do
  it &quot;should publish a new entry when I publish it&quot; do
    post 'publish'

    new_posting = assigns[:posting]
    new_posting.should be_published
  end
end
&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Evidently my subconscious &lt;em&gt;insists&lt;/em&gt; I rename &lt;code&gt;create&lt;/code&gt; to &lt;code&gt;publish&lt;/code&gt;, so I do that. Now my spec is violated, so I satisfy it. In the process, I introduce the new method &lt;code&gt;publish&lt;/code&gt; on &lt;code&gt;Posting&lt;/code&gt;, which I&amp;#8217;ve spec-driven.&lt;/p&gt;
&lt;pre&gt;
class Posting &amp;lt; ActiveRecord::Base
  def publish
    self.published_at = DateTime.now
    save
  end
end
&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This makes the change to the controller easier.&lt;/p&gt;
&lt;pre&gt;
def publish
  @posting = Posting.new(params[:posting])
  if @posting.publish
    update_tags_for(@posting)
    flash[:notice] = 'Posting was successfully created.'
    redirect_to :controller =&amp;gt; 'weblog'
  else
    render :action =&amp;gt; 'new'
  end
end
&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I only had to change &lt;code&gt;@posting.save&lt;/code&gt; to &lt;code&gt;@posting.publish&lt;/code&gt;. That looks like that works, so I try it manually through the UI&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#fn734d8058d3b46233bec5e25c65e64ef2afb66f1d&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. Now I can publish a new entry, so I need to be able to preview one. It&amp;#8217;s time for another spec.&lt;/p&gt;
&lt;pre&gt;
describe PostingsController do
  it &quot;should preview when I press the 'Preview' button&quot; do
    post 'submit_new', :submit =&amp;gt; &quot;preview&quot;
    assigns[:posting].should_not be_published
  end
end
&lt;/pre&gt;
&lt;p&gt;Satisfying this spec is pretty straightforward, so I retrospec for the &amp;#8216;Publish&amp;#8217; case. After a little refactoring, I have this:&lt;/p&gt;
&lt;pre&gt;
class PostingsController &amp;lt; ApplicationController
  def submit_new
    self.send(params[:submit].downcase)
  end
end
&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Clever, no? Perhaps too clever, but time will tell. It works for me. I&amp;#8217;d worry about a security hole if I weren&amp;#8217;t the only user who could submit this form.&lt;/p&gt;
&lt;p&gt;A quick manual test reveals a problem: &amp;#8220;Couldn&amp;#8217;t find Posting without an ID.&amp;#8221; It looks like I&amp;#8217;m missing a preview-related spec, so I add one&amp;#8230; and when I do, all hell breaks loose. Here&amp;#8217;s the short version of the story:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;I noticed my &lt;code&gt;authorize&lt;/code&gt; filter wasn&amp;#8217;t right, so I fixed it.&lt;/li&gt;
	&lt;li&gt;I didn&amp;#8217;t notice that this would cause all my specs to fail because they don&amp;#8217;t login with an authorized user first.&lt;/li&gt;
	&lt;li&gt;I didn&amp;#8217;t notice that this was the problem, because I made a change to unspec-ed code and didn&amp;#8217;t think anything of it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Great how that happens, no? So I search for something on the topic of how to stub out filters, and I &lt;a href=&quot;http://blog.michaeltrier.com/2007/4/6/stubbing-authentication-in-your-controllers&quot;&gt;read this&lt;/a&gt;, which suggested I write&lt;/p&gt;
&lt;pre&gt;
controller.stub!(:login_required).and_return(false)
&lt;/pre&gt;
&lt;p&gt;to indicate that there&amp;#8217;s no need to login. I tried that and it didn&amp;#8217;t work, so I added this instead:&lt;/p&gt;
&lt;pre&gt;
describe PostingsController do
  before(:each) do
    controller.stub!(:authorize)
  end
end	
&lt;/pre&gt;
&lt;p&gt;Now everyone is authorized in my specs. With that distraction out of the way, I can get back to the point.&lt;/p&gt;
&lt;pre&gt;
describe PostingsController do
  it &quot;shouldn't preview an incomplete entry&quot; do
    post 'preview', :title =&amp;gt; &quot;&quot;, :content =&amp;gt; &quot;&quot;
    assigns[:posting].should be_new_record
    assert_redirected_to :action =&amp;gt; &quot;new&quot;
  end
end
&lt;/pre&gt;
&lt;p&gt;This is violated because I redirect to the wrong place. It&amp;#8217;s an easy fix, but with a little manual testing, I see that while &amp;#8220;Publish&amp;#8221; gives me nice error messages when it fails, &amp;#8220;Preview&amp;#8221; doesn&amp;#8217;t. Upon further inspection, it&amp;#8217;s because &lt;code&gt;preview&lt;/code&gt; redirects to &lt;code&gt;new&lt;/code&gt; on failure, rather than merely rendering it, as &lt;code&gt;publish&lt;/code&gt; does. I should write a spec for that. This time, I add some expectations to the last spec I wrote.&lt;/p&gt;
&lt;pre&gt;
describe PostingsController do
  it &quot;shouldn't preview an incomplete entry&quot; do
    post 'preview', :title =&amp;gt; &quot;&quot;, :content =&amp;gt; &quot;&quot;
    assigns[:posting].should be_new_record
    response.should_not be_redirect
    response.should render_template(&quot;new&quot;)
  end
end
&lt;/pre&gt;
&lt;p&gt;I notice that I had typed &lt;code&gt;assert_redirected_to&lt;/code&gt; up there. Old habits die hard, especially when the fingers can work without the conscious mind. Frightening. This spec is violated because I redirect, so I fix that. Now I see that &lt;code&gt;publish&lt;/code&gt; and &lt;code&gt;preview&lt;/code&gt; are structurally similar.&lt;/p&gt;
&lt;pre&gt;def publish
  @posting = Posting.new(params[:posting])
  if @posting.publish
    update_tags_for(@posting)
    flash[:notice] = 'Posting was successfully created.'
    redirect_to :controller =&amp;gt; 'weblog'
  else
    render :action =&amp;gt; 'new'
  end
end

def preview
  @posting = Posting.new(params[:posting])
  if @posting.save
    redirect_to :action =&amp;gt; &quot;read&quot;, :id =&amp;gt; @posting.id
  else
    render :action =&amp;gt; &quot;new&quot;
  end
end
&lt;/pre&gt;
&lt;p&gt;The differences? The method they invoke on &lt;code&gt;@posting&lt;/code&gt; and the &lt;code&gt;true&lt;/code&gt; branch of the &lt;code&gt;if&lt;/code&gt; statement. It takes a little to refactor this, but I arrive at the following.&lt;/p&gt;
&lt;pre&gt;class PostingsController &amp;lt; ApplicationController
  def publish
    save_posting :publish, :on_success =&amp;gt; lambda { | posting |
      update_tags_for(posting)
      flash[:notice] = 'Posting was successfully created.'
      redirect_to :controller =&amp;gt; 'weblog'
    }
  end

  def preview
    save_posting :preview, :on_success =&amp;gt; lambda { | posting |
      redirect_to :action =&amp;gt; &quot;read&quot;, :id =&amp;gt; posting.id
    }
  end

  private

  def save_posting(save_action_symbol, events)
    @posting = Posting.new(params[:posting])
    if @posting.send(save_action_symbol)
      events[:on_success].call(@posting)
    else
      render :action =&amp;gt; 'new'
    end
  end
end&lt;/pre&gt;
&lt;p&gt;Now, I think, the feature works. Just to be sure, I try a few manual tests. I would prefer to rely on specs, but it&amp;#8217;s 03.21 and I don&amp;#8217;t plan on much more retrospec-ing tonight. One thing I notice is the &amp;#8220;preview&amp;#8221; view doesn&amp;#8217;t say anything about being a preview, so I should fix that.&lt;/p&gt;
&lt;pre&gt;describe PostingsController do
  it &quot;should tell me a preview is a preview&quot; do
    post 'preview', :posting =&amp;gt; {
      :title =&amp;gt; &quot;Irrelevant detail&quot;,
      :content =&amp;gt; &quot;Irrelevant detail&quot;
    }
    
    response.should redirect_to(
      :action =&amp;gt; &quot;preview&quot;,
      :id =&amp;gt; assigns[:posting].id
    )
  end
end
&lt;/pre&gt;
&lt;p&gt;Making that pass is easy: I redirect to &lt;code&gt;preview&lt;/code&gt;, rather than &lt;code&gt;read&lt;/code&gt;. A little manual inspection reveals that nothing about the &amp;#8220;preview&amp;#8221; template makes it look like a preview, so I add a little color to make that more obvious. I&amp;#8217;ll go with this for now:&lt;/p&gt;
&lt;pre&gt;&amp;lt;% @title = &quot;Preview '#{@posting.title}'&quot; %&amp;gt;
&amp;lt;div style=&quot;border: 1px solid; padding: 5px; background: pink&quot;&amp;gt;
&amp;lt;%= render :partial =&amp;gt; &quot;posting&quot; %&amp;gt;
&amp;lt;p style=&quot;text-align: right&quot;&amp;gt;preview&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;It looks reasonably good, and although I have to use the browser&amp;#8217;s Back button to edit the draft, and although the &amp;#8220;edit&amp;#8221; button in the entry doesn&amp;#8217;t do what I expect, I can live with it for now.&lt;/p&gt;
&lt;p&gt;So, my first RSpec experience has been a good one. In spite of a couple of minor problems, I felt I proceeded steadily, if a little slowly. I imagine I could get used to this quite quickly. RSpec on Rails is a terrific plug-in.&lt;/p&gt;
&lt;p&gt;Still, I&amp;#8217;d prefer not to have to create real entries in order to write specs for my controllers. I&amp;#8217;m sure there&amp;#8217;s a better way, but learning what that is will have to wait for another day. It&amp;#8217;s 03.43, I have to pack and get some sleep before traveling from Philadelphia to DC for Agile 2007. Before I go, though, I should deploy.&lt;/p&gt;
&lt;p&gt;In the process of preparing to commit my changes to my code repository, I updated the RSpec plug-ins, and can no longer run my specs. It looks like a problem in one of the plug-ins. Needless to say I&amp;#8217;m not impressed with that. Fortunately, it&amp;#8217;s not a big problem: I simply needed to do &lt;code&gt;script/generate rspec&lt;/code&gt; again, and all was well. As a result, I&amp;#8217;d better freeze my plug-ins before deploying. How do I do that?&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://pmade.com/files/freeze_plugins.rake&quot;&gt;Ask, and ye shall receive&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So while that took longer than it usually does, I was able to preview this entry with the new feature, so I&amp;#8217;m satisfied with it. The next step might be to add real-time preview or the primitive preview feature when editing an entry. Either way, I learned a lot, and I think I&amp;#8217;ll be more comfortable spec-ing my next new feature.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fnc1be1a7787074fc5251a6dd0321219461031f192&quot;&gt;&lt;sup&gt;1&lt;/sup&gt; What&amp;#8217;s the verb for doing &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt;? In &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;, we say &amp;#8220;test-drive&amp;#8221;. What do I say when doing &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; with RSpec? Write me and let me know.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn895b7fa041ffda46fd18338d2e27693a6e2e2ba1&quot;&gt;&lt;sup&gt;2&lt;/sup&gt; I tried &lt;code&gt;Posting.new.should_not_be published&lt;/code&gt;, but it didn&amp;#8217;t work. Shame.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fndd71eb46739f12fb65776c1bcae27fb7cec60ecd&quot;&gt;&lt;sup&gt;3&lt;/sup&gt; You can change some of the language of &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt;, but you&amp;#8217;ll take my green bar from my cold&amp;#8230; well, you get the idea.&lt;/p&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn734d8058d3b46233bec5e25c65e64ef2afb66f1d&quot;&gt;&lt;sup&gt;4&lt;/sup&gt; Yes; I wrote untested, unspec-ed code. I&amp;#8217;m not proud of it. Why do you think I&amp;#8217;m writing this article?&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/127';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/127&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 12, 2007  08:29
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/rails&quot;&gt;rails&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/adventures-in-RSpec&quot;&gt;adventures in RSpec&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 12 Aug 2007 08:29:16 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/127</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Three tutorials at Better Software's Agile Development Practices conference</title>
      <link>http://jbrains.ca/permalink/114</link>
      <description>&lt;div class='entry posting' id='entry-_posting_114'&gt;
&lt;div class='posting' id='content-_posting_114'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I&amp;#8217;d like to announce that I am hosting three tutorials at Better Software&amp;#8217;s new &lt;a href=&quot;http://www.sqe.com/agiledevpractices/&quot;&gt;Agile Development Practices&lt;/a&gt; conference. Please join us and tell your friends!&lt;/p&gt;
&lt;p&gt;(The schedule is subject to change without notice. Don&amp;#8217;t blame me; I&amp;#8217;m just a presenter. Changes affect me, too.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;December 3, 2007 at 8:30 AM&lt;/strong&gt; is &lt;em&gt;Test-Driven Enterprise Code&lt;/em&gt;, my popular tutorial on test-driving code in the enterprise environment. The examples and demo are in Java, but you can apply these concepts to other platforms, including .&lt;span class=&quot;caps&quot;&gt;NET&lt;/span&gt;. This is a half-day tutorial with lecture, demo and Q&amp;amp;A.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;December 3, 2007 at 1:00 PM&lt;/strong&gt; is &lt;em&gt;Incremental Evolutionary Design&lt;/em&gt;. If you&amp;#8217;ve never seen a design evolve before your eyes, here&amp;#8217;s your chance. This is a half-day tutorial that is decidedly hands-on, so bring a laptop with Eclipse 3.2+ and &lt;span class=&quot;caps&quot;&gt;JDK&lt;/span&gt; 1.4 (not Java 5 or 6).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;December 6, 2007 at 10:00 AM&lt;/strong&gt; is &lt;em&gt;Refactoring: Where Do I Start?&lt;/em&gt; If you want to refactor code, but are overwhelmed by how much you have, learn some tips for getting started. Learn about which refactorings are the most safe to do without tests, which parts of your code base are the best places to start refactoring, and how to crack the chicken-and-egg problem of &amp;#8220;I need to refactor to write tests, and I need to write tests to refactor&amp;#8221;. This is a 90-minute tutorial with lecture and Q&amp;amp;A.&lt;/p&gt;
&lt;p&gt;I look forward to meeting you in Orlando this December!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/114';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/114&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 12, 2007  03:16
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 12 Aug 2007 03:16:39 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/114</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Rethinking &quot;Rethinking Stand-Up Meetings&quot;</title>
      <link>http://jbrains.ca/permalink/113</link>
      <description>&lt;div class='entry posting' id='entry-_posting_113'&gt;
&lt;div class='posting' id='content-_posting_113'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Recently, &lt;a href=&quot;http://jbrains.ca/permalink/107&quot;&gt;I commented on&lt;/a&gt; Steve Smith&amp;#8217;s article &lt;a href=&quot;http://www.ayeconference.com/Articles/RethinkingStandUpMeetings.html&quot;&gt;Rethinking Stand-Up Meetings&lt;/a&gt;.  Steve wrote me to clear the air: it&amp;#8217;s the standing up part he takes issue with, and not the meeting. To clarify his position, he has &lt;a href=&quot;http://tinyurl.com/24x8rt&quot;&gt;said more&lt;/a&gt;, and for whatever it&amp;#8217;s worth, I believe his argument is spot-on.&lt;/p&gt;
&lt;p&gt;Even so, if you&amp;#8217;re new to this kind of meeting, you should try standing up first, to interrupt the usual meeting patterns of straying off topic, monopolizing the time, and goofing off. If, after you&amp;#8217;ve held true Stand-Up meetings, you find that standing up has outlived its usefulness, you should consider sitting down; however, if the old habits return, try standing up again. If it didn&amp;#8217;t work, no-one would have called them &amp;#8220;Stand-Up&amp;#8221;s.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/113';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/113&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 12, 2007  02:50
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 12 Aug 2007 02:50:23 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/113</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Cutting through the bullshit</title>
      <link>http://jbrains.ca/permalink/112</link>
      <description>&lt;div class='entry posting' id='entry-_posting_112'&gt;
&lt;div class='posting' id='content-_posting_112'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Sometimes, in the middle of a long, drawn-out discussion, someone says something that cuts to the heart of the matter, or some portion of it. I usually find it refreshing, and I love it, even when I&amp;#8217;m not the one saying it. I just read one and would like to share it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I think that there is one kind of business value, profit.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&amp;#8217;s funny, but funnier in context. Click the title of this entry to read the entire thread, but only if you have some energy to spare.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/112';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/112&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 12, 2007  00:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/writing&quot;&gt;writing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 12 Aug 2007 00:00:45 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/112</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The worst kind of writing</title>
      <link>http://jbrains.ca/permalink/111</link>
      <description>&lt;div class='entry posting' id='entry-_posting_111'&gt;
&lt;div class='posting' id='content-_posting_111'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Some colleagues have drawn my attention to this, from an &lt;span class=&quot;caps&quot;&gt;MSDN&lt;/span&gt; article:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Although the idea of code coverage is simple enough, actually performing code coverage analysis in a non-.&lt;span class=&quot;caps&quot;&gt;NET&lt;/span&gt; environment can be very time consuming, difficult, and expensive. (&lt;a href=&quot;http://msdn.microsoft.com/msdnmag/issues/04/04/CodeCoverageAnalysis/&quot;&gt;Source&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ignoring for a moment whether the statement in the article is true, it&amp;#8217;s pointless, because it sets up a comparison without describing what it&amp;#8217;s comparing to. It&amp;#8217;s a vacuous statement masquerading as a fact. This is the worst kind of writing.&lt;/p&gt;
&lt;p&gt;There are several reasons this statement is valueless:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Even if performing code coverage analysis &lt;strong&gt;can&lt;/strong&gt; be expensive, that doesn&amp;#8217;t mean it &lt;strong&gt;must&lt;/strong&gt; be expensive. Almost anything a person might do &lt;strong&gt;could&lt;/strong&gt; be expensive, if done poorly enough.&lt;/li&gt;
	&lt;li&gt;Performing code coverage analysis can be relatively easy and cheap. I haven&amp;#8217;t done it in a while, but the last time I set up a project with Maven I got code coverage analysis free of charge, and it only took me a half-day to learn and do. Not free, but relatively cheap, considering everything I get for my investment of a half day.&lt;/li&gt;
	&lt;li&gt;The author cites nothing to support this statement, making an opinion (debatable) look like a fact (not up for debate).&lt;/li&gt;
	&lt;li&gt;Later, the author writes &amp;#8220;In the days before .&lt;span class=&quot;caps&quot;&gt;NET&lt;/span&gt;, code coverage was one of the most frustrating parts of my job as a tester.&amp;#8221; On which platforms? In which contexts? At least tell us a story to entertain us. Maybe you were an idiot back then and you&amp;#8217;re smarter now, and your current self would have been able to easily perform code coverage on that project.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I could go on, but I believe you get the point.&lt;/p&gt;
&lt;p&gt;Let me be clear: I don&amp;#8217;t mean to say that one shouldn&amp;#8217;t try to express one&amp;#8217;s opinion in the best possible light; and I don&amp;#8217;t mean to say that one ought not to promote one&amp;#8217;s work. I do both. Still, when one writes, one needs to remember to separate opinion from fact and one needs to support one&amp;#8217;s opinions with at least one concrete anecdote to give the reader an idea that one is not simply talking out of one&amp;#8217;s ass. To do any less is to show an astounding lack of respect for one&amp;#8217;s readers.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/111';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/111&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 09, 2007  08:10
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/writing&quot;&gt;writing&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 09 Aug 2007 08:10:31 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/111</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>I'm up for deletion</title>
      <link>http://jbrains.ca/permalink/110</link>
      <description>&lt;div class='entry posting' id='entry-_posting_110'&gt;
&lt;div class='posting' id='content-_posting_110'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I noticed tonight that my Wikipedia article is being considered for deletion. I was honored to have someone add me to WIkipedia in the first place, but now I have to wonder. I hadn&amp;#8217;t had a window into the self-important Wikirati until now. Their discussion about deleting my bio reads like a bunch of people who talk out of their ass, sprinkled with a person or two who might have a clue.&lt;/p&gt;
&lt;p&gt;To wit:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;#8220;It did list first on Amazon (search term: &amp;#8220;junit java&amp;#8221;, rank order &amp;#8220;bestselling&amp;#8221;; first book with JUnit in title) but I found a book or two with very comparable sales ranks (60,000 for those counting)&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This refers to &lt;em&gt;JUnit Recipes&lt;/em&gt;. The commenter is using its Amazon sales rank to evaluate its importance. In the last year, its sales rank has swung mightily from as high as 9,000th to as low as 190,000th. I&amp;#8217;ve seen it swing from 80,000th to 10,000th in one day, as well as the other way around. To say the least, Amazon&amp;#8217;s sales ranks can&amp;#8217;t be taken too narrowly once you get below the top 1,000 books.&lt;/p&gt;
&lt;p&gt;In case the commenter wants to know, according to my publisher, it has sold over 7,000 copies. For a purely technical book in the agile world, that&amp;#8217;s very good.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;#8220;&amp;#8230;the &lt;span class=&quot;caps&quot;&gt;IEEE&lt;/span&gt; &amp;#8220;standard reference&amp;#8221; quote is not exactly disinterested, considering he works for them.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This refers to the comment that &lt;span class=&quot;caps&quot;&gt;IEEE&lt;/span&gt; software considers &lt;em&gt;JUnit Recipes&lt;/em&gt; to be the standard reference for JUnit users. It&amp;#8217;s worth saying that I write a column for &lt;span class=&quot;caps&quot;&gt;IEEE&lt;/span&gt; Software magazine, but I don&amp;#8217;t &amp;#8220;work for &lt;span class=&quot;caps&quot;&gt;IEEE&lt;/span&gt;&amp;#8221; in the sense of a full-time employee. I have no real desire to advance any particular agenda of the &lt;span class=&quot;caps&quot;&gt;IEEE&lt;/span&gt;. On the contrary, freelance writers tend to write for publications that can advance the writer&amp;#8217;s agenda!&lt;/p&gt;
&lt;p&gt;I will, however, give one commenter some credit:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;#8220;Reads like an ad.&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&amp;#8217;m not surprised. The original version of the article was pasted from a bio I submitted to a conference at which I was speaking, which I certainly wrote as soft advertising copy. Good eye.&lt;/p&gt;
&lt;p&gt;The whole experience makes me feel like I&amp;#8217;m in a room with people talking about me while not acknowledging my presence and not seeming to care what I think about that.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;Epilogue&lt;/strong&gt; on July 30, 2007. It appears they&amp;#8217;ve decided to keep my article around at Wikipedia, for now. My ego is mollified, but I remain uncomfortable about the entire incident. It felt creepy.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/110';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/110&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 28, 2007  04:22
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/writing&quot;&gt;writing&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 28 Jul 2007 04:22:19 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/110</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Google Singleton Detector</title>
      <link>http://jbrains.ca/permalink/109</link>
      <description>&lt;div class='entry posting' id='entry-_posting_109'&gt;
&lt;div class='posting' id='content-_posting_109'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Google Code have released a version of &lt;strong&gt;Singleton Detector&lt;/strong&gt;, which does pretty much what you think it would do, on Java bytecode. I think this is a neat project. I especially like their &lt;span class=&quot;caps&quot;&gt;FAQ&lt;/span&gt; answer &lt;a href=&quot;http://tinyurl.com/2hrse2&quot;&gt;Why Singletons are Controversial&lt;/a&gt;, and the little developerWorks article they refer to.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/109';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/109&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 24, 2007  19:12
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 24 Jul 2007 19:12:41 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/109</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Intentional Software Development</title>
      <link>http://jbrains.ca/permalink/108</link>
      <description>&lt;div class='entry posting' id='entry-_posting_108'&gt;
&lt;div class='posting' id='content-_posting_108'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;What is Intentional Software Development? A half-serious attempt to sidestep the &amp;#8220;how does one define agile?&amp;#8221; question and perhaps ask a question more likely to need more valuable answers. &lt;a href=&quot;http://tinyurl.com/3775me&quot;&gt;Join the discussion.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/108';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/108&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 17, 2007  21:21
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/writing&quot;&gt;writing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 17 Jul 2007 21:21:27 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/108</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Why stand up?</title>
      <link>http://jbrains.ca/permalink/107</link>
      <description>&lt;div class='entry posting' id='entry-_posting_107'&gt;
&lt;div class='posting' id='content-_posting_107'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I just read an article by Steve Smith entitled &lt;a href=&quot;http://www.ayeconference.com/Articles/RethinkingStandUpMeetings.html&quot;&gt;Rethinking Stand-Up Meetings&lt;/a&gt;. I encourage you to read the article, in case you disagree with my interpretations and conclusions here. As always, I might be wrong.&lt;/p&gt;
&lt;p&gt;I was particularly struck by this passage:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When I started my career, I had to wear a tie every day. The next job required a suit. Management told me clothing built teamwork. I think standing up during a meeting is like wearing a tie. My teamwork isn&amp;#8217;t any better wearing a suit and tie than it is when I wear shorts and a t-shirt And I don&amp;#8217;t believe my team&amp;#8217;s effectiveness changes whether they are standing up or sitting down during a meeting.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Steve is welcome to believe his team&amp;#8217;s effectiveness doesn&amp;#8217;t depend on standing up or not standing up, but I&amp;#8217;m worried about his logic. He seems to conclude, incorrectly I think, that since stand-ups don&amp;#8217;t help his team be effective, therefore standing up at a meeting, in general, doesn&amp;#8217;t matter. This is a false generalization.&lt;/p&gt;
&lt;p&gt;While it&amp;#8217;s true that stand-up meetings don&amp;#8217;t &lt;strong&gt;indicate&lt;/strong&gt; team effectiveness, stand-up meetings do at least help people re-think how they meet. If nothing else, it reminds people to get to the point, and when someone drones on, it gives others a chance to practise holding that person to account for droning on. Granted, I&amp;#8217;ve seen bad stand-up meetings, but given that stand-ups have a clear objective and focus on essential communication, when I watch a painful stand-up meeting, I can easily point to it as an example of the team&amp;#8217;s communication problems. It clearly illustrates some ways they need to improve. If nothing else, the way a team behaves in a stand-up meeting tells me a great deal about how it communicates overall. I find that very useful.&lt;/p&gt;
&lt;p&gt;I have also found stand-ups useful as a participant, so they&amp;#8217;re not just useful to a consultant trying to learn about how the team behaves.&lt;/p&gt;
&lt;p&gt;So Steve, while I applaud your title, &amp;#8220;Rethinking Stand-Up Meetings&amp;#8221;, I think the passage I&amp;#8217;ve highlighted is too easy for doubters to excerpt and say to themselves &amp;#8220;See? These stand-ups are as useless as neckties.&amp;#8221; On average, that&amp;#8217;s just not true.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/107';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/107&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 10, 2007  05:22
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 10 Jul 2007 05:22:08 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/107</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Make your users say &quot;Wow!&quot;</title>
      <link>http://jbrains.ca/permalink/106</link>
      <description>&lt;div class='entry posting' id='entry-_posting_106'&gt;
&lt;div class='posting' id='content-_posting_106'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;One of extreme programming&amp;#8217;s practices is &amp;#8220;daily deployment&amp;#8221;. That name sounds imposing, but don&amp;#8217;t ask your team to start deploying daily on Monday. We&amp;#8217;re not in it to deploy for its own sake. Like everything else in XP, deploy &lt;em&gt;intentionally&lt;/em&gt;. There are a number of reasons to deploy your product more frequently:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Practise deployment so that it is effortless when you would normally deploy&lt;/strong&gt;. I find teams underestimate the value of practising &lt;em&gt;in general&lt;/em&gt;, let alone practising deployment. Still, if your deployment mechanism is complex enough that a specialist or team of specialists needs to perform it, then you have room for improvement. Anything you can do to move in the direction of one-button deployment would be good.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deploying more frequently means paying greater attention to &amp;#8220;done&amp;#8221;.&lt;/strong&gt; Many of the teams I work with suffer the same problem: they underestimate what it means to be &amp;#8220;done&amp;#8221;, so they find a lot of unplanned work piles up at the end of an iteration, and because iterations are shorter than they used to be, they experience the pain of delivery more often than they used to. Unfortunately, since they often don&amp;#8217;t really &lt;em&gt;deliver&lt;/em&gt; to a paying customer, these iterations become little more than more frequent, but arbitrary deadlines, and we all hate arbitrary deadlines. It&amp;#8217;s important to make iterations mean something by truly delivering to a real customer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Let your users steer your feature set.&lt;/strong&gt; The most obvious reason to deploy frequently is to let your users give you feedback on what to build, what &lt;em&gt;not&lt;/em&gt; to build, and how well you&amp;#8217;ve built what you&amp;#8217;ve built. When your users are involved in choosing features, they are more likely to be happy with the results, as you tend to build what they plan to use.&lt;/p&gt;
&lt;p&gt;With all this, though, there is another important reason to deploy frequently: &lt;strong&gt;give your users a chance to say &amp;#8220;Wow!&amp;#8221;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A few days ago, I logged in to Google Documents. The night before they must have deployed a new version of the service, because I found a new, nicer user interface. I actually said &amp;#8220;Wow!&amp;#8221; aloud when I saw it, not because it&amp;#8217;s so great, but because I didn&amp;#8217;t expect to see it. It was a pleasant surprise, and whenever you can pleasantly surprise your customers, that&amp;#8217;s certainly to your advantage.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re able to deploy daily, then you&amp;#8217;re able to release your product at any time, especially early. Releasing early helps set up the opportunity for your users to say &amp;#8220;Wow!&amp;#8221; If Google Documents hadn&amp;#8217;t run with the less attractive interface, then I wouldn&amp;#8217;t have been as impressed by the nicer-looking one. To be frank, the nicer-looking interface is nothing special: it looks a lot like Outlook or any other e-mail client I&amp;#8217;ve ever used. Still, it&amp;#8217;s nicer than what was there before, and it&amp;#8217;s that contrast that made the difference for me. Am I advocating releasing crap so that when you release not-crap your users will be impressed? Not at all. I am, however, advocating releasing as soon as you have an adequate product, in part so that you know which bells and whistles are worth building. If, in the process, you impress your users, then so much the better.&lt;/p&gt;
&lt;p&gt;Now early on I wrote that switching from, say, yearly deployment to daily deployment overnight is a mistake. I&amp;#8217;ve made it before. It frustrates the team no end to try to do something its infrastructure is simply not set up to do, so I have changed my approach here. However frequently you deploy your product now, try doubling the frequency. If you released twice last year, release four times this year. If you were releasing every month, then try every two weeks. This way you can build up the infrastructure gradually, rather than having to stop the line and face a host of difficult, frustrating problems at once. There&amp;#8217;s no reason why we have to kill ourselves to move in the direction of deploying daily, so let&amp;#8217;s not do that. Pick one aspect of your deployment mechanism, automate it (or make the current automation easier to use), then try deploying twice as frequently as you currently do. When that becomes more comfortable, double the frequency again. Before you know it, you&amp;#8217;ll be able to deploy every day and your users will say &amp;#8220;Wow!&amp;#8221; even when you release something you feel isn&amp;#8217;t all that impressive.&lt;/p&gt;
&lt;p&gt;How can you lose?&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/106';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/106&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 01, 2007  18:38
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/planning&quot;&gt;planning&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 01 Jul 2007 18:38:54 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/106</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Splitting stories: an example</title>
      <link>http://jbrains.ca/permalink/5</link>
      <description>&lt;div class='entry posting' id='entry-_posting_5'&gt;
&lt;div class='posting' id='content-_posting_5'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Most user stories are too big&amp;mdash;at least, this is how it tends to be for teams making the transition to incremental development and delivery. After discussing the benefits of splitting stories into manageable increments, a team generally goes through (at least) these stages of development:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;splitting stories along process lines, then&lt;/li&gt;
	&lt;li&gt;splitting stories along architectural lines, then&lt;/li&gt;
	&lt;li&gt;splitting stories along procedural lines, then finally&lt;/li&gt;
	&lt;li&gt;splitting stories into smaller stories&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What&amp;#8217;s the difference? Allow me to explain with an example from my own work.&lt;/p&gt;
&lt;p&gt;I am currently working on the xpday.info site, and one of the key themes is collecting registrations for XP Day North America. In particular, we are preparing to host XP Day Montreal 2006 on September 23, 2006. It&amp;#8217;s obvious that &amp;#8220;collect registrations&amp;#8221; is more of a theme than a single story, so I split the theme into a coarse-grained stories like these&amp;mdash;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;anyone can register by paying immediately with &lt;a href=&quot;http://www.paypal.com&quot;&gt;paypal.com&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;anyone can register, then request an invoice&lt;/li&gt;
	&lt;li&gt;anyone can register (and pay for) an entire group, rather than just themselves&lt;/li&gt;
	&lt;li&gt;anyone can register and pay later&lt;/li&gt;
	&lt;li&gt;automatically generate the invoice&lt;/li&gt;
	&lt;li&gt;remind all unpaid registrants on demand&lt;/li&gt;
	&lt;li&gt;automatically remind unpaid registrants on a regular basis&lt;/li&gt;
	&lt;li&gt;a registrant can cancel his registration&lt;/li&gt;
	&lt;li&gt;a registrant can add or remove people from the group&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now these might not &lt;em&gt;seem&lt;/em&gt; coarse-grained, but when your iterations are on the order of a half-day each, it&amp;#8217;s nice to have stories that I can complete in about an hour. (Yes, an hour.) Since I am also the &lt;a href=&quot;http://tinyurl.com/lt84g&quot;&gt;Product Director&lt;/a&gt; on this project, and my primary goal is to be able to collect money from registrants, I identified the first story as the minimum for the first release, and estimated it at about 2 hours. That&amp;#8217;s a little big for a 3-hour iteration, so I want to split it. The first thing I did was a little modeling, to make sure I knew what I meant by &amp;#8220;anyone can register by paying immediately with paypal.com&amp;#8221;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://articles.jbrains.ca/SimpleRegistration-model.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p class=&quot;aside&quot;&gt;Notice that, even here, I jumped to handling the case where the registrant did not pay. I didn&amp;#8217;t realize that until I started writing this entry, so I suppose this is a kind of substitute for pairing. (Thank you.)&lt;/p&gt;
&lt;p&gt;Stepping into the shoes of the teams that allow me to work with them a little, here is what I often see when we try to split the story &lt;em&gt;anyone can register and pay immediately with paypal.com&lt;/em&gt;. First, the split along process lines:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;design&lt;/li&gt;
	&lt;li&gt;code&lt;/li&gt;
	&lt;li&gt;write programmer tests&lt;/li&gt;
	&lt;li&gt;write acceptance tests&lt;/li&gt;
	&lt;li&gt;document&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is a fine checklist, but whether splitting a story into smaller ones or into tasks, this doesn&amp;#8217;t work very well. None of these items produces value &lt;em&gt;on their own&lt;/em&gt;. The closest, perhaps, is &amp;#8220;write acceptance tests&amp;#8221;, but even those don&amp;#8217;t represent value until someone has tried to test-drive with them, because only then do we learn what we missed and what we mis-wrote. A team generally does this in their first planning session after deciding to &amp;#8220;go agile&amp;#8221;. It&amp;#8217;s a good effort, but it does nothing to encourage them to change the way they work. It is certainly not incremental. When we apply the &lt;a href=&quot;http://tinyurl.com/z339d&quot;&gt;&lt;span class=&quot;caps&quot;&gt;INVEST&lt;/span&gt;&lt;/a&gt; test, this split of stories mostly fails. While these &amp;#8220;stories&amp;#8221; are perhaps negotiable and somewhat estimatable (estimable? neither seems correct), they depend on one another, have little inherent value on their own, are likely not all small and are definitely not all testable. We need to try again.&lt;/p&gt;
&lt;p&gt;Once the team gets past this troubling first phase, they tend to split across architectural lines:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;test-drive the UI&lt;/li&gt;
	&lt;li&gt;test-drive the business logic&lt;/li&gt;
	&lt;li&gt;test-drive the database client&lt;/li&gt;
	&lt;li&gt;write acceptance tests&lt;/li&gt;
	&lt;li&gt;document&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now this is an interesting hybrid approach between architectural and process-based splitting. This looks more like a traditional work breakdown structure, which appears to allow for concurrent work, but doesn&amp;#8217;t. (Can you see why?) It is tempting to say that this split satisfies the independent property of &lt;span class=&quot;caps&quot;&gt;INVEST&lt;/span&gt;, but it really doesn&amp;#8217;t, as you would find out as soon as you tried to integrate the work of the individuals who performed each task independently. There is still no value in just the UI or just the database client, the items are smaller, but probably not small enough, and as a result, I would not trust any estimates on them. We need to try again.&lt;/p&gt;
&lt;p&gt;Once the team gets past this second phase, they tend to split across procedural lines:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;collect registrant information&lt;/li&gt;
	&lt;li&gt;integrate paypal.com&lt;/li&gt;
	&lt;li&gt;e-mail registrant after payment&lt;/li&gt;
	&lt;li&gt;e-mail organizer after payment&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is &lt;em&gt;much&lt;/em&gt; better, because at least we no longer see &amp;#8220;write acceptance tests&amp;#8221; and &amp;#8220;document&amp;#8221; as separate tasks. These are almost stories, as they are self-contained bundles of work that include &amp;#8220;code, design, programmer tests, customer tests, document, deploy, install&amp;#8221; and all those wonderful things. There is still one big problem: this split of &amp;#8220;stories&amp;#8221; fails the &amp;#8220;V&amp;#8221; property: just how valuable is collecting registrant information? We certainly can&amp;#8217;t deliver that on its own. We need to try again.&lt;/p&gt;
&lt;p&gt;After the team gets past this third phase, which tends to last a while, they &lt;em&gt;finally&lt;/em&gt; get it, and split the stories into self-contained increments of value:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;register with just e-mail, then pay with paypal.com&lt;/li&gt;
	&lt;li&gt;collect more information from registrant (name, address, phone)&lt;/li&gt;
	&lt;li&gt;notify both registrant and organizer after registration&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&amp;#8217;s it! This story split satisfies all the &lt;span class=&quot;caps&quot;&gt;INVEST&lt;/span&gt; properties&amp;mdash;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Independent&lt;/strong&gt;.&amp;nbsp;It is relatively easy to see how to build each of these stories on its own. #1 is a one-field form whose submit action includes going to paypal.com; #2 is a multiple-field form with a simple &amp;#8220;create&amp;#8221; submit action; #3 is a one-field form whose submit action sends out an e-mail to two recipients. We can build these in any order.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Negotiable&lt;/strong&gt;.&amp;nbsp;We can negotiate the scope of each of these stories. For #1, is it just a link to paypal.com, or do we have to bring the user back to xpday.info? Do we have to handle an incomplete payment, or will humans verify that by looking at the list of registrants and the payers in their paypal.com account? For #2, how much information do we have to collect? For #3, do we send out a standard e-mail? Is it a form e-mail with some user-based personalization? Do we need a tool for writing or changing the e-mail template? For each story, we can easily negotiate economy &lt;em&gt;or&lt;/em&gt; luxury versions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Valuable&lt;/strong&gt;.&amp;nbsp;If we do #1 on its own, then at least we can take their money and we have enough information to contact them after they register. We can easily choose to do #2 or #3 in either order after that. Even better, we can do #2 on its own, if &amp;#8220;the business&amp;#8221; decides that a human requesting payment is good enough, but we really need an automated way to capture registrants&amp;#8217; information. We could even do #3 first: a person could take all the registration information (by phone or e-mail), then enter the registrant&amp;#8217;s e-mail address in a form that sends out a form letter to her as well as the organizer. Any of these could have value, depending on the needs of the customer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Estim(at)able&lt;/strong&gt;. The first story is the biggest, because I don&amp;#8217;t remember how to do the whole paypal.com thing, but I&amp;#8217;m pretty sure I can put the bare bones together in 30 minutes. It might take another 30 minutes to handle a return link, and another 30 minutes for the &amp;#8220;receiving page&amp;#8221; to know whether payment was complete or not. I did this before, but about a year ago. For story #2, we can have something in 15 minutes, then it&amp;#8217;s up to the product director to critique the UI layout and suggest changes. For story #3, we can have a standard e-mail in 15 minutes, it&amp;#8217;ll take another 30 minutes for a form e-mail, and another 30 minutes to be able to change the e-mail template through the web UI. Make that 90 minutes, because we would have to add role-based security for the first time.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Small&lt;/strong&gt;. Only one story is 90 minutes; the others are 30 minutes or less. For a 3-hour iteration, we can fit about 4-8 stories into an iteration. According to my good friend &lt;a href=&quot;http://www.jamesshore.com&quot;&gt;Jim Shore&lt;/a&gt;, that&amp;#8217;s a good number of stories for an iteration, and I agree.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Testable&lt;/strong&gt;. I would hate to see what someone like &lt;a href=&quot;http://www.michaelbolton.net/&quot;&gt;Michael Bolton&lt;/a&gt; would do with these little stories. I should ask him to test the site, just for laughs. (Well, I think I&amp;#8217;d be crying by the end, but &lt;em&gt;he&lt;/em&gt; would be laughing.) As a product director, though, I can easily tell when these stories are complete, so I can easily write acceptance tests for them.&lt;/p&gt;
&lt;p&gt;So there you have it, I hope: a thorough example of splitting a story into smaller increments, each able to be built and delivered independently. If our plan starts to show that we&amp;#8217;re running long, we can cut 2 of the 3 stories, but still meet our primary business objective: collect payments from registrants. That would be good enough for our first release. Now would be a good time to freshen my coffee (during which I have my stand-up meeting with myself), then get to work. We &lt;span style=&quot;font-style: italic;&quot;&gt;absolutely must&lt;/span&gt; have a working first release in the next 3 hours&amp;#8230; or at least that&amp;#8217;s what the product director claims.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/5';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/5&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 30, 2007  04:01
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/stories&quot;&gt;stories&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 30 Jun 2007 04:01:02 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/5</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The myth of the repeatable process</title>
      <link>http://jbrains.ca/permalink/105</link>
      <description>&lt;div class='entry posting' id='entry-_posting_105'&gt;
&lt;div class='posting' id='content-_posting_105'&gt;
&lt;div style='text-align: justify'&gt;
&lt;blockquote&gt;
&lt;p&gt;A &amp;#8220;repeatable process&amp;#8221; is some confused perverted combination of engineering and manufacturing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The only thing you want to repeat is the success. As we cannot predict the future, we can only assume the ability to repeat success is inherent in people that have achieved success.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Maybe the single cleverest thing I&amp;#8217;ve read in months. I only hope Kevin Casey is the guy&amp;#8217;s real name, so I can credit him properly.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/105';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/105&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 30, 2007  01:17
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 30 Jun 2007 01:17:44 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/105</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>XP 2007: a review</title>
      <link>http://jbrains.ca/permalink/104</link>
      <description>&lt;div class='entry posting' id='entry-_posting_104'&gt;
&lt;div class='posting' id='content-_posting_104'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;My review at a glance:&lt;/p&gt;
&lt;table style=&quot;border:1px solid;&quot;&gt;
	&lt;tr&gt;
		&lt;td&gt;Program&lt;/td&gt;
		&lt;td&gt;D&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;Agile Cafe&lt;/td&gt;
		&lt;td&gt;A&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;Location&lt;/td&gt;
		&lt;td&gt;A&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;Attendees&lt;/td&gt;
		&lt;td&gt;B&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;Amenities&lt;/td&gt;
		&lt;td&gt;C&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;Expense&lt;/td&gt;
		&lt;td&gt;C&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;Hotel&lt;/td&gt;
		&lt;td&gt;B&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt;Overall&lt;/td&gt;
		&lt;td&gt;C+&lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Program&lt;/strong&gt;. Part of the grade for the program had to do with its structure: sessions before the conference, 1-1/2 days of &amp;#8220;actual conference&amp;#8221;, then sessions after the conference. Given how it was structured, some people came in for a day or two, then left, rather than sticking around all week. That weakened the experience considerably.&lt;/p&gt;
&lt;p&gt;Part of the grade for the program had to do with the pricing structure. All workshops and tutorials were pay-per-use, which means that I had to know in advance exactly what I wanted to do in order to attend sessions other than my own. While I&amp;#8217;m accustomed to paying extra for tutorials, I find it ridiculous to pay for workshops. In fact, &lt;strong&gt;even the workshop facilitators paid to attend their own workshops&lt;/strong&gt;, albeit at a half-price &lt;span class=&quot;caps&quot;&gt;EUR&lt;/span&gt; 15. I thought that was a joke when I heard about it, but it wasn&amp;#8217;t. I can&amp;#8217;t fathom that, even now after knowing it had happened. It&amp;#8217;s an affront to workshop facilitators. I didn&amp;#8217;t attend any sessions other than my own, because the free content was more than competitive.&lt;/p&gt;
&lt;p&gt;Part of the grade for the program had to do with the keynotes. There were 3 keynotes on the schedule, only 1 of which was any kind of keynote. The presentation from Ferrari was a solid experience report, in which we got a glimpse of an organization that really &lt;em&gt;needs&lt;/em&gt; short iterations. The presentation from Exoftware was a shaky description of a strategy model, including vision, mission and execution. While the presenter attempted to integrate some entertainment, he fell victim to a &amp;#8220;Vista moment&amp;#8221; as well as letting live game-play muddle his point. For about 20 minutes there, I didn&amp;#8217;t know what was happening. &lt;a href=&quot;http://jbrains.ca/permalink/18&quot;&gt;While I can empathize with the presenter&amp;#8217;s plight&lt;/a&gt;, it was still an under-prepared presentation, and his message was lost as a result. Only Kent Beck&amp;#8217;s talk, entitled &amp;#8220;Ease at Work&amp;#8221;, had the element of inspiration that I believe is essential to a keynote, and not even Kent&amp;#8217;s talk was universally lauded. Some felt Kent was trying to shed his former smartass persona, but I don&amp;#8217;t buy it. I believe Kent is more than sincere in describing the next step beyond XP, towards a more holistic notion of ease. Some love it, some don&amp;#8217;t, and I suppose that&amp;#8217;s good for a keynote. It had people talking.&lt;/p&gt;
&lt;p&gt;Part of the grade for the program had to do with a lack of Open Space, which has become a staple at agile conferences.&lt;/p&gt;
&lt;p&gt;By and large, I would have been upset to pay for the conference and be given that program.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Agile Cafe&lt;/strong&gt;. With a lack of Open Space, Charlie Poole led a number of people in developing the &amp;#8220;Agile Cafe&amp;#8221;, a light version of Open Space. We simply designated the tables on the terrace outside the conference hotel as the agile cafe and conducted impromptu discussions there. Some gave real results, as my brief collaboration with Rick Mugridge on his story-testing &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt; and others were simply enjoyable for their ephemeral nature. We chatted, we drank, we argued, it was excellent. I think I might prefer this to Open Space!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Location&lt;/strong&gt;. Como, Italy. Enough said. Go.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Attendees&lt;/strong&gt;. I missed a lot of people in Como, but I also saw some people I hadn&amp;#8217;t seen in a long time. While some key members of the European agile community were not present, I very much enjoyed almost everyone I saw or met. I would like to have met more people, but that&amp;#8217;s partly my fault for not reaching out and partly their fault for not sitting down at an agile cafe table.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Amenities&lt;/strong&gt;. Specifically I mean the conference amenities, and even if they were fantastic, no-one ever told us about them, so we would never have known. The hotel lunch was atrocious for the &lt;span class=&quot;caps&quot;&gt;EUR&lt;/span&gt; 22 per person. Bad enough that we had to book in advance each day in order to attend, but the food was only a shadow of the high quality food almost everywhere else in the city. The coffee breaks were good, once one understood not to wait in line for the espresso bar. It&amp;#8217;s the Italian way, I was told, simply to elbow one&amp;#8217;s way up to the bar and bypass the orderly queue filled with North Americans and meeker Europeans. The coffee itself was excellent, even if it took 20 minutes to get a coffee the first day, before I&amp;#8217;d learned the Italian way. Finally, I felt under-supported in my tutorial. I didn&amp;#8217;t have the right room at first, didn&amp;#8217;t get quick support when I thought I was having &lt;span class=&quot;caps&quot;&gt;LCD&lt;/span&gt; projector problems, and the room itself was &lt;strong&gt;hot&lt;/strong&gt;. Certainly not what I&amp;#8217;m accustomed to as a presenter at other conferences. It&amp;#8217;s as through the industry folks were mostly left to their own devices, and that&amp;#8217;s a shame.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Expense&lt;/strong&gt;. The trip was costly, compared to Oulu, Finland. Food was especially expensive: lunch the first day was &lt;span class=&quot;caps&quot;&gt;EUR&lt;/span&gt; 55 for Sarah and me. Once she found a piadineria, though, our budget came back under control. I was happy to belly up for my share of Argentinian Steer for 4 people at San Agostino&amp;#8217;s. What an experience! Thanks to the Agical folks for suggesting it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hotel&lt;/strong&gt;. The Alberto Terminus was quaint, the people were friendly, the room was comfortable, and the breakfast was diverse and satisfying. Internet access was an extra charge, but not enough to cause us to complain. We spent &lt;span class=&quot;caps&quot;&gt;EUR&lt;/span&gt; 30 on the internet service for the week, which is comparable to most North American hotels.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overall&lt;/strong&gt;. I&amp;#8217;m glad I didn&amp;#8217;t pay to attend the conference proper. I probably would have considered that a complete waste of money. Still, the people, their commitment to self-organization and the charm of Como made it a good experience. The conference gets a D, but the rest of the trip rates a solid A, for a total of C+.&lt;/p&gt;
&lt;p&gt;We look forward to XP 2008 in Limerick, Ireland, which promises to be a wonderful experience.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/104';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/104&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 26, 2007  02:25
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/xp2007&quot;&gt;xp2007&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 26 Jun 2007 02:25:33 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/104</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>XP 2007: Wish they were here</title>
      <link>http://jbrains.ca/permalink/103</link>
      <description>&lt;div class='entry posting' id='entry-_posting_103'&gt;
&lt;div class='posting' id='content-_posting_103'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Not everyone could be here in Como, Italy for XP 2007. I asked for some well-wishes and greetings from those who &lt;del&gt;didn&amp;#8217;t bother to&lt;/del&gt; couldn&amp;#8217;t make the trip. These folks were nice enough to say hello:&lt;/p&gt;
&lt;p style=&quot;float:right;&quot;&gt;&lt;img src=&quot;http://xp2007.jbrains.ca/IljaPreuss.jpg&quot; title=&quot;Ilja Preu&amp;amp;szlig;&quot; alt=&quot;Ilja Preu&amp;amp;szlig;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Ilja Preu&amp;szlig; says, &amp;#8220;Hi, this is Ilja. I&amp;#8217;m sorry I couldn&amp;#8217;t make it out there to be with you this week. I&amp;#8217;m sure you are having great discussions and a lot of fun, so what remains is to wish you better weather than we have here in Karlsruhe. Have a great time!&amp;#8221;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://xp2007.jbrains.ca/xp2007_greeting_lasse_koskela_v2.mov&quot;&gt;Lasse Koskela&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://xp2007.jbrains.ca/XP2007UncleBobGreeting.mov&quot;&gt;Uncle Bob Martin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://xp2007.jbrains.ca/chetSaysHi.3gp&quot;&gt;Chet Hendrickson&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://xp2007.jbrains.ca/ronSaysHi.3gp&quot;&gt;Ron Jeffries&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/103';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/103&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 22, 2007  07:53
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/xp2007&quot;&gt;xp2007&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 22 Jun 2007 07:53:23 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/103</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Test-Driven Enterprise Code at XP 2007</title>
      <link>http://jbrains.ca/permalink/91</link>
      <description>&lt;div class='entry posting' id='entry-_posting_91'&gt;
&lt;div class='posting' id='content-_posting_91'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Once again this year, I am happy to present a tutorial at &lt;a href=&quot;http://www.xp2007.org/&quot;&gt;XP 2007&lt;/a&gt; in Lake Como, Italy. This will be the first time presenting my greatly improved  Test-Driven J2EE, now named Test-Driven Enterprise Code. According to the &lt;a href=&quot;http://tinyurl.com/38pvho&quot;&gt;current XP 2007 schedule&lt;/a&gt;  (as of April 18), my tutorial will be on June 21, 2007 at 2:00 PM. If you&amp;#8217;re planning to attend the conference, I hope you&amp;#8217;ll consider attending this tutorial. You can learn more about the tutorial &lt;a href=&quot;http://tinyurl.com/34qlj3&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I hope to see you there!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/91';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/91&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 16, 2007  05:31
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/xp2007&quot;&gt;xp2007&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 16 Jun 2007 05:31:15 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/91</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>I'm an HTTP moron</title>
      <link>http://jbrains.ca/permalink/84</link>
      <description>&lt;div class='entry posting' id='entry-_posting_84'&gt;
&lt;div class='posting' id='content-_posting_84'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I&amp;#8217;ve spent the past several hours trying to build a simple application in &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt;. I&amp;#8217;m doing this in &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; because I&amp;#8217;ve run out of allowable processes on my TextDrive account, and don&amp;#8217;t want to build a Rails application just to do some very simple dynamic web pages. I&amp;#8217;ve wanted to do an &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; redirect after POSTing a form, so I did what I thought was sensible:&lt;/p&gt;
&lt;blockquote&gt;I went to the &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; manual, searched the function list for &amp;#8220;redirect&amp;#8221;, found &lt;code&gt;http_redirect&lt;/code&gt;, found out it was in a separate library called &lt;code&gt;pecl_http&lt;/code&gt;, learned what the hell &lt;span class=&quot;caps&quot;&gt;PECL&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;PEAR&lt;/span&gt; were, found out why &lt;span class=&quot;caps&quot;&gt;PECL&lt;/span&gt; doesn&amp;#8217;t work so well with &lt;span class=&quot;caps&quot;&gt;MAMP&lt;/span&gt;, finally got a fresh Apache 2.2 and &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; 5.2 installation working on my Mac, finally installed &lt;code&gt;pecl_http&lt;/code&gt; properly with &lt;span class=&quot;caps&quot;&gt;PECL&lt;/span&gt;, all of which only took about six hours.&lt;/blockquote&gt;
&lt;p&gt;Then I found out that I could just have done this:&lt;/p&gt;
&lt;pre&gt;&amp;lt;? header(&quot;Location: http://www.where.i.want.to.go/&quot;); ?&amp;gt;&lt;/pre&gt;
&lt;p&gt;This is one consequence of all these convenience APIs. It&amp;#8217;s easy to forget that sometimes a header is just a header.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/84';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/84&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 08, 2007  00:38
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 08 Jun 2007 00:38:48 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/84</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>ObjectMother, or something like it, for Rails</title>
      <link>http://jbrains.ca/permalink/86</link>
      <description>&lt;div class='entry posting' id='entry-_posting_86'&gt;
&lt;div class='posting' id='content-_posting_86'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;XP Day Toronto 2007 is coming up soon, so I&amp;#8217;m busy working on &lt;a href=&quot;http://www.xpday.info&quot;&gt;xpday.info&lt;/a&gt;, preparing it for the stampede of registrations we expect in the coming weeks. (I can dream.) In the process, I am writing Rails unit tests, which means using fixtures again. I wasn&amp;#8217;t thrilled with my use of fixtures last time I coded Rails seriously, because it felt like the &amp;#8220;One Dataset For All Tests&amp;#8221; anti-pattern that I discovered so painfully on my first XP project. I would be much, much happier if I could have fixtures with the flexibility of named datasets per test, just as I can get with &lt;a href=&quot;http://www.dbunit.org&quot;&gt;DbUnit&lt;/a&gt;. Still, I remembered&lt;br /&gt;
reading &lt;a href=&quot;http://snippets.dzone.com/posts/show/2263&quot;&gt;something about &lt;span class=&quot;caps&quot;&gt;DRY&lt;/span&gt; database configurations&lt;/a&gt; and it gave me an idea for implementing a kind of ObjectMother pattern in &lt;span class=&quot;caps&quot;&gt;YAML&lt;/span&gt;. This is what I did.&lt;/p&gt;
&lt;pre&gt;
dummy: &amp;amp;dummy
  id: 10
  where: &quot;Nowhere, man&quot;
  web_site_url: http://default.xpday.info
  start_date: 2007-01-01
  registration_open_on: 2006-11-01

open:
  &amp;lt;&amp;lt;: *dummy
  id: 11
  registration_open_on: 2006-12-01
&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;dummy&lt;/code&gt; fixture object &lt;strong&gt;must&lt;/strong&gt; provide values for all the required properties, but &lt;strong&gt;should not&lt;/strong&gt; provide values for the optional ones. The idea is for the properties to be overridable so that later fixture objects can specify only those property they care about specifying, accepting defaults for the rest. It seems pretty similar to &lt;a href=&quot;http://www.google.com/url?sa=t&amp;amp;ct=res&amp;amp;cd=1&amp;amp;url=http%3A%2F%2Fwww.thoughtworks.com%2Fobject-mother-easing-test-object-creation.pdf&amp;amp;ei=KRAQRvvHIpO6pwLV2qyZBg&amp;amp;usg=__whSl8WRBKs7t4gGaYEhix46blhA=&amp;amp;sig2=UnVw8FGViiVR6cWPlZ6jOw&quot;&gt;ObjectMother&lt;/a&gt; to me! We&amp;#8217;ll see how it works for me.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/86';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/86&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 06, 2007  17:05
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/xpday&quot;&gt;xpday&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 06 Jun 2007 17:05:39 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/86</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Textile spoken here</title>
      <link>http://jbrains.ca/permalink/102</link>
      <description>&lt;div class='entry posting' id='entry-_posting_102'&gt;
&lt;div class='posting' id='content-_posting_102'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Thanks to &lt;a href=&quot;http://hobix.com/textile/&quot;&gt;Textile&lt;/a&gt; it is now a good deal easier for me to write entries for this weblog. Whether it has an effect on the &lt;em&gt;number&lt;/em&gt; and &lt;em&gt;quality&lt;/em&gt; of entries is yet to be seen, but I really do like the fact that Textile handles both raw &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; and &lt;code&gt;textile&lt;/code&gt; markup the way I&amp;#8217;d expect. Very nice.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/102';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/102&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 06, 2007  01:54
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 06 Jun 2007 01:54:18 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/102</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>An example: the difference between simple and easy</title>
      <link>http://jbrains.ca/permalink/101</link>
      <description>&lt;div class='entry posting' id='entry-_posting_101'&gt;
&lt;div class='posting' id='content-_posting_101'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;My wife has &lt;a href=&quot;http://www.curbly.com/uploads/photos/0000/0000/0305/curtains.jpg&quot;&gt;this shower curtain&lt;/a&gt; for &lt;span class=&quot;caps&quot;&gt;SAT&lt;/span&gt; preparation in mathematics. It&amp;#8217;s mostly for humor, but I suppose it might work for some. It reminds me of a clear example of the difference between simple and easy. Recall that agile suggests doing &amp;#8220;the simplest thing that could possibly work&amp;#8221; and describes &amp;#8220;simple design&amp;#8221; in terms of passing tests, good names, eliminating duplication and removing unnecessary complexity. One of our struggles in teaching simplicity to others is that they often believe that what&amp;#8217;s easiest is what&amp;#8217;s simplest. We don&amp;#8217;t often have good examples, so when I find one, I feel I should share it.&lt;/p&gt;
&lt;p&gt;So the shower curtain describes how to multiply binomials such as &lt;code&gt;(x+5)(x+7)&lt;/code&gt; using the acronym &lt;span class=&quot;caps&quot;&gt;FOIL&lt;/span&gt; for &amp;#8220;first, outer, inner, last&amp;#8221;. This is a mnemonic device to help students remember to multiply all four pairs of terms before adding them together. &lt;span class=&quot;caps&quot;&gt;FOIL&lt;/span&gt;, as a mnemonic device, makes multiplying binomials easier (for some), but it is &lt;strong&gt;not&lt;/strong&gt; simple. Simpler would be to apply the distributive law twice, like so:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;
  (x+5)(x+7)
= (x+5)(x) + (x+5)(7)
= x^2+5x + 7x+35
= x^2+12x+35
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is &lt;strong&gt;simpler&lt;/strong&gt; because in order to do it, I only have to apply a more general technique (the distributive law) twice, rather than knowing both the distributive law and the &lt;span class=&quot;caps&quot;&gt;FOIL&lt;/span&gt; mnemonic. &lt;span class=&quot;caps&quot;&gt;FOIL&lt;/span&gt;, while easier, adds to the student&amp;#8217;s cognitive load by making him remember two things that he could easily believe were different, even though &lt;span class=&quot;caps&quot;&gt;FOIL&lt;/span&gt; is a special case of the distributive law. A student who learns these two techniques might never see the relationship between the two, and so taking the easier route is doubly bad: it adds cognitive load and gets in the way of seeing an important relationship between two seemingly different ideas.&lt;/p&gt;
&lt;p&gt;We see this all the time in designs: two structures that look different are really the same, but you need to dig a little more deeply than usually to see the similarity. If we insist on piling &amp;#8220;easy&amp;#8221; design elements on top of one another, rather than looking underneath for the similarities and removing the superficial duplication, we might never take advantage of our chance to simplify the design. It&amp;#8217;s not as easy right now, but simpler designs tend to put less cognitive load on the reader, and so actually cost less once they&amp;#8217;re built.&lt;/p&gt;
&lt;p&gt;If you have other good examples of the difference between simple and easy, please share them so we can make this concept clearer to those to whom we teach agile programming techniques.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/101';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/101&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 03, 2007  05:35
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 03 Jun 2007 05:35:02 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/101</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Why I don't worry about growth</title>
      <link>http://jbrains.ca/permalink/100</link>
      <description>&lt;div class='entry posting' id='entry-_posting_100'&gt;
&lt;div class='posting' id='content-_posting_100'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I&amp;#8217;ve been reading 37signals&amp;#8217; &amp;#8220;Getting Real&amp;#8221; and I like what I&amp;#8217;ve read so far. The most striking passage so far is this one:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;All the cash, all the marketing, all the people in the world can&amp;#8217;t buy the agility you get from being small.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is one of the reasons I don&amp;#8217;t worry about growth. I intentionally keep my needs modest so that they don&amp;#8217;t conflict with my desire to be free from overcommitment. The more committed you are to longer-term courses of action, the more money you need, the more you need to do what you&amp;#8217;ve been doing (but better, faster, cheaper) and the less intentional your work becomes.&lt;/p&gt;
&lt;p&gt;Have you ever looked at a child and said, &amp;#8220;Don&amp;#8217;t be in a hurry to grow up; it&amp;#8217;s not as great as it looks&amp;#8221;? I feel the same way about small companies: don&amp;#8217;t be in such a hurry to grow up; it&amp;#8217;s not as great as it looks.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/100';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/100&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 31, 2007  22:57
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/review&quot;&gt;review&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 31 May 2007 22:57:30 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/100</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Reaction to XP Day Toronto 2007</title>
      <link>http://jbrains.ca/permalink/98</link>
      <description>&lt;div class='entry posting' id='entry-_posting_98'&gt;
&lt;div class='posting' id='content-_posting_98'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;XP Day Toronto 2007 was successful, even though attendance was down quite a bit from 2005. I am learning to be happy about a smaller event, as the more intimate setting is good for almost everyone participating. We have some changes to make to the format, but I can safely say that the experiment we call XP Day North America is mostly giving good results, so we intend to continue. Next stop, Manhattan on September 22, 2007, with details to come soon.&lt;/p&gt;
&lt;p&gt;The XP/Agile Toronto user group hosted a session entitled &amp;#8220;What we learned at XP Day Toronto 2007&amp;#8221; soon after our event, featuring five talks from various people at Intelliware. It was certainly satisfying to see people excited about the event and happy with their attendance and involvement. Brian Marick certainly delivered a thought-provoking keynote and Open Space was a definite hit, thanks mainly to Deb Hartmann&amp;#8217;s expert facilitation. One person, Jason Cheong-Kee-You, wrote about his reactions to the day at length on &lt;a href=&quot;http://tinyurl.com/2629on&quot;&gt;his weblog&lt;/a&gt;, which makes for good reading. If you&amp;#8217;d like details, I&amp;#8217;m sure he&amp;#8217;d provide them.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/98';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/98&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 30, 2007  21:33
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/xpday&quot;&gt;xpday&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 30 May 2007 21:33:17 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/98</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Don't go too fast</title>
      <link>http://jbrains.ca/permalink/99</link>
      <description>&lt;div class='entry posting' id='entry-_posting_99'&gt;
&lt;div class='posting' id='content-_posting_99'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;In his keynote at XP Day Toronto 2007, Brian Marick cautioned against the team going too fast early in a project, because it sets up false expectations about the team&amp;#8217;s long-term velocity. He said, in essence, that if your customers are really happy, then you&amp;#8217;re probably going too fast. In a blog comment, Mike Wasserman wrote&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It is statements like this that make me cringe and give XP a bad name.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I understand Mike&amp;#8217;s concern, but I think his reaction points to a problem with most approaches to software development: teams are motivated to attempt to go more quickly than they are able to go. This appears to be simply the nature of business: shareholders (whether for a public or privately-held company) want growth, which comes from market dominance, which comes in part from speed to market. It seems rational, then, for the business to want to produce software (whether products or support for the rest of the business) as quickly as possible. The problem, though, is when a business &lt;strong&gt;plans&lt;/strong&gt; to deliver software &lt;strong&gt;more quickly than possible&lt;/strong&gt; given their current people. Typically, this causes teams to do one of two things: try to go too quickly and deliver poor software, or over-react and hold back their velocity in protest. Neither achieves the desired goal of sustained growth through maximum velocity over time. So what can we do?&lt;/p&gt;
&lt;p&gt;One option is to timebox our overdrive period. If we truly need the software organization to sacrifice in the short term to &amp;#8220;get over a hump&amp;#8221;, then we owe them an explanation. Specifically, we should tell the software organization how long we intend them to work in overdrive, why we need them to do so, under what conditions the overdrive period will end and how we will compensate them for working in overdrive. If we do this, we greatly increases our chances of guarding our capital investment in our top people, a competitive advantage that I believe is largely ignored in today&amp;#8217;s marketplace. Software people are reasonable people: if you tell them you need them to work 60-hour weeks for 4-6 months until revenue is up to $400k/month, after which time they&amp;#8217;ll receive 4 paid weeks of vacation and the opportunity to reorganize their teams however they like, then they can make the decision whether to pitch in or not. If not, you can replace them with more willing people while the cost to replace them is lower. For the ones that stay on, they will most likely get behind you and &lt;strong&gt;push hard&lt;/strong&gt;, which is exactly what you need at a time like this. To do otherwise is to create an army of people who only cash their paycheques during your biggest crunch and who leave the moment it&amp;#8217;s over. I recognize that being this transparent is frightening, but as I have become more transparent as a businessman, I&amp;#8217;ve been happy with the results.&lt;/p&gt;
&lt;p&gt;Another option is to fix the problems that led to the overdrive situation in the first place. There are many reasons to need to deliver software more quickly than you&amp;#8217;re capable of: an overzealous sales organization, poor communication between the software teams and salespeople, desperation due to long periods with low sales, and generally unplanned growth. This list is by no means exhaustive, but it&amp;#8217;s enough for the current discussion. All these problems have a common source: the quest for growth by wishful thinking and not through planning. If your company intends to grow by some magical rate year over year, you need to have a plan that supports that growth, and if delivering software is a key component of achieving that growth, then you need an accurate picture of how quickly your software organization can deliver. Remember the lessons of the Theory of Constraints: the throughput of a system is bounded by the throughput of its slowest component. Not only is there no point in selling software you can&amp;#8217;t deliver, but it actually hurts your business to try to do it, and from a number of angles: disloyal customers or customers who refuse to pay, driving good customers to your competition, higher employee turnover including your best people moving to the competition, and decreasing trust between the &amp;#8220;front and back of the house&amp;#8221;. If your organization can&amp;#8217;t execute on your growth plan, then you need to consolidate your organization first, because hoping for the best is not a management strategy. Perhaps you need to invest in training, in more people, in different people, or perhaps you simply need to rein in your sales staff a little. Satisfy one customer, then two, then four, then 20. Even in industries where this seems impossible, it must be better than the alternative of abject failure to satisfy anyone.&lt;/p&gt;
&lt;p&gt;So when Marick says, &amp;#8220;don&amp;#8217;t go too fast&amp;#8221;, don&amp;#8217;t take it to mean that we should slow down for its own sake; we need to slow down because otherwise the business will make unrealistic plans based on our unsustainable performance, and once they start to do that, it&amp;#8217;s a ticking timebomb, and only a matter of time before the entire house of cards falls down.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/99';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/99&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 28, 2007  17:24
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/planning&quot;&gt;planning&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 28 May 2007 17:24:48 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/99</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Catalysts' Coding Contest: neat!</title>
      <link>http://jbrains.ca/permalink/97</link>
      <description>&lt;div class='entry posting' id='entry-_posting_97'&gt;
&lt;div class='posting' id='content-_posting_97'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I just found out about a very neat programming contest. If you want to test your skills against people from around the world, &lt;a href=&quot;http://catalysts.cc/?id=contest&quot;&gt;here is your chance&lt;/a&gt;. If we&amp;#8217;re settled in enough after the move to Dauphin, I will participate myself.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/97';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/97&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 18, 2007  04:37
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 18 May 2007 04:37:38 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/97</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>May 29, 2007 at the TPMA</title>
      <link>http://jbrains.ca/permalink/96</link>
      <description>&lt;div class='entry posting' id='entry-_posting_96'&gt;
&lt;div class='posting' id='content-_posting_96'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I will be speaking at the Toronto Product Management Association in downtown Toronto on May 29, 2007. We will discuss what it means to manage a product in an agile environment, why it&amp;#8217;s difficult and what we can do about it. If you&amp;#8217;re interested in attending a highly interactive discussion of the topic, do join us! Click the title of this entry for details.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/96';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/96&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 12, 2007  02:15
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 12 May 2007 02:15:47 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/96</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Post-agile? I don't get it; I don't know why I care so much</title>
      <link>http://jbrains.ca/permalink/93</link>
      <description>&lt;div class='entry posting' id='entry-_posting_93'&gt;
&lt;div class='posting' id='content-_posting_93'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I just finished reading some of Jonathan Kohl&amp;#8217;s writings about &amp;#8220;post-agile&amp;#8221;, which he describes (and I paraphrase) as going past the agile doctrine by taking what works and leaving what doesn&amp;#8217;t work behind. He seems to emphasize leaving &amp;#8220;the hype&amp;#8221; behind, too. I don&amp;#8217;t know why this line of thought bothers me, beyond a very basic logical fallacy I can&amp;#8217;t help but see: the notion that agile is the hype or that agile is the practices. It isn&amp;#8217;t now, and it never was. Being agile &lt;em&gt;requires&lt;/em&gt; adapting the process to local conditions, so I can&amp;#8217;t understand why adapting the process to local conditions would be something other than agile. I hope stating it that way makes the fallacy apparent.&lt;/p&gt;
&lt;p&gt;Kohl concludes &lt;a href=&quot;http://www.kohl.ca/blog/archives/000184.html&quot;&gt;one of his pieces&lt;/a&gt; with this:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
At the end of the day, Post-Agilism is just an idea, or a model that some of us find helpful right now. Don&amp;#8217;t find it helpful? Don&amp;#8217;t worry about it. We aren&amp;#8217;t trying to change minds, &lt;strong&gt;we&amp;#8217;re just trying to get people to think about what they are doing&lt;/strong&gt;. If Agilism works for you, great! If something else does, that&amp;#8217;s great too. There are a lot of good ideas to choose from, particularly if you expand your view.&lt;/blockquote&gt;
&lt;p&gt;I have added emphasis for the portion I want to deal with. Since when can one be agile without thinking about what one is doing? The essence of Scrum is &amp;#8220;inspect and adapt&amp;#8221;. From what I understand, you can&amp;#8217;t do either of those without thinking about it quite deeply. The essence of XP, as Beck  described it even in the first edition of &amp;#8220;XP Explained&amp;#8221; is pick a problem, solve it &amp;#8220;the XP way&amp;#8221;, then repeat on the next problem. You can&amp;#8217;t do that without thinking about what you&amp;#8217;re doing. What I dislike about Kohl&amp;#8217;s post-agile formulation is that it assumes that agile is the worst way it&amp;#8217;s practiced: thoughtlessly. That is not agile; and Kohl&amp;#8217;s conception is not post-agile. It might be post-bad-agile or post-dogmatic-agile, but what he calls post-agile is really just agile. This, in spite of his claim to the contrary. (My apologies for the long excerpt to come; I will interleave my comments.)&lt;/p&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;p&gt;&lt;strong&gt;Isn&amp;#8217;t This Really Just &amp;#8220;Pure Agile&amp;#8221;? Aren&amp;#8217;t You Just Reacting to Agile Corruption?&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;No, we are reacting and adapting to experience on our own projects, and to change. Furthermore, post-agile thinkers I&amp;#8217;ve spoken to tend to be contextualists who, like the Context Driven Testing community, believe the value of a practice depends on its context. [&amp;#8230;]&lt;/p&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But this &lt;em&gt;is&lt;/em&gt; agile. From what I understand, agile is what the various schools (XP, Scrum, &lt;span class=&quot;caps&quot;&gt;FDD&lt;/span&gt;, &lt;span class=&quot;caps&quot;&gt;DSDM&lt;/span&gt;, Crystal) all have in common, and they are all context-driven. Some recommend a set of practices to start with, but once you&amp;#8217;ve mastered the practices, you know which to use when. Others give you the responsibility to discover the practices you need. Each is driven by a set of principles and values, among which is the notion that we continually improve the way we work. I don&amp;#8217;t think any is considered dogmatic, although XP is strongly interpreted by many to say, &amp;#8220;Don&amp;#8217;t mess with it until you understand how it works; and you won&amp;#8217;t understand how it works until you try it as is.&amp;#8221; Agile or not, I simply find that advice generally sensible.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ravi Mohan: &amp;quot;&amp;#8230;each agile practice (or the whole lot together with an appropriate label) makes sense only in certain contexts (certain types of enterprise software, with certain types of teams) even in the &amp;#8220;uncorrupted&amp;#8221;, &amp;#8220;pure&amp;#8221; state. A &amp;#8220;pure agile&amp;#8221; process is not superior to a &amp;#8220;non agile&amp;#8221; process de facto. Agile is not the &amp;#8220;best way we know how to create software&amp;#8221;. It is one way we know how to create software. It has no intrinsic superiority (except against obvious straw men like &amp;#8220;pure waterfall&amp;#8221; for projects with rapidly changing requirements). &amp;#8220;Post Agile&amp;#8221; is just an adjective that describes people who have used agile extensively, adopted what made sense, rejected the parts that didn&amp;#8217;t work (and the hype) and choose to think for themselves. It is not a reaction against the perceived corruption of an originally perfect process.&amp;quot; (From comments on Vlad Levin&amp;#8217;s blog.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I believe Kohl (in quoting Mohan) confuses &amp;#8220;agile&amp;#8221; for &amp;#8220;a set of practices&amp;#8221; here. He may do this just because he uses the term &amp;#8220;agile&amp;#8221; to mean &amp;#8220;a set of agile practices&amp;#8221;, but the larger community has been saying &lt;strong&gt;for years&lt;/strong&gt; that agile is &lt;em&gt;not&lt;/em&gt; the practices. Ron Jeffries says that XP is what you do after you&amp;#8217;ve mastered the practices, echoing Charlie Parker&amp;#8217;s line that jazz is what you do once you get past the rules of music and just play. Bill Caputo says, &amp;#8220;XP isn&amp;#8217;t out there; it&amp;#8217;s in here.&amp;#8221; Agile is certainly the same: agile is what you do once you internalize the practices; agile, it seems, &lt;em&gt;is&lt;/em&gt; Kohl&amp;#8217;s &amp;#8220;post-agile&amp;#8221;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A popular misconception is that if you are in an iterative lifecycle, focus on communication, customer involvement, value testing, and delivering great software, then you are, by definition &amp;#8220;Agile.&amp;#8221; [&amp;#8230;]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&amp;#8217;m pretty sure &amp;#8220;agile&amp;#8221; was defined at Snowbird as &amp;#8220;what&amp;#8217;s the least we can do and still build great software?&amp;#8221; Recall that &amp;#8220;agile&amp;#8221; is the term only because people didn&amp;#8217;t want to be called &amp;#8220;lightweights&amp;#8221;, otherwise it&amp;#8217;s likely that &amp;#8220;lightweight&amp;#8221; would have been the term. So if &amp;#8220;agile&amp;#8221; isn&amp;#8217;t its definition, then what is it? It seems to me that being iterative and evolutionary with excellent communication is one sure way to deliver good software without unneccessary process. That sounds agile to me.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The Agile movement did not create these practices, and does not have sole ownership of them. Many of us were doing these things on projects in the pre-Agile era. In my own experience, I was on teams that used iterative lifecycles with two week iterations in the late &amp;#8216;90s. We looked at Rapid Application Development and adopted some of those practices, and retained what worked. We also looked at &lt;span class=&quot;caps&quot;&gt;RUP&lt;/span&gt;, and did the same thing, and a big influence at that time was the Open Source movement. If you go back to the &amp;#8217;60s, thirty-forty years before the Agile Manifesto was created, Jerry Weinberg describes something very similar to extreme programming on the Mercury project. That doesn&amp;#8217;t mean the Agile movement is wrong, it just shows that there are other schools of thought other than Agile when it comes to iterative, incremental development.&lt;/p&gt;
&lt;p&gt;The Agile movement did not invent these practices &amp;#8211; they&amp;#8217;ve been around for a long time. Some of us were very excited about what the Agile movement brought to the industry, because we had also been working in that direction. What the Agile movement gave to us was a shared language, a set of tools and practices and advances in these techniques that can be very useful. The Agile movement has given us a lot of innovative ideas, but we can look at pre-Agile and Agile eras for great ideas and inspiration.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This sidebar is irrelevant to the discussion. The agile community doesn&amp;#8217;t lay claim to inventing these ideas, although in some pockets, it claims to have re-packaged them in interesting ways. Much of the agile movement has been about rediscovering and repopularizing grand old ideas that were lost in the furor of the &lt;span class=&quot;caps&quot;&gt;CASE&lt;/span&gt; revolution and its flawed thesis that programming is just typing. I dislike assuming intent in others, but I have to ask: is Kohl angry because he feels the agile movement co-opted ideas that he held dear? I don&amp;#8217;t know that it matters, except to further understand his perspective, which I find troubling in its inherent contradiction. After all, if agile is nothing new, then certainly neither is post-agile.&lt;/p&gt;
&lt;p&gt;The bottom line is that whenever I work with a new team, when I find it&amp;#8217;s time to introduce a new practice, I start with something appropriate from XP, then adapt as needed. If it&amp;#8217;s a new team starting out, I try to use as many of the XP practices as make sense, then fix what&amp;#8217;s broken. I&amp;#8217;ve done this from the moment I had experienced enough XP to feel comfortable doing it. According to Kohl, that makes me post-agile. According to everything I&amp;#8217;ve ever read and known on the subject, that makes me agile.&lt;/p&gt;
&lt;p&gt;But why spend an hour writing about this? After all, Kohl says he&amp;#8217;s not out to change the hearts and minds of men. What does it matter? Well, let me share something I read on &amp;#8220;The Daily &lt;span class=&quot;caps&quot;&gt;WTF&lt;/span&gt;&amp;#8221;, now called worsethanfailure.com:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;a href=&quot;http://worsethanfailure.com/Comments/AddComment.aspx?ArticleId=4991&amp;ReplyTo=128469&amp;Quote=Y&quot;&gt;&lt;br /&gt;
To a manager, refactor means to upgrade or add functionality. It is a danger of us techies using our language to explain something to non-techies.&lt;/a&gt;&lt;/blockquote&gt;
&lt;p&gt;You might well imagine my jaw dropping upon reading this. A term has been warped to mean its exact opposite. How could that possibly help me communicate to both programmers and managers in the course of my work as a change agent? So it is with Kohl&amp;#8217;s &amp;#8220;post agile&amp;#8221;: if he calls &amp;#8220;post agile&amp;#8221; what large numbers of people already call &amp;#8220;agile&amp;#8221;, how does that help us communicate?&lt;/p&gt;
&lt;p&gt;It takes me one step closer to simply keeping bees and growing asparagus.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;PS, added May 10, 2007: &lt;a href=&quot;http://www.infoq.com/news/2007/05/is-post-agile-just-agile&quot;&gt;It seems these opinions have gained some external visibility&lt;/a&gt;. It&amp;#8217;s always nice to know someone&amp;#8217;s reading.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/93';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/93&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 10, 2007  16:33
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 10 May 2007 16:33:39 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/93</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Speaking: May 17, 2007, Ames, Iowa, USA</title>
      <link>http://jbrains.ca/permalink/95</link>
      <description>&lt;div class='entry posting' id='entry-_posting_95'&gt;
&lt;div class='posting' id='content-_posting_95'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;It&amp;#8217;s a little last-minute, but I&amp;#8217;ll be speaking at the Agile Iowa user group in Ames on Thursday, May 17, 2007. It will be an abbreviated preview of &amp;#8220;My Greatest Misses: XP 2000-2007&amp;#8221;, which I will present as a tutorial at Agile 2007. I will tell stories of how I have failed adopting and evangelizing XP over the years, what I&amp;#8217;ve learned from those failures and what I do differently now. It will be a lot of fun! If you&amp;#8217;re in the general area, please drop by and join us! Click the title of this entry for details, which should be posted soon.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/95';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/95&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 10, 2007  03:32
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile2007&quot;&gt;agile2007&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 10 May 2007 03:32:47 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/95</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Travelocity.ca can't add, either</title>
      <link>http://jbrains.ca/permalink/94</link>
      <description>&lt;div class='entry posting' id='entry-_posting_94'&gt;
&lt;div class='posting' id='content-_posting_94'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I feel sorry for book-keepers, especially because I&amp;#8217;m acting as one for my own company. (Don&amp;#8217;t do it. I&amp;#8217;m a masochist.) In particular, I just booked a flight on travelocity.ca, and their ever-helpful receipt shows an astounding carelessness. Here is a recreation of an excerpt.&lt;/p&gt;
&lt;pre&gt;
Total airline charges........ CAD 614.56
Total Travelocity.ca fees.... CAD   6.60
Total GST.................... CAD  33.73
Total........................ CAD 621.16
&lt;/pre&gt;
&lt;p&gt;Then, later&lt;/p&gt;
&lt;pre&gt;
Your credit card statement may show separate airline charges for each passenger, as listed below:
Joseph Rainsberger: CAD 647.89 
&lt;/pre&gt;
&lt;p&gt;So in order to put this into QuickBooks, I have to know all these things:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;The &lt;span class=&quot;caps&quot;&gt;GST&lt;/span&gt; on the Travelocity.ca fees are $0.40, and on the flight, the remaining $33.33.&lt;/li&gt;
&lt;li&gt;Travelocity.ca can&amp;#8217;t add: the total is &lt;span class=&quot;caps&quot;&gt;CAD&lt;/span&gt; 654.89, not &lt;span class=&quot;caps&quot;&gt;CAD&lt;/span&gt; 612.21.&lt;/li&gt;
&lt;li&gt;The separate fee, which shows up as &amp;#8220;travel services&amp;#8221; on my credit card, is $7.00 total.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;&amp;#8230;and this is when the charges add up nicely&amp;#8230; &lt;em&gt;eventually&lt;/em&gt;. Don&amp;#8217;t get me started on Travelocity.ca and European flights.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s a big company. Can&amp;#8217;t they teach their systems to add?&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/94';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/94&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 09, 2007  19:47
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 09 May 2007 19:47:57 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/94</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>99 bottles of beer...</title>
      <link>http://jbrains.ca/permalink/92</link>
      <description>&lt;div class='entry posting' id='entry-_posting_92'&gt;
&lt;div class='posting' id='content-_posting_92'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have been accepted into the annals of computing history with &lt;a href=&quot;http://www.99-bottles-of-beer.net/language-ruby-1436.html&quot;&gt;my interpretation of &amp;#8220;99 bottles of beer&amp;#8221; in Ruby&lt;/a&gt;. I&amp;#8217;m so proud!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/92';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/92&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 06, 2007  17:09
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 06 May 2007 17:09:25 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/92</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>A sign you're mocking too much</title>
      <link>http://jbrains.ca/permalink/90</link>
      <description>&lt;div class='entry posting' id='entry-_posting_90'&gt;
&lt;div class='posting' id='content-_posting_90'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I recently read &lt;a href=&quot;http://tinyurl.com/23yh3q&quot;&gt;this article at mockobjects.com&lt;/a&gt; and it reminded me of advice I give when I teach people about test doubles.&lt;/p&gt;
&lt;p&gt;At some point after you learn how to use test doubles, and perhaps dabble with JMock or Mocha, you notice that you&amp;#8217;re using test doubles &lt;em&gt;everywhere&lt;/em&gt;. With any luck, you notice it, stand back, scratch your head, then wonder, &amp;#8220;What exactly am I testing here?&amp;#8221; If you&amp;#8217;ve reached that stage, then you&amp;#8217;re ready for this advice.&lt;/p&gt;
&lt;p&gt;First, remember that everything in your system is either a Service, Entity or Value. I didn&amp;#8217;t make those names up: I learned them from Eric Evans in Domain-Driven Design.&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;value&lt;/em&gt; has no lifecycle, is usually immutable and behaves with value semantics. This last point mostly means that &amp;#8220;equals&amp;#8221; depends on the value and not the location in memory. Strings, numbers, points, lists, monetary amounts, intervals, instants in time, these are values.&lt;/p&gt;
&lt;p&gt;An &lt;em&gt;entity&lt;/em&gt; has a lifecycle, is usually persisted, and behaves with ID semantics. That means that two entities can look the same by value, but represent different things, and therefore aren&amp;#8217;t equal. Think of George Foreman&amp;#8217;s kids, all named George. If your system only stores the child&amp;#8217;s name and its parents&amp;#8217; names, then all those Georges look the same, but each is unique as a snowflake. Entities often use values. People, accounts, banks, transactions, these are entities.&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;service&lt;/em&gt; co-ordinates work and provides an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; for applications to use it. A service is transient, can be pluggable and is often best when stateless. The notion of equality doesn&amp;#8217;t much make sense for a service, and in many applications, one instance of a service is enough. (That doesn&amp;#8217;t mean services should be singletons in the Gang of Four sense! They might be singletons in the Spring dependency injection container sense.) Services mostly figure out which entities need changing or retrieving, then either change or retrieve them. Transfer funds, deposit, withdraw, post interest, these are services.&lt;/p&gt;
&lt;p&gt;Now that we have a common language that&amp;#8217;s probably wrong, but suitable enough for the current purpose, here is the advice I have to offer.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Never mock values, sometimes mock entities, but mock services freely.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That&amp;#8217;s the version that&amp;#8217;s easy to remember. Here&amp;#8217;s the longer answer.&lt;/p&gt;
&lt;p&gt;If you want to mock a value, then you&amp;#8217;re not using it as a value, or your &amp;#8220;value&amp;#8221; is really trying to be an entity, or worse, a service. Values just are. They don&amp;#8217;t persist themselves, they don&amp;#8217;t find themselves&amp;#8230; you just instantiate them, calculate with them, then throw them away. Entities will typically hold onto them, and when entities persist, the values go with them, but typically, that&amp;#8217;s the entity&amp;#8217;s concern, and not the value&amp;#8217;s. A value should be so simple that there&amp;#8217;s no benefit to mocking them. You should have no test doubles for values. If you do, it&amp;#8217;s time to uncover what mislaid responsibility your value has, extract it out, then try again.&lt;/p&gt;
&lt;p&gt;You might want to mock an entity, but more likely you want to mock how you got the entity. Again, I use the term I learned from Evans: Repository. A repository is a place to look up and store entities. A repository is a service for keeping track of entities. Most of the time, I should be able to instantiate an entity and use it, so there&amp;#8217;s no need to use a test double in its place. Typically, when you think you want to mock an entity, first try mocking the repository from whence it came.&lt;/p&gt;
&lt;p&gt;Services, you can mock with impunity. In fact, the only time not to mock a service is when you&amp;#8217;re testing the service. Since services are typically interfaces and pluggable, you&amp;#8217;ll want to use test doubles when you test how the application uses the service, or how a service uses another service. Since services tend to use repositories, entities and values, when you test the service, you&amp;#8217;ll likely use test doubles for the repositories, but not for the entities nor the values.&lt;/p&gt;
&lt;p&gt;So that&amp;#8217;s a summary of when I mock what. Of course, given that &amp;#8220;mock&amp;#8221; makes a great verb, and given the history of the term, I used mock in the foregoing mainly as a general term for &amp;#8220;substituting a test double&amp;#8221;, which I generally don&amp;#8217;t like to do. I apologize for that. If this were going in a book, I&amp;#8217;d be far more careful. There are several types of test double: mock, spy, stub, fake, dummy&amp;#8230; &lt;a href=&quot;http://www.diasparsoftware.com/weblog/archives/00000054.html&quot;&gt;I once wrote about when to fake and when to mock&lt;/a&gt;, so read that if you&amp;#8217;re confused about how to use the different kinds of test doubles.&lt;/p&gt;
&lt;p&gt;I hope you found this useful, and if you didn&amp;#8217;t, tell me why and I&amp;#8217;ll find a way to make it up to you.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/90';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/90&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 14, 2007  19:06
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 14 Apr 2007 19:06:30 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/90</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>One year later: an Agile podcast</title>
      <link>http://jbrains.ca/permalink/89</link>
      <description>&lt;div class='entry posting' id='entry-_posting_89'&gt;
&lt;div class='posting' id='content-_posting_89'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Click on the title to listen to a podcast from Agile 2006, with Bob Payne as your host. I spoke mostly about XP Day North America, and the plan sounds dated now. We didn&amp;#8217;t run the conference in Austin, in Portland, in St. Louis&amp;#8230; but we still have plans to get there eventually. Manhattan is likely a &amp;#8220;go&amp;#8221; for autumn 2007, and we hope to pick up the pace in 2008. And yes, I am a columnist for &lt;span class=&quot;caps&quot;&gt;IEEE&lt;/span&gt; Software, but no, I haven&amp;#8217;t started writing that other book yet.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/89';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/89&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 11, 2007  20:15
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/xpday&quot;&gt;xpday&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2006&quot;&gt;agile 2006&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 11 Apr 2007 20:15:41 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/89</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Best rant ever (rated PG-13)</title>
      <link>http://jbrains.ca/permalink/88</link>
      <description>&lt;div class='entry posting' id='entry-_posting_88'&gt;
&lt;div class='posting' id='content-_posting_88'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I apologize if the foul language offends you, but I laughed uncontrollably for several minutes upon reading it. For complete context, click the title.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;#8230;God damn Edward&amp;#8230; &lt;span class=&quot;caps&quot;&gt;GOD&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;DAMN&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;EDWARD&lt;/span&gt;! &lt;span class=&quot;caps&quot;&gt;AAAUUUGGHH&lt;/span&gt;! I &lt;span class=&quot;caps&quot;&gt;CHANGE&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;THREE&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;LINE&lt;/span&gt;! &lt;span class=&quot;caps&quot;&gt;THREE&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;GODDAMN&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;LINE&lt;/span&gt;! Two comment! &lt;span class=&quot;caps&quot;&gt;AND&lt;/span&gt; IT NO &lt;span class=&quot;caps&quot;&gt;COMPILE&lt;/span&gt;! &lt;span class=&quot;caps&quot;&gt;AUUUGHHH&lt;/span&gt;! &lt;span class=&quot;caps&quot;&gt;GOD&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;DAMN&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;EDWARD&lt;/span&gt;! You have to &lt;span class=&quot;caps&quot;&gt;READ&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;HIS&lt;/span&gt; F*CKING &lt;span class=&quot;caps&quot;&gt;MIND&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;AND&lt;/span&gt; HE NO &lt;span class=&quot;caps&quot;&gt;EVEN&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;HERE&lt;/span&gt;!!!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/88';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/88&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 10, 2007  20:02
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 10 Apr 2007 20:02:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/88</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Perl and Scrabble</title>
      <link>http://jbrains.ca/permalink/87</link>
      <description>&lt;div class='entry posting' id='entry-_posting_87'&gt;
&lt;div class='posting' id='content-_posting_87'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I certainly don&amp;#8217;t like to denigrate entire classes of people in public. It&amp;#8217;s not nice, it&amp;#8217;s bad for business, and it&amp;#8217;s bad for karma. Still, I found this statement about perl programmers and I absolutely had to share it with a wider audience.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(&amp;#8220;Programmers&amp;#8221; is in inverted commas [that&amp;#8217;s British for &amp;#8216;quotation marks&amp;#8217; -&lt;span class=&quot;caps&quot;&gt;JBR&lt;/span&gt;] since we all know Perl guys don&amp;#8217;t actually code, they just throw fistfuls of scrabble tiles on the floor and type in whatever characters show face up)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/87';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/87&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
April 04, 2007  01:41
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 04 Apr 2007 01:41:57 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/87</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Mac OS widgets won't go away!</title>
      <link>http://jbrains.ca/permalink/85</link>
      <description>&lt;div class='entry posting' id='entry-_posting_85'&gt;
&lt;div class='posting' id='content-_posting_85'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I just ran into a little trouble: I was removing a Dashboard widget while starting Windows XP under Parallels, and when I looked down at the bottom of my screen, I saw widgets instead of the Dock. The widgets actually blocked the Dock, rather than just annoyingly being superimposed on them. Nothing I clicked seemed to help, but Google did. Although I didn&amp;#8217;t find an exact hit on the subject, I found out that I can kill the Dock and restart it. When I tried that, it worked. So if you find yourself in that situation, try this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;
% sudo killall -TERM Dock
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;That might do it for you, as it did for me. Enjoy.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/85';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/85&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
March 31, 2007  17:59
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/mac&quot;&gt;mac&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 31 Mar 2007 17:59:44 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/85</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Thank you, J. Lozano</title>
      <link>http://jbrains.ca/permalink/83</link>
      <description>&lt;div class='entry posting' id='entry-_posting_83'&gt;
&lt;div class='posting' id='content-_posting_83'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I hope you don&amp;#8217;t think it&amp;#8217;s bad form for me to post this here, but I was so pleased with &lt;a href=&quot;http://tinyurl.com/wtrrh&quot;&gt;the latest review at amazon.com for &lt;em&gt;JUnit Recipes&lt;/em&gt;&lt;/a&gt; that I wanted to thank the reviewer in public. Your words are very kind, and I appreciate them.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/83';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/83&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
March 29, 2007  02:52
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/review&quot;&gt;review&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 29 Mar 2007 02:52:53 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/83</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Simply disturbing</title>
      <link>http://jbrains.ca/permalink/82</link>
      <description>&lt;div class='entry posting' id='entry-_posting_82'&gt;
&lt;div class='posting' id='content-_posting_82'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&lt;a href=&quot;http://tinyurl.com/2awwow&quot;&gt;There are no words.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/82';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/82&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
March 29, 2007  02:14
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 29 Mar 2007 02:14:40 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/82</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>A riff on &quot;Mentoring, as Team Leader&quot;</title>
      <link>http://jbrains.ca/permalink/81</link>
      <description>&lt;div class='entry posting' id='entry-_posting_81'&gt;
&lt;div class='posting' id='content-_posting_81'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;George Dinwiddie recently wrote about mentoring as a team leader (click through the title to read him), and I would like to share a little about my wife&amp;#8217;s business: tutoring for secondary school students. Sarah works routinely with undermotivated, underachieving students, some of whom show an astonishing lack of the basic knowledge of the subjects they study. She once told me that one way she gets more out of these students is setting higher expectations for them than anyone else in their lives. To paraphrase her, if you don&amp;#8217;t set the bar at least a little off the ground, the kid won&amp;#8217;t try to jump. I find it&amp;#8217;s the same with adults: when left in an environment that doesn&amp;#8217;t explicitly expect them to learn and grow, adults eventually lose the desire to do it. It&amp;#8217;s even happened to me, and I consider myself quite the self-starter. So I do the same: when I find myself face-to-face with someone who has stopped learning, I use language that expresses that I expect them to keep learning. It can be subtle; it can be overt; either way, I tend to have more positive than negative responses.&lt;/p&gt;
&lt;p&gt;Returning to the substance of George&amp;#8217;s question, let me assume the problem is that an internal person (not a consultant) is being asked to be a mentor where he wasn&amp;#8217;t expected to be one before. I have been there, and I did a poor job of it. (I was young!) I don&amp;#8217;t think those people understood why I was asserting myself in a teaching role, so they resented me for it. If I could do it again, I&amp;#8217;d be clear, telling them that I have been asked to act more as a teacher, and that I&amp;#8217;ll do my best to balance criticism with respect. Finally, if they think I&amp;#8217;m going too far, they should come to me and tell me, or if they prefer, they should speak to our manager (who, I assume, gave me the assignment). Put simply, it&amp;#8217;s easier for a peer to teach when his peers are set up to expect to be taught.&lt;/p&gt;
&lt;p&gt;Of course, if an employee could master the Weinbergian art of the Lone Ranger touch, that would be great. I still don&amp;#8217;t know how to do that.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/81';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/81&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
February 12, 2007  23:18
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 12 Feb 2007 23:18:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/81</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>I'm &quot;it&quot;: five little-known things about me</title>
      <link>http://jbrains.ca/permalink/80</link>
      <description>&lt;div class='entry posting' id='entry-_posting_80'&gt;
&lt;div class='posting' id='content-_posting_80'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;James Shore wrote about &lt;a href=&quot;http://www.jamesshore.com/Blog/tagged.html&quot;&gt;five little-known things about himself&lt;/a&gt;, then he tagged me, so I&amp;#8217;m &amp;#8220;it&amp;#8221;. Here, then, are five things about myself that might be well-known by some, but not generally known by readers of this weblog.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;I have been a life-long enthusiast of languages, and am capable of reading several with varying degrees of competence. Some of you know that I presented in French at XP Day France 2006, and that was my first public speech in French since my university days. I can also converse reasonably in Spanish, very annoyingly in German, and can read enough Portuguese, Italian, Catalan and Proven&amp;ccedil;al to avoid starvation. Strangely, though, I prefer to know things about language over actually learning them. While not a true student of linguistics, I am always interested in the peculiarities of languages like Hungarian and Finnish, Russian, Mandarin, Japanese, and Piraha, among others. I can easily get lost for hours on Wikipedia, surfing the pages devoted to languages and linguistics.&lt;/li&gt;
	&lt;li&gt;I am a member of the &lt;a href=&quot;http://www.sportalliance.com/new/games.html&quot;&gt;Ontario Winter Games&lt;/a&gt; 1991 champion (young) mens &lt;a href=&quot;http://www.c5pba.ca/&quot;&gt;5-pin bowling&lt;/a&gt; team from Central Ontario. As I recall, we placed fourth in Canada that year. I returned to the 1993 Winter Games as a member of a much improved Central Ontario team, but we tanked, finishing fourth. I was a competitive bowler for 20 years, ending about 8 years ago. When we move to &lt;a href=&quot;http://www.dauphin.ca&quot;&gt;Dauphin, Manitoba&lt;/a&gt; this year, I plan to take up the sport again seriously.&lt;/li&gt;
	&lt;li&gt;For 19 years, I was a member of the &lt;a href=&quot;http://ptdklawyers.com/THROW/index.html&quot;&gt;Toronto Houseleague Religiously Obsessed with Winning, or &lt;span class=&quot;caps&quot;&gt;THROW&lt;/span&gt;&lt;/a&gt;, a simulation baseball league that plays &lt;a href=&quot;http://designdepot.com/&quot;&gt;Dynasty League Baseball&lt;/a&gt;. If you have no idea what that might be, imagine a Role-Playing Game for baseball, where you get to own a team, be responsible for its finances, trade players, sign free agents and manage games on the field, mostly by throwing dice at another person for 6 hours on a Sunday afternoon once a month. After over a decade of losing, I won my &lt;a href=&quot;http://ptdklawyers.com/THROW/archivefiles/THROWArchives.htm&quot;&gt;first and only championship in 2003&lt;/a&gt; before walking away from the team at the end of the 2004 season. I have attended the weddings of 4 of my fellow league members over the years, and in spite of leaving, many of them continue to be valued friends.&lt;/li&gt;
	&lt;li&gt;I have appeared on &lt;a href=&quot;http://www.ctv.ca/&quot;&gt;Canadian national television&lt;/a&gt; once, in January 1986, on a family-oriented magazine show entitled &amp;#8220;Lifetime&amp;#8221;. I appeared with my mother on a segment about parents living with and raising gifted children. When asked what it was like to live with me (then 12), my mother answered, &amp;#8220;It&amp;#8217;s like playing &amp;#8221;http://www.trivialpursuit.com/&amp;#8220;&amp;gt;Trivial Pursuit&lt;/a&gt; 24 hours a day.&amp;#8221; Fortunately, no copy of that show is known to have survived.&lt;/li&gt;
	&lt;li&gt;I fully expect to have retired before I turn 40 (on May 4, 2014, health and weather permitting). Here, by &amp;#8220;retired&amp;#8221; I mean that I will no longer need to work in order to pay the bills: &lt;a href=&quot;http://entrepreneurs.about.com/od/gettingstarted/a/passiveincome.htm&quot;&gt;passive income&lt;/a&gt; will cover all our important expenses and any work I do will be either on a volunteer basis, for &amp;#8220;mad money&amp;#8221;, or to further increase our wealth. (Our wealth ratio is tough to compute right now, but it&amp;#8217;s somewhere between 0.4 and 0.6.) The only reason I could foresee wanting to increase our wealth past the point where I don&amp;#8217;t need to work for living is to have more choice about where in the world we can afford to live without working.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;At this point, I am supposed to tag five more people, but I don&amp;#8217;t know whom to tag, so instead, if you can read this, you&amp;#8217;re it!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/80';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/80&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 26, 2007  01:53
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 26 Jan 2007 01:53:51 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/80</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Ah, spammers</title>
      <link>http://jbrains.ca/permalink/79</link>
      <description>&lt;div class='entry posting' id='entry-_posting_79'&gt;
&lt;div class='posting' id='content-_posting_79'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Recently, TextDrive has been overrun by spammers attacking their mail servers. This morning, when I grabbed my mail, I had about 1,700 &amp;#8220;Unable to deliver&amp;#8221; bounceback messages in my inbox, because someone has got hold of my e-mail address and been sending out naughty e-mails in my disguise. This time, it was phishing e-mails for Wachovia Bank accounts, I think. Fantastic.&lt;/p&gt;
&lt;p&gt;I know this will mostly fall on deaf ears, because anyone who reads this weblog likely knows already that I am not a spammer, but on the off chance that someone Googles and finds me in response to this phishing e-mail, it did not come from me. I don&amp;#8217;t know enough technical detail to take a step to protect myself. I&amp;#8217;m quite sure this is not a virus problem. I believe it is TextDrive, and not me, that they are attacking. There is likely nothing I can do. I&amp;#8217;m really sorry.&lt;/p&gt;
&lt;p&gt;Please don&amp;#8217;t think I&amp;#8217;m a spammer.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/79';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/79&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 14, 2007  16:24
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 14 Jan 2007 16:24:21 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/79</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Burnout</title>
      <link>http://jbrains.ca/permalink/78</link>
      <description>&lt;div class='entry posting' id='entry-_posting_78'&gt;
&lt;div class='posting' id='content-_posting_78'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I think I might finally have hit the end of my tether. I have been fighting burnout for about two years, now, and I think I&amp;#8217;m out of fight. In re-reading Jerry Weinberg&amp;#8217;s &lt;em&gt;Secrets of Consulting&lt;/em&gt;, I&amp;#8217;ve just recently re-read the section about how consultants are always either Busy or Idle. For the past two years I have been Busy, which is generally a good thing, but I think I&amp;#8217;ve bit off more than I can chew. There are a number of personal reasons why I&amp;#8217;ve done this, and I&amp;#8217;m not ready to go into those in public just yet, but suffice it to say that I&amp;#8217;m going to have to scale back my professional activities in 2007, quite literally for the sake of my sanity.&lt;/p&gt;
&lt;p&gt;One of the things I&amp;#8217;ll need are people to help me with the projects I&amp;#8217;ve committed to. XP Day North America is a considerable drain on me, and I&amp;#8217;m considering canceling the Portland and Austin events, just to give myself some breathing room. If someone out there wishes to volunteer to organize these events, I&amp;#8217;m open to the help. I am willing to oversee and provide guidance, but you&amp;#8217;d need to do the legwork. You&amp;#8217;ll receive free entry to the conference, hearty public exposure and free travel to another XP Day somewhere else on the continent in 2007.&lt;/p&gt;
&lt;p&gt;If anyone would like to send me their suggestions for how to deal with burnout, feel free to send e-mail to &lt;code&gt;me at jbrains dot ca&lt;/code&gt;. I would be glad to hear from you, even if they&amp;#8217;re just well-wishes.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/78';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/78&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 13, 2006  21:43
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 13 Dec 2006 21:43:09 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/78</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>What is your customer's job?</title>
      <link>http://jbrains.ca/permalink/77</link>
      <description>&lt;div class='entry posting' id='entry-_posting_77'&gt;
&lt;div class='posting' id='content-_posting_77'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;In listening to &lt;a href=&quot;http://www.infoq.com/interviews/jeffries-running-tested-features&quot;&gt;Ron Jeffries talk about Running, Tested Features&lt;/a&gt;, he reminds us of something very important for us to understand. Our customer&amp;#8217;s job is to envision a product with more features than could possibly exist, sooner than it could possibly exist. Our job, as software delivery professionals, is to work with them to define a product that &lt;em&gt;can&lt;/em&gt; exist by the time they need it and be &amp;#8220;meaty&amp;#8221; enough to satisfy them.&lt;/p&gt;
&lt;p&gt;I believe this reformulation of our relationship to our customers helps remove some of the antagonism we tend to find when &amp;#8220;they&amp;#8221; ask &amp;#8220;us&amp;#8221; to do the impossible. &lt;em&gt;That&amp;#8217;s their job.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/77';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/77&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
December 02, 2006  00:31
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/planning&quot;&gt;planning&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 02 Dec 2006 00:31:50 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/77</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>An obsession with Agility</title>
      <link>http://jbrains.ca/permalink/76</link>
      <description>&lt;div class='entry posting' id='entry-_posting_76'&gt;
&lt;div class='posting' id='content-_posting_76'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I attend the XP/Agile Toronto User Group fairly irregularly these days, but I still consider myself a member and contributor. This week, Dmitri Zimin(e) presented &amp;#8220;Agile Enough&amp;#8221;, a case study of Opalis Software. In it, he mentioned their early setbacks, among which the biggest obstacle was an &amp;#8220;obsession with agility&amp;#8221;. When I read this, I thought back to all the projects I&amp;#8217;ve worked on since 2000 when I was still at &lt;span class=&quot;caps&quot;&gt;IBM&lt;/span&gt;, and I see a common theme. The failures have had, at their root, the obsession with acting agile, being agile, performing the agile practices, appearing to be agile&amp;#8230; all this instead of focusing on helping the project succeed. The successes have had, at their root, a lack of this obsession, primarily because in those cases, no-one was opposing the agile practices. So it&amp;#8217;s reasonable to wonder why this happens.&lt;/p&gt;
&lt;p&gt;My greatest successes have been either solo projects (my last six months at &lt;span class=&quot;caps&quot;&gt;IBM&lt;/span&gt;, my work with the Toronto Blue Jays) or projects where everyone agreed to focus on delivering incrementally, quickly, with quality (the first two months at Toyota) and allowed agile practices to be the way we achieved that goal. My greatest failures (the rest of my time at Toyota, my most recent transitions over the past 18 months) have stemmed in part from wasting energy trying to convince people to work one way or from wasting energy on &amp;#8220;compensating&amp;#8221; (as arrogant as that sounds, that&amp;#8217;s what we were doing) for the poor habits other team members seemed to insist on maintaining. It is clear to me now that there wasn&amp;#8217;t true buy-in from everyone about how we would work, so that, for example, when schedule pressure kicked in, they would immediately go back to the old ways of working. I know, from my experience and from that of others, that this back-sliding is human nature and part of any change program, but I&amp;#8217;m left wondering what to do about it. What can I do differently?&lt;/p&gt;
&lt;p&gt;First, I can stop fighting or trying to convince people to work my way, but rather offer them the opportunity to work my way and evaluate that for themselves. If it helps them, then we can work together, and if not, then we can&amp;#8217;t. That&amp;#8217;s all right: there is no rule that says we &lt;em&gt;must&lt;/em&gt; be able to work together to be friends, or even to be civil to one another. Next, I can stop focusing on the practices and instead focus on the results. This means measuring the current results before trying to change things. I&amp;#8217;ll admit that I&amp;#8217;ve generally done a poor job of that so far. Finally, I can stop ramming change down people&amp;#8217;s throats, but instead invite them to take the journey with me. I think I can achieve this through regular retrospectives in which we examine what&amp;#8217;s working and what isn&amp;#8217;t working, then propose &lt;strong&gt;together&lt;/strong&gt; ways to improve. I need to remember that my solution, although it works for me, isn&amp;#8217;t always best for everyone else, including whichever team I&amp;#8217;m on. I think if I apply these three ideas to my consulting work, I&amp;#8217;ll find better results. This means learning what to measure, how to measure it, and how to present that information in non-threatening ways. I suppose I know my next area of research&amp;#8230; now we&amp;#8217;ll just see whether I actually do it.&lt;/p&gt;
&lt;blockquote&gt;&amp;#8220;I didn&amp;#8217;t ask &amp;#8216;&lt;em&gt;can&lt;/em&gt; he do it&amp;#8217;, I asked &amp;#8216;&lt;em&gt;will&lt;/em&gt; he do it&amp;#8217;. With Eddie, those are two different things.&amp;#8221; &amp;#8211; Bert Gordon, &lt;em&gt;The Hustler&lt;/em&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/76';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/76&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
November 23, 2006  18:50
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 23 Nov 2006 18:50:34 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/76</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Parallels + hotel connection = pain on wheels</title>
      <link>http://jbrains.ca/permalink/75</link>
      <description>&lt;div class='entry posting' id='entry-_posting_75'&gt;
&lt;div class='posting' id='content-_posting_75'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Recently I have found that when I use Parallels to run Windows under Mac OS X, then connect to the internet at a hotel, I have to do the &amp;#8220;I&amp;#8217;m here&amp;#8221; dance. This consists of signing in on Mac OS, browsing for a while, then going to Windows, signing in there, browsing for a while, and back and forth&amp;#8230; since I use QuickBooks under Windows and, of course, have my company file under version control and, of course, have marked the company file as &amp;#8220;needs locking&amp;#8221;, it becomes a hassle whenever I need to do a little book-keeping on the side. Here at &lt;a href=&quot;http://www.ayeconference.com&quot;&gt;&lt;span class=&quot;caps&quot;&gt;AYE&lt;/span&gt; Conference&lt;/a&gt; it&amp;#8217;s become worse: I couldn&amp;#8217;t sign in under Windows, for reasons I was not willing to explore. Fortunately, Google came to the rescue. I found out that Parallels has &amp;#8220;Shared Networking&amp;#8221; mode, and that sounded like it would help. It&amp;#8217;s simple. (Even I could handle it.)&lt;/p&gt;
&lt;p&gt;In Mac OS, enable Internet Sharing on your network adapter. In Parallels, shut down your VM, edit its settings, then choose &amp;#8220;Shared Networking&amp;#8221; for your networking needs, instead of &amp;#8220;Bridged Ethernet&amp;#8221;. Restart your VM and voil&amp;agrave;, both Mac OS and Windows use the same connection and your hotel will never know the difference. Of course, if you&amp;#8217;re using your VM to host an outside internet service, then the outside world won&amp;#8217;t be able to distinguish your VM from your Mac, but I can&amp;#8217;t imagine why you&amp;#8217;d do that, anyway.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/75';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/75&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
November 06, 2006  14:36
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/mac&quot;&gt;mac&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 06 Nov 2006 14:36:07 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/75</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Commenting by intention</title>
      <link>http://jbrains.ca/permalink/74</link>
      <description>&lt;div class='entry posting' id='entry-_posting_74'&gt;
&lt;div class='posting' id='content-_posting_74'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;JBR&lt;/span&gt;: You see? This is &lt;em&gt;precisely&lt;/em&gt; the kind of comment I can&amp;#8217;t stand. If this is what the code does, then why not extract a method and program by intention?&lt;/p&gt;
&lt;p&gt;Client: We &lt;em&gt;are&lt;/em&gt; programming by intention; it&amp;#8217;s just that we&amp;#8217;re capturing the intent in the comments.&lt;/p&gt;
&lt;p&gt;(If you&amp;#8217;re looking for my client&amp;#8217;s tongue, you might want to check his cheek.)&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/74';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/74&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
November 02, 2006  00:28
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 02 Nov 2006 00:28:50 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/74</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>JDO? NFW.</title>
      <link>http://jbrains.ca/permalink/73</link>
      <description>&lt;div class='entry posting' id='entry-_posting_73'&gt;
&lt;div class='posting' id='content-_posting_73'&gt;
&lt;div style='text-align: justify'&gt;
	&lt;p&gt;I just finished testing something for a client (and friend) that involved &lt;span class=&quot;caps&quot;&gt;JDO&lt;/span&gt;. I wanted to test the case where one detaches a parent object, changes one of its children (foreign keys), then re-attaches the parent. My client was having trouble because Kodo was attempting to insert a second copy of the child object, rather than simply changing the parent to point away from its old child object towards its new, existing child object. Thinking how easy that is to write in Ruby, I wasn&amp;#8217;t prepared for the work it would take with &lt;span class=&quot;caps&quot;&gt;JDO&lt;/span&gt;.&lt;/p&gt;
	&lt;p&gt;I went with the simplest solution I could imagine: Java, &lt;span class=&quot;caps&quot;&gt;JPOX&lt;/span&gt;, &lt;span class=&quot;caps&quot;&gt;HSQLDB&lt;/span&gt;, so that everything ran in memory and there would be no need for direct &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; manipulation. Even so, the documentation for &lt;span class=&quot;caps&quot;&gt;JPOX&lt;/span&gt; was incredibly hard to find. Their web site is a frustrating maze of endless links. Not only that, the code I had to write was obscene. Duplication everywhere! No wonder people can&amp;#8217;t build decent designs with &lt;span class=&quot;caps&quot;&gt;JDO&lt;/span&gt;. I applaud their effort and think we should all bring them beer and pretzels to help them while they try to wrangle this absurd standard.&lt;/p&gt;
	&lt;p&gt;I didn&amp;#8217;t need another reason to run, screaming away from Java, but I have one. Oy. Friends don&amp;#8217;t let friends use &lt;span class=&quot;caps&quot;&gt;JDO&lt;/span&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/73';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/73&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 30, 2006  05:51
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 30 Oct 2006 05:51:44 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/73</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Kent Beck on the attitude of spreading Agile</title>
      <link>http://jbrains.ca/permalink/72</link>
      <description>&lt;div class='entry posting' id='entry-_posting_72'&gt;
&lt;div class='posting' id='content-_posting_72'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;In the process of catching up with the &lt;tt&gt;extremeprogramming&lt;/tt&gt; mailing list, I read the following, and found it hit home. It is a reaction to Martin Fowler&amp;#8217;s observation that management imposing Agile is rarely successful.&lt;/p&gt;
&lt;blockquote&gt; &lt;img src=&quot;http://www.threeriversinstitute.org/Kent%202.jpg&quot; width=&quot;75&quot; style=&quot;float: left; padding: 5px;&quot; /&gt; We think that we, as programmers or consultants, have the right to say &amp;#8220;We should all be working in an agile way.&amp;#8221; Why not a manager or a &lt;span class=&quot;caps&quot;&gt;CEO&lt;/span&gt;? What makes that entirely a programmer&amp;#8217;s perogative? Agile development is not a process that can only be dictated from the programmer level. I think that this points to an attitude problem with the structure inherent in a company, that money and power are not equally distributed and that process/work style/work culture like many other aspects of company life may not be in your individual control. If you accept company structure, how best to adopt agile process? Programmers like it if it is their idea, but long-term success is dependent on management buy-in, not programmer buy-in. Agile development is not a process that can only be dictated from the programmer level. &lt;/blockquote&gt;
&lt;p&gt;While I agree with Martin that imposition from on high rarely succeeds, I suspect it has much to do with the common thread of imposing process (effectively turning it into a defined process&amp;mdash;oh, the irony), rather than aligning people to the corresponding goals. I wonder what we could do to help executives feel more comfortable trusting us with their (business) goals?&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/72';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/72&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 23, 2006  02:45
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 23 Oct 2006 02:45:33 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/72</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>From Java to Ruby</title>
      <link>http://jbrains.ca/permalink/71</link>
      <description>&lt;div class='entry posting' id='entry-_posting_71'&gt;
&lt;div class='posting' id='content-_posting_71'&gt;
&lt;div style='text-align: justify'&gt;
	&lt;p&gt;About a year ago I wrote that &lt;a href=&quot;http://www.diasparsoftware.com/weblog/archives/00000088.html&quot;&gt;I was no longer a Java programmer&lt;/a&gt;&amp;mdash;or rather, that my days as a professional Java programmer were numbered. I wrote this in reaction to the announcement that sooner or later the &lt;a href=&quot;http://java.sun.com/docs/books/jls/&quot;&gt;Java language was going to &lt;em&gt;force us&lt;/em&gt; to use parameterized types&lt;/a&gt;. I simply found that too depressing to continue, so I chose that as a good time to switch to Ruby and have already implemented one small, but successful piece of software on the Rails platform: this weblog. Fortunately, I don&amp;#8217;t have a manager dictating the technology I use for my projects. On the contrary, we have just started a medium-sized project in Rails, rather than being beholden to a client&amp;#8217;s &amp;#8220;requirement&amp;#8221; to use a legacy platform like &lt;a href=&quot;http://java.sun.com/javaee/&quot;&gt;Java Enterprise Edition&lt;/a&gt; or &lt;a href=&quot;http://www.microsoft.com/net/&quot;&gt;.&lt;span class=&quot;caps&quot;&gt;NET&lt;/span&gt;&lt;/a&gt;. It&amp;#8217;s quite liberating.&lt;/p&gt;
	&lt;p&gt;Still, if I &lt;em&gt;did&lt;/em&gt; have to convince a manager, director or client to choose Rails over Java EE, I&amp;#8217;m glad I now have Bruce Tate&amp;#8217;s &lt;a href=&quot;http://tinyurl.com/k6mxd&quot;&gt;&lt;em&gt;From Java to Ruby&lt;/em&gt;&lt;/a&gt; to give them. It is a quick read, as most of the Pragmatic Programmers&amp;#8217; books are, and it does a very good job of outlining the advantages and disadvantages of Ruby as a development platform. If you know Ruby, then you won&amp;#8217;t be surprised by his arguments in favor: shorter development cycles, higher productivity for simpler tasks, more design flexibility and quicker feedback. If you&amp;#8217;re a Ruby &lt;em&gt;fan&lt;/em&gt; then you might be surprised to read about the disadvantages, because they are likely things that do bother your manager, but don&amp;#8217;t bother you. I&amp;#8217;ll invite you to read the book, rather than enumerate them here.&lt;/p&gt;
	&lt;p&gt;If you are thinking of starting a grassroots movement in your organization to move even one subproject from Java to Ruby, then you need to read this book, understand its message, then be better capable of formulating an argument your management can appreciate, understand and believe. If you don&amp;#8217;t, then you might be dooming yourself to yet another &amp;#8220;crackpot disinformation campaign&amp;#8221;, the kind of thing I used to do at &lt;span class=&quot;caps&quot;&gt;IBM&lt;/span&gt; before I knew any better.&lt;/p&gt;
	&lt;p&gt;If you are a manager and your people have started putting pressure on you to adopt Ruby as a development platform, this book will help you navigate the waters, learn how to dip your toe in, or give you the solid arguments you need to convince them that you&amp;#8217;re not ready. I suppose you &lt;em&gt;could&lt;/em&gt; just veto them with an &amp;#8220;I told you so&amp;#8221;, but a reasoned argument will be better received and less likely to drive them a step closer to polishing up their resumes.&lt;/p&gt;
	&lt;p&gt;Bruce Tate&amp;#8217;s &lt;em&gt;From Java to Ruby&lt;/em&gt; is an indispensable field guide to those who need to decide whether to carry out a campaign to supplant Java with Ruby as your development platform of choice.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/71';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/71&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 22, 2006  05:32
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/rails&quot;&gt;rails&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/review&quot;&gt;review&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 22 Oct 2006 05:32:45 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/71</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Useless comments, an example</title>
      <link>http://jbrains.ca/permalink/70</link>
      <description>&lt;div class='entry posting' id='entry-_posting_70'&gt;
&lt;div class='posting' id='content-_posting_70'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;People often ask me for examples of code smells, but I never seem to have any handy, most of the ones I see are from clients, and by the time I have energy to write about them, I forget them. Today, at thedailywtf.com, I saw an example of code with plausible, but useless comments. See whether you can spot them.&lt;/p&gt;
&lt;pre&gt;
//SQL Query to retreive all unbroadcast messages
string sqlCmd = 
  &quot;SELECT o.*, r.*, ..., c.*, u.* &quot; +
  &quot;  FROM Orgs o, Recipients r, Contacts C, &quot; +
  &quot;       ... &quot; +
  &quot;       Groups g, Users u &quot; +
  &quot; WHERE m.Group_Id = g._Group_Id &quot; +
  &quot;   AND u.User_Id = gu.User_Id &quot; +
  &quot;   AND ... &quot; + 
  &quot; ORDER BY o.Priority_Code, o.Delivery_Num, ...&quot;;

//Execute SqlCommand
DataTable dt = DataHelper.ExecSqlToTable(sqlCmd);

//For each row retreived, insert a row into the Queue table
for(int i=0; i&amp;amp;lt;dt.Rows.Count; i++)
{
  //Insert Sql command
  SqlCommand insCmd = DataHelper.CreateCmd(
    &quot;INSERT INTO Queue (Sender_Id, Recipient_Id, ...) &quot; + 
    &quot; VALUES (@Sender_Id, @Recipient_Id, ...))&quot;;
    
  //Add Parameters to command
  AppendParam( insCmd, &quot;@Sender_Id&quot;, dt.Rows[i][&quot;Sender_Id&quot;]);
  AppendParam( insCmd, &quot;@Recipient_Id&quot;, dt.Rows[i][&quot;@Recipient_Id&quot;]);
  ...
 
  //execute command
  insCmd.ExecuteNonQuery();
}
&lt;/pre&gt;
&lt;p&gt;If you answered &amp;#8220;every one&amp;#8221;, you win!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/70';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/70&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 18, 2006  22:20
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 18 Oct 2006 22:20:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/70</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>&quot;I don't have a name...&quot;</title>
      <link>http://jbrains.ca/permalink/69</link>
      <description>&lt;div class='entry posting' id='entry-_posting_69'&gt;
&lt;div class='posting' id='content-_posting_69'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;There are some things you just want to shout to the world right away. My business partner and good friend, Niraj Khanna, just gave me a teaser for a story about his ordeal with &lt;a href=&quot;http://www.aircanada.ca&quot;&gt;Air Canada&lt;/a&gt; today. He&amp;#8217;ll tell the complete story later, but I wanted to share this chestnut.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Niraj: What&amp;#8217;s your name?&lt;/p&gt;
&lt;p&gt;Agent: I work for Air Canada; I don&amp;#8217;t have a name.&lt;/p&gt;
&lt;p&gt;Niraj: What do you want me to call you?&lt;/p&gt;
&lt;p&gt;Agent: &amp;#8220;Ticket Agent.&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What?! Awesome. I&amp;#8217;ll try that the next time I&amp;#8217;m stupid enough to fly Air Canada.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/69';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/69&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 16, 2006  00:13
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 16 Oct 2006 00:13:18 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/69</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The Leaky View: An antipattern in MVP</title>
      <link>http://jbrains.ca/permalink/68</link>
      <description>&lt;div class='entry posting' id='entry-_posting_68'&gt;
&lt;div class='posting' id='content-_posting_68'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have written &lt;a href=&quot;http://articles.jbrains.info/LeakyView.pdf&quot;&gt;an article&lt;/a&gt; about an antipattern I found in code that someone designed using the Presenter-First approach as a guideline. The &lt;strong&gt;Leaky View&lt;/strong&gt; is not limited to Presenter-First, but it is a smell that I think careful application of Presenter-First should entirely eliminate, so I was surprised when it crept in.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/68';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/68&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 06, 2006  03:53
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/antipatterns&quot;&gt;antipatterns&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 06 Oct 2006 03:53:48 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/68</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Shotgun Programming</title>
      <link>http://jbrains.ca/permalink/67</link>
      <description>&lt;div class='entry posting' id='entry-_posting_67'&gt;
&lt;div class='posting' id='content-_posting_67'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;This entry comes from a guest blogger who wishes to remain anonymous for now. As he wrote to me &lt;blockquote&gt; I&amp;#8217;d blog about this but some parties to whom this is directed might end up reading it and get offended. So prepare for a rant. :-) &lt;/blockquote&gt; &lt;p&gt;The image is so vivid that I had to post this on his behalf. Enjoy.&lt;/p&gt;
&lt;hr&gt;&lt;/hr&gt;
&lt;p&gt;The most dreadful style of programming is shotgun programming. Perhaps you&amp;#8217;ve heard of cowboy coding. This is its ugliest, rudest form. A cowboy at least uses a pistol, a weapon which in the right hands can be wickedly accurate and effective. But the shotgun totin&amp;#8217; programmer makes for a completely different game. It&amp;#8217;s a wild, drunken attack at the keyboard, launching random code at the compiler and seeing what sticks. It ignores all logged messages and compiler warnings. Documentation is never consulted. Who actually reads that stuff anyway? Thinking before shooting is not just discouraged, it&amp;#8217;s never considered. Who needs to think when you&amp;#8217;ve got a bloody shotgun!&lt;/p&gt;
&lt;p&gt;The way a shotgunner approaches programming is to blindly start shooting first and ask questions later. And when something does work, well, don&amp;#8217;t sit around worryin&amp;#8217; about why, just start doin&amp;#8217; it again! Do it again and again and again. It worked once (somehow) so it must work again, right? To take the time to understand why or how something works is a waste of time. I suppose it&amp;#8217;s a sort of evolutionary approach to programming, where intelligence and design have no place.&lt;/p&gt;
&lt;p&gt;And when I say blindly, I mean the &amp;#8220;blind-folded swinging at the pinata&amp;#8221; style. It starts with wild swings in any direction. Who knows what the right direction might be? That&amp;#8217;s impossible! Computers are magic black boxes (of the devil, I might add). As soon as something connects, whether or not it happens to actually be the pinata, you beat the hell out of it. Of course, you never take the blindfold off to see what you&amp;#8217;re doing, so you end up with a bloody pulp of code.&lt;/p&gt;
&lt;p&gt;What am I talking about specifically? I&amp;#8217;m talking about spending hours randomly debugging a problem when looking at the actual runtime error message would lead you directly to the bug within minutes. I&amp;#8217;m talking about never, ever, looking at the documentation. I&amp;#8217;m talking about cut and paste-ing the wrong code, sometimes entirely different applications, that&amp;#8217;s right, cut and paste as a whole, and then strangling it into submission. I&amp;#8217;m talking about learning one compilable trick and then using it for every solution. Or it&amp;#8217;s the other extreme of the engineer who thinks good code is measured by the absolute number of design patterns and acronyms one can cram into an executable. It&amp;#8217;s randomly adding methods to whatever class happens to be within reach at the moment with no thought of encapsulation or separation of concerns. I&amp;#8217;m talking about fundamentally not caring about what it is you end up with and what depths you sink to along the way.&lt;/p&gt;
&lt;p&gt;Of course, shotguns are so 1999. With today&amp;#8217;s modern code generating IDE&amp;#8217;s we allow former shotgunners to lay down their punitive arms and take up carpet bombing their code instead. And that tragedy is another rant all to itself.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/67';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/67&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 04, 2006  11:57
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 04 Oct 2006 11:57:41 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/67</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>An alternate version of Parameterized Test Case</title>
      <link>http://jbrains.ca/permalink/66</link>
      <description>&lt;div class='entry posting' id='entry-_posting_66'&gt;
&lt;div class='posting' id='content-_posting_66'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;In &lt;em&gt;JUnit Recipes&lt;/em&gt;, I wrote about the &lt;strong&gt;Parameterized Test Case&lt;/strong&gt; pattern, in recipe 4.8 &amp;#8220;Build a data-driven suite&amp;#8221;. The problem occurs when we want to run the same test with different input and output. If we write these tests the most straightforward way, we duplicate the algorithm in the test. Even if we extract that into a method, we have to remember to invoke that method from each test. Either way, it&amp;#8217;s avoidable duplication. In recipe 4.8, I described how to build a custom test suite so that you can specify the input and output data in a table and run a test for each row in that table. Although this involves fairly intermediate use of JUnit, it eliminates a lot of duplication. At the time, I considered it the way to express parameterized tests in JUnit.&lt;/p&gt;
&lt;p&gt;Of course, we now have JUnit 4 and its direct support for parameterized tests. I won&amp;#8217;t write about that here, primarily because I don&amp;#8217;t use Java 5 much, so I also don&amp;#8217;t use JUnit 4. Instead, I&amp;#8217;d like to share an alternate design for parameterized tests with JUnit 3 that a student intern showed me while consulting on a large Agile transition. It&amp;#8217;s a bit strange, but it works.&lt;/p&gt;
&lt;p&gt;The previous approach I described consisted of these steps:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Implement a custom suite() method that iterates through a table of data and creates TestCase instances, passing each row of data to the constructor.&lt;/li&gt;
	&lt;li&gt;Implementing a constructor to store the input and output data in fixture objects (fields).&lt;/li&gt;
	&lt;li&gt;Overriding runTest() to execute the test, rather than writing a test method.&lt;/li&gt;
&lt;/ol&gt;
&lt;/ol&gt;
&lt;p&gt;Now, instead of building a custom test suite, we can use test methods to set the fixture objects. This improves clarity of intent in the code (to a degree) at the cost of confusing the first-time reader by setting fixture objects in a method whose name starts with &lt;code&gt;test&lt;/code&gt;. Let yourself be the judge of whether this is an improvement.&lt;/p&gt;

&lt;pre&gt;public class AlternateParameterizedTest 
       extends ParameterizedTestCaseTemplate {

    private Integer[] sides;
    private TriangleType expectedType;

    public void testEquilateral() throws Exception {
        sides = new Integer[] { 3, 3, 3 };
        expectedType = TriangleType.EQUILATERAL;
    }

    public void testIsoceles() throws Exception {
        sides = new Integer[] { 3, 4, 3 };
        expectedType = TriangleType.ISOCELES;
    }

    public void testScalene() throws Exception {
        sides = new Integer[] { 6, 4, 5 };
        expectedType = TriangleType.SCALENE;
    }

    public void testNonPositiveLengthSide() throws Exception {
        sides = new Integer[] { 5, 0, 4 };
        expectedType = TriangleType.INVALID;
    }

    public void testInconstructible() throws Exception {
        sides = new Integer[] { 3, 1, 2 };
        expectedType = TriangleType.INCONSTRUCTIBLE;
    }

    public void testInconstructibleLooksLikeIsoceles() throws Exception {
        sides = new Integer[] { 1, 4, 1 };
        expectedType = TriangleType.INCONSTRUCTIBLE;
    }

    @Override
    protected void doTest() {
        assertSame(expectedType, new Triangle(sides).classify());
    }
}&lt;/pre&gt;
&lt;p&gt;I have pulled a couple of methods up into a test template class to remove the unnecesary elements from each parameterized test case. There is one big thing not to like: those methods should be named something like &lt;code&gt;fixtureInconstructible()&lt;/code&gt; or &lt;code&gt;caseInconstructible()&lt;/code&gt;, rather than &lt;code&gt;testInconstructible()&lt;/code&gt;, but that&amp;#8217;s not something we can implement in a JUnit 3 extension. We would have to separate selecting the test methods from the test runner, something that appears already to have happened with JUnit 4. Still, I do like the way the tests read more than seeing a big table of data in a &lt;code&gt;suite()&lt;/code&gt; method, or worse, having the test data sit outside the test case class. It&amp;#8217;s worth experimenting with, so if you try it, please share your opinions or improvements with the &lt;a href=&quot;http://groups.yahoo.com/group/junit&quot;&gt;&lt;code&gt;junit&lt;/code&gt; Yahoo! group&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/66';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/66&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
October 02, 2006  13:19
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 02 Oct 2006 13:19:29 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/66</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>There are open workspaces, then there are open workspaces</title>
      <link>http://jbrains.ca/permalink/65</link>
      <description>&lt;div class='entry posting' id='entry-_posting_65'&gt;
&lt;div class='posting' id='content-_posting_65'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I spotted this in the agile project management Yahoo! group, and it caught my attention.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If someone in marketing sneezed on 11th Ave the &amp;#8220;bless yous&amp;#8221; made it all the way to 12th Ave.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That might be a little too open a workspace. To read more about it: &lt;a href=&quot;http://tinyurl.com/s8bp7&quot;&gt;go here&lt;/a&gt;.
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/65';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/65&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 30, 2006  21:40
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 30 Sep 2006 21:40:34 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/65</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>You can't please them all</title>
      <link>http://jbrains.ca/permalink/64</link>
      <description>&lt;div class='entry posting' id='entry-_posting_64'&gt;
&lt;div class='posting' id='content-_posting_64'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;At Agile 2006 I hosted a discovery session entitled &amp;#8220;The Truth about Programmers and Testers&amp;#8221;. The goal of the session is to help programmers and testers understand each other more, have more insight into the other group&amp;#8217;s motivations and concerns. I thought the session was quite successful, and I remember feeling quite good about it when it ended. Today, I received feedback from the attendees, which was mixed. One comment stuck out.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I hoped for more ideas on how to get past the animosity between testers and programmers&amp;#8230; not so much [a] gripe session.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I&amp;#8217;m stumped by this one. I think the key way to get past the animosity between the two groups is to sit them down together and ask them to talk about the exact things we discussed in the session! The exercise itself is the killer idea on how to get past the animosity between testers and programmers!&lt;/p&gt;
&lt;p&gt;This is a hazard of a real discovery session, I guess. Next time, if you simply want to be told what to do, please attend a tutorial.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/64';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/64&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 29, 2006  03:49
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2006&quot;&gt;agile 2006&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 29 Sep 2006 03:49:45 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/64</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Is your build process under control?</title>
      <link>http://jbrains.ca/permalink/63</link>
      <description>&lt;div class='entry posting' id='entry-_posting_63'&gt;
&lt;div class='posting' id='content-_posting_63'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;From the text of a book I&amp;#8217;m currently reviewing and editing.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Being able to quickly get a new developer building the project is a sign that the build process is under control.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Simple&amp;mdash;very simple&amp;mdash;and oh, so true.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/63';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/63&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 29, 2006  01:41
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/review&quot;&gt;review&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 29 Sep 2006 01:41:33 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/63</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Flexible like in yoga or Flexible like in C++?</title>
      <link>http://jbrains.ca/permalink/62</link>
      <description>&lt;div class='entry posting' id='entry-_posting_62'&gt;
&lt;div class='posting' id='content-_posting_62'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I read an article comparing JUnit 4 to TestNG today. I didn&amp;#8217;t much care for it, although some of it was quite good. I don&amp;#8217;t want to go point-by-point through it to rebut it, although I will share my observation that the author exaggerated the significance of a point or two. In particular, he claims TestNG &lt;em&gt;pioneered&lt;/em&gt;&amp;mdash;his emphasis and not mine&amp;mdash;the use of annotations for testing in Java. Who cares? NUnit was doing that years ago and TestNG copied that. Not only that, who wouldn&amp;#8217;t have known how to do that? Being the first to do something obvious is a pretty weak way to define &amp;#8220;pioneer&amp;#8221;. I digress. The one particular point I want to call out has to do with his claim that TestNG is more flexible than JUnit 4 because, in part:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Obviously the two listings [&lt;a href=&quot;http://tinyurl.com/qgcz7&quot;&gt;here as listings 1 and 2&lt;/a&gt;] are pretty similar, but if you look closely, you&amp;#8217;ll see that the TestNG coding conventions are more flexible than JUnit 4&amp;#8217;s. In Listing 1, JUnit forced me to declare my &lt;code&gt;@BeforeClass&lt;/code&gt; decorated method as &lt;code&gt;static&lt;/code&gt;, which consequently required me to also declare my fixture, &lt;code&gt;finder&lt;/code&gt;, as &lt;code&gt;static&lt;/code&gt;. I also had to declare my &lt;code&gt;init()&lt;/code&gt; method as &lt;code&gt;public&lt;/code&gt;. Looking at Listing 2, you see a different story because those conventions aren&amp;#8217;t required. My &lt;code&gt;init()&lt;/code&gt; method is neither &lt;code&gt;static&lt;/code&gt; nor &lt;code&gt;public&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I just don&amp;#8217;t understand this. TestNG allows the programmer to make a class-level relationship look like an instance-level relationship and that&amp;#8217;s a &lt;em&gt;good&lt;/em&gt; thing? I don&amp;#8217;t think so&amp;mdash;it&amp;#8217;s just poor design. What good is having an instance-level field on a class where the value of that field is the same for every instance of the class? Don&amp;#8217;t you find that confusing? I&amp;#8217;m sure I would, especially in the heat of battle. In fact, I&amp;#8217;m sure I have. I imagine you have, too, at least once.&lt;/p&gt;
&lt;p&gt;If this is the kind of &amp;#8220;flexibility&amp;#8221; TestNG offers, then thank you, but no thank you. I&amp;#8217;m not going to claim that TestNG is a poor tool because of this, but I certainly think any claims of flexibility borne out of obviously poor design do a disservice, both to the claimant and to TestNG itself. Congratulations: TestNG allows you to test poorly-designed code by writing poorly-designed tests. Enjoy.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/62';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/62&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 26, 2006  23:38
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 26 Sep 2006 23:38:54 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/62</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Not Just Coding</title>
      <link>http://jbrains.ca/permalink/61</link>
      <description>&lt;div class='entry posting' id='entry-_posting_61'&gt;
&lt;div class='posting' id='content-_posting_61'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I am pleased to announce that my new column, &lt;em&gt;Not Just Coding&lt;/em&gt; will debut in &lt;a href=&quot;http://www.computer.org/software/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;IEEE&lt;/span&gt; Software magazine&lt;/a&gt;&amp;#8217;s January/February 2007 edition. I hope to use this column to help coders become all-around programmers, looking beyond code into other issues related to writing software, and not just touchy-feely, interpersonal issues, but technical and practical ones. I am excited to have the opportunity to reach a broader audience, and I hope they receive me well.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/61';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/61&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 26, 2006  00:51
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/writing&quot;&gt;writing&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 26 Sep 2006 00:51:33 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/61</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Attention: do not do anything that will expose our bugs</title>
      <link>http://jbrains.ca/permalink/60</link>
      <description>&lt;div class='entry posting' id='entry-_posting_60'&gt;
&lt;div class='posting' id='content-_posting_60'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I won&amp;#8217;t embarrass the site developers in public, but my wife Sarah tells me an event registration system showed her this warning message when she tried to register for an event.&lt;/p&gt;
&lt;blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;ATTENTION&lt;/span&gt;: DO &lt;span class=&quot;caps&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;USE&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;THE&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;SAME&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;EMAIL&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;ADDRESS&lt;/span&gt; TO &lt;span class=&quot;caps&quot;&gt;TRY&lt;/span&gt; TO &lt;span class=&quot;caps&quot;&gt;REGISTER&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;ANOTHER&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;PERSON&lt;/span&gt;. Your Email address is used to identify you and if you register another person with this email address &lt;span class=&quot;caps&quot;&gt;YOUR&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;OWN&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;REGISTRATION&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;WILL&lt;/span&gt; BE &lt;span class=&quot;caps&quot;&gt;REPLACED&lt;/span&gt;. Each person you register must use a &lt;span class=&quot;caps&quot;&gt;UNIQUE&lt;/span&gt; email address.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/60';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/60&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 25, 2006  01:41
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 25 Sep 2006 01:41:23 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/60</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>XP Day Montreal 2006</title>
      <link>http://jbrains.ca/permalink/59</link>
      <description>&lt;div class='entry posting' id='entry-_posting_59'&gt;
&lt;div class='posting' id='content-_posting_59'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Saturday, September 23 is fast approaching. That&amp;#8217;s the day of XP Day Montreal 2006, the third in our series of one-day conferences dedicated to Extreme Programming in North America. Although we&amp;#8217;ve taken a year off, we&amp;#8217;re back with top-notch speakers, including Laurent Bossavit and Michael Feathers. This, to our knowledge, is the first officially bilingual XP conference in North America, with content in both French and English. Please join us!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/59';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/59&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
September 15, 2006  21:29
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/xpday&quot;&gt;xpday&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 15 Sep 2006 21:29:54 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/59</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The first goodbyes: Labball 2006</title>
      <link>http://jbrains.ca/permalink/58</link>
      <description>&lt;div class='entry posting' id='entry-_posting_58'&gt;
&lt;div class='posting' id='content-_posting_58'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&lt;img src=&quot;http://tinyurl.com/mjfzy&quot; width=&quot;250&quot; style=&quot;float: right&quot; /&gt;This past week I said my first goodbyes as we prepare to move to &lt;a href=&quot;http://tinyurl.com/zulkz&quot;&gt;Dauphin, Manitoba&lt;/a&gt; next June. For eight years, I played a variant of softball most accurately called &amp;#8220;recreational, sexist three-pitch&amp;#8221;, because it&amp;#8217;s six pitches for women. When I first joined the team, it was a rag-tag bunch. There was plenty of enthusiasm, but not much knowledge or experience, so I taught a bunch of them how to play, starting with 90-minute seminars explaining the rules of the game. (No joke. &amp;#8220;The objective of baseball&amp;#8230;&amp;#8221;)&lt;/p&gt;
&lt;p&gt;Those first few years, we were &lt;em&gt;horrible&lt;/em&gt;. The kind of horrible that gives you nightmares, if you sleep at all. A few years of losing heavily gave us time to develop our skills, inject some more talent and gel as a team. After seasons of 1-11 or 2-10, the last three seasons we finished third, second and third, respectively, after regular seasons winning at least 75% of our games. In the meantime, we had plenty of turnover, but we had a core group of people dedicated to giving a strong effort, improving their skills and learning how to play the game well. Only the rain stopped us from our best chance at a championship in 2005.&lt;/p&gt;
&lt;p&gt;Reflecting on this time of my life, not only am I reminded of the ups and downs, specific moments of pain and trimuph, but I also see that this has been the only real &lt;em&gt;team&lt;/em&gt; in my life. Referring to Patrick Lencioni&amp;#8217;s five dysfunctions of a team, I can honestly state that, for the most part, we have trusted each other, engaged in healthy conflict, come through on our commitments, held one another accountable and cared more deeply about the team&amp;#8217;s results than our own. I see it in little things, like accepting responsibility for poor play to big things, like rearranging one&amp;#8217;s personal schedule to be available to play for the team. Everyone on the team has grown, as players, as leaders. This is the experience I wish I could have on software projects. If I did, I think I&amp;#8217;d look forward to them as eagerly as I looked forward to each May and the start of Labball season.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s wishing you find a team like that someday.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/58';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/58&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 30, 2006  07:21
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/baseball&quot;&gt;baseball&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/moving&quot;&gt;moving&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 30 Aug 2006 07:21:22 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/58</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The Daily Scrum and accountability</title>
      <link>http://jbrains.ca/permalink/57</link>
      <description>&lt;div class='entry posting' id='entry-_posting_57'&gt;
&lt;div class='posting' id='content-_posting_57'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;These days I have been going back through some of my favorite books, including Patrick Lencioni&amp;#8217;s &lt;em&gt;Overcoming the Five Dysfunctions of a Team&lt;/em&gt;. I am certainly interested in team dynamics, not only as a coach of software teams, but also because I use these principles in my daily life in relating to my wife, my friends and others. In re-reading the section on accountability, I am struck by the idea that the Daily Scrum or Stand-up Meeting is, at least in part, an exercise in holding team members accountable to their work commitments. By asking the questions, &amp;#8220;What did you achieve yesterday?&amp;#8221; and &amp;#8220;What do you commit to achieving today?&amp;#8221; we are taking the meeting beyond a mere checkpointing activity into the realm of asking team members to account for their time in front of the rest of the team, and possibly their managers and stakeholders. This strikes me as a remarkably advanced practice!&lt;/p&gt;
&lt;p&gt;Lencioni describes embracing accountability as the fourth step in his five-step model towards becoming a team. Before embracing accountability, we should build trust, master conflict and achieve commitment. This presents an interesting dilemma. When a team decides to adopt Scrum or XP or some other agile method, can it really institute the Daily Scrum or Stand-up Meeting right away? or is such a team jumping the gun with regard to its own development as a true team? Should we spend time overcoming the first three dysfunctions before attempting to employ this practice? If so, then why is this practice among the very first things we recommend for teams learning to become agile?&lt;/p&gt;
&lt;p&gt;There is one way that I can reconcile these ideas, each of which I believe in separately, and that has to do with the questions we ask at the Stand-up Meeting. When starting out, team members tend to ask each other, &amp;#8220;What did you do yesterday?&amp;#8221; and &amp;#8220;What do you plan to do today?&amp;#8221; These questions are much softer than the ones I gave earlier, and perhaps a team has to spend time answering these softer questions before they can benefit from answering the harder ones related to commitments. I can&amp;#8217;t be sure that&amp;#8217;s the case, but it&amp;#8217;s one way to explain the apparent contradiction. I would enjoy hearing about other ideas on the topic, so I just might write about this on a mailing list somewhere. Any recommendations on which one?&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/57';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/57&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 29, 2006  23:30
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 29 Aug 2006 23:30:19 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/57</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>I am a spammer by association. Thanks.</title>
      <link>http://jbrains.ca/permalink/56</link>
      <description>&lt;div class='entry posting' id='entry-_posting_56'&gt;
&lt;div class='posting' id='content-_posting_56'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I didn&amp;#8217;t realize that the &lt;code&gt;info&lt;/code&gt; top-level domain is the domain of spammers. Apparently at least Yahoo! groups feels this way. After some help from James Knox and a little testing, I have found out that when I include a link to &lt;code&gt;http://www.jbrains.info&lt;/code&gt; in my signature, Yahoo! groups counts the message as spam; whereas when I change it to &lt;code&gt;http://www.jbrains.ca&lt;/code&gt;, all is well.&lt;/p&gt;
&lt;p&gt;Awesome.&lt;/p&gt;
&lt;p&gt;So how on earth did I manage to be lumped in with spammers, just for uttering&amp;mdash;not using, because I send e-mails to Yahoo! groups with a &lt;code&gt;rogers.com&lt;/code&gt; account&amp;mdash;a &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; that ends in &lt;code&gt;.info&lt;/code&gt;?&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/56';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/56&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 25, 2006  04:49
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 25 Aug 2006 04:49:24 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/56</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>PayPal sandbox: Message 3005</title>
      <link>http://jbrains.ca/permalink/55</link>
      <description>&lt;div class='entry posting' id='entry-_posting_55'&gt;
&lt;div class='posting' id='content-_posting_55'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;What is the #1 rule of software? When you demo it, it won&amp;#8217;t work.&lt;/p&gt;
&lt;p&gt;So there I was at the home of my business partner, demonstrating the application I was working on, which included integrating with &lt;a href=&quot;http://www.paypal.com&quot;&gt;PayPal&lt;/a&gt;. The big finish, of course, was how the site goes to PayPal, the shopper gives us his money, then returns to our site.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Message 3005&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Have you ever seen this? According to &lt;a href=&quot;http://www.google.com&quot;&gt;Google&lt;/a&gt; there are &lt;a href=&quot;http://cdbaby.com/mp3lofi/cadenceunplugged2-03.m3u&quot;&gt;50 ways to get this message&lt;/a&gt;. (Did you sing the last part of that sentence? I did.) I tried a few fixes, like clearing my cache, destroying all my PayPal cookies, standing on one leg and barking like a dog. (OK, I made up one of those fixes.) Still, no love. I did, however, notice something out of the corner of my brain that ended up helping me solve the problem: I had changed the payee account (that is, the account receiving the funds), but that account hadn&amp;#8217;t confirmed its e-mail address. Aha? As it turns out, yes. Once I went through the confirmation and verification ritual, all was well. I eventually remembered that the e-mail the sandbox sends is not a real e-mail to my real e-mail address. (That took only 10 minutes.)&lt;/p&gt;
&lt;p&gt;Now, an error message with even a faint whiff of an explanation of the problem would have helped, but all I can do about that is cry. In the meantime, I am leaving this here so the next poor sap can find it when he desperately types paypal sandbox &amp;#8220;message 3005&amp;#8221; into Google.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/55';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/55&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 25, 2006  04:12
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 25 Aug 2006 04:12:56 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/55</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Toronto: the disengaged customer</title>
      <link>http://jbrains.ca/permalink/54</link>
      <description>&lt;div class='entry posting' id='entry-_posting_54'&gt;
&lt;div class='posting' id='content-_posting_54'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;The last leg of the MacDonald-Cartier Freeway Experience was last night in Toronto with the &lt;a href=&quot;http://www.xptoronto.com&quot;&gt;XP/Agile Toronto user group&lt;/a&gt;. Once again, I split the group into two and asked each to develop a plan for my talk, the theme of which was &lt;strong&gt;Steering the Ship: the Joy and Heartbreak of Planning&lt;/strong&gt;. It went well, on the whole. This group took only about 40 seconds to ask me a question, whereas Ottawa took 13 minutes and Montr&amp;eacute;al around 6 minutes. The Toronto group using the computer cheated (in a good way) and abandoned the computer as a planning tool, despite my objection, after about 30 minutes. That was quickest among the computer teams at all three sites. These statistics, however, aren&amp;#8217;t the most interesting part of the evening for me.&lt;/p&gt;
&lt;p&gt;In Toronto, two very different things happened than Ottawa and Montr&amp;eacute;al: first, after two iterations, the two customer teams joined forces and worked on a single plan, recognizing that that would create more value and reduce the effort; second, I noticed a handful of customers &lt;em&gt;very&lt;/em&gt; disengaged, sitting in the corner and chatting among themselves. By way of the Telephone Game, word reached me that some of those people felt thrown into the deep end with no idea what to do, so they pulled out and did nothing. I also heard at least one person was quite disappointed with the event as a result. Whoever that person is, these words are for you: now you know how a typical XP customer feels on her first project.&lt;/p&gt;
&lt;p&gt;One of the themes of &lt;a href=&quot;http://montreal2006.xpday.info&quot;&gt;XP Day Montr&amp;eacute;al 2006&lt;/a&gt; is the importance of the customer role in XP. &amp;#8220;It&amp;#8217;s more important than you think&amp;#8230; no really, even more important than that.&amp;#8221; After more than half a decade, the XP community still doesn&amp;#8217;t seem to have a learning roadmap for customers. As a result, they are thrust into the role on a team, mostly because the programmers want to work that way, and are left with the most difficult jobs of all: decide what to build, in what order, and how to describe it in a way that programmers can build. These are all responsibilities that these people might or might not have had in their past as the customer of a software project. At a minimum, it&amp;#8217;s likely no-one has held them this responsible and demanded such relative formality in the way they ask for features. (Isn&amp;#8217;t that ironic?) We need to do more to support our customers, especially the would-be customers who are doing this for the first time. So if you&amp;#8217;re undertaking your first XP project, or if your customer is undertaking &lt;em&gt;his&lt;/em&gt; first XP project, work more closely with the customer than you think you should&amp;#8230; no really, even more closely than that. No other single decision has as much impact on the project&amp;#8217;s success.&lt;/p&gt;
&lt;p&gt;Really.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/54';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/54&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 23, 2006  21:03
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 23 Aug 2006 21:03:20 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/54</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Alternate implementation, or fake?</title>
      <link>http://jbrains.ca/permalink/52</link>
      <description>&lt;div class='entry posting' id='entry-_posting_52'&gt;
&lt;div class='posting' id='content-_posting_52'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Sometimes it only takes a few years to figure out what I&amp;#8217;m talking about&amp;#8230; for me, I mean.&lt;/p&gt;
&lt;p&gt;Years ago, when I was first learning how to use test doubles (stubs, fakes, spies, mocks), I made the distinction between &lt;strong&gt;fakes&lt;/strong&gt; and &lt;strong&gt;alternate implementations&lt;/strong&gt;. The distinction was always semi-clear in my mind, but I could never quite articulate it well enough to explain it to others. In the process of reviewing &lt;em&gt;&lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; in Action&lt;/em&gt;, I think I finally have it. Let me try to explain it to you.&lt;/p&gt;
&lt;p&gt;An &lt;strong&gt;alternate implementation&lt;/strong&gt; (typically, of an interface) mimics the logic of the production implementation, but is lighter weight. A &lt;strong&gt;fake&lt;/strong&gt; merely hardcodes the results of methods.&lt;/p&gt;
&lt;p&gt;Clear, isn&amp;#8217;t it? Fine, an example is in order.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s consider an &lt;strong&gt;authentication service&lt;/strong&gt;, which determines whether a given user name/password pair represents a valid user. Such a thing would have a simple interface.&lt;/p&gt;

&lt;pre&gt;public interface AuthenticationService {
    User login(String userName, String password);
}&lt;/pre&gt;
&lt;p&gt;Some controller, let&amp;#8217;s pretend it&amp;#8217;s a plain Java class for now, needs to use this authentication service to decide whether to forward the user to the personalized welcome page or back to the login page with a &amp;#8220;nice try&amp;#8221; message. My test list for this feature is pretty short.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Existing user means valid User object on the welcome page.&lt;/li&gt;
	&lt;li&gt;Non-existent user means back to login page; don&amp;#8217;t include the parameters in the request.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One way to write these tests is to create a &amp;#8220;mock&amp;#8221; authentication service in the style of the &lt;a href=&quot;http://www.mockobjects.com&quot;&gt;&lt;cite&gt;mockobjects.com&lt;/cite&gt;&lt;/a&gt; project, that has an &lt;code&gt;addUser()&lt;/code&gt; method. With this method, you would add users to the user directory (stored as a &lt;code&gt;Map&lt;/code&gt;, say), then look them up with the &lt;code&gt;login()&lt;/code&gt; method. You could use the same mock authentication service for both tests by simply attempting to login with the existing user for one test and some random obviously non-existent user for the other test. This would work, but it violates a principle of interaction testing:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;When simulating a collaborator, don&amp;#8217;t reimplement its logic.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why not? Simple: if you reimplement the logic, you run the risk of reimplementing it incorrectly, simple though that logic may be. This is the danger of alternate implementations: you might incorrectly simulate the production implementation. This is the reason I use fakes, instead.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;fake&lt;/strong&gt; simply answers whatever &lt;code&gt;User&lt;/code&gt; object you need for the given test. In the happy path case, it would answer any non-null &lt;code&gt;User&lt;/code&gt; object; in the error case, it would answer &lt;code&gt;null&lt;/code&gt;. As my friend Pat Welsh would ask, &amp;#8220;How do it know?&amp;#8221; Well, each test knows how it wants the authentication service to behave, so, &lt;em&gt;it just know&lt;/em&gt;. To show you what I mean, here is one way to write the happy path test.&lt;/p&gt;

&lt;pre&gt;public void testHappyPath() throws Exception {
    final User jbrains = User.named(&quot;jbrains&quot;);

    AuthenticationService authenticationService = new AuthenticationService() {
        public User authenticate(String userName, String password) {
            return jbrains;
        }
    };

    LoginController controller = new LoginController(authenticationService);
    controller.handleRequest(requestFor(&quot;/login&quot;)
                            .withParameter(&quot;user&quot;, jbrains.getName())
                            .withParameter(&quot;password&quot;, &quot;don't matter&quot;)
                            .withEmptySession());

    assertForwardedTo(&quot;/welcome&quot;);
    assertModelContains(&quot;user&quot;);
    assertEquals(jbrains, modelObject(&quot;user&quot;));
}&lt;/pre&gt;
&lt;p&gt;The key point here is that the cotestntroller doesn&amp;#8217;t have to know the right password. There&amp;#8217;s no way the test can use&lt;br /&gt;
the authenticate service incorrectly, because the test simply tells the authentication service, &amp;#8220;Return a valid user&lt;br /&gt;
(meaning not &lt;code&gt;null&lt;/code&gt;); I don&amp;#8217;t care why.&amp;#8221; You&amp;#8217;ll notice that I intentionally gave the &lt;code&gt;password&lt;/code&gt;&lt;br /&gt;
parameter a nonsense value, to emphasize the fact that &lt;em&gt;we&amp;#8217;re not even looking at it&lt;/em&gt;. This test is really&lt;br /&gt;
resistant to change, and that&amp;#8217;s a big deal to me.&lt;/p&gt;
&lt;p&gt;Incidentally, we can do better, by refactoring a little.&lt;/p&gt;

&lt;pre&gt;public void testHappyPath() throws Exception {
    final User jbrains = User.named(&quot;jbrains&quot;);

    AuthenticationService authenticationService = fakeAuthenticationServiceReturning(user);

    LoginController controller = new LoginController(authenticationService);
    controller.handleRequest(requestFor(&quot;/login&quot;)
                            .withParameter(&quot;user&quot;, jbrains.getName())
                            .withParameter(&quot;password&quot;, &quot;don't matter&quot;)
                            .withEmptySession());

    assertForwardedTo(&quot;/welcome&quot;);
    assertModelContains(&quot;user&quot;);
    assertEquals(jbrains, modelObject(&quot;user&quot;));
}&lt;/pre&gt;
&lt;p&gt;You can imagine how to extract code into the method &lt;code&gt;fakeAuthenticationServiceReturning()&lt;/code&gt;. Now to write the error path test, simply have the autthenticate service return &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;public void testNoSuchUser() throws Exception {
    AuthenticationService authenticationService = fakeAuthenticationServiceReturning(null);

    LoginController controller = new LoginController(authenticationService);
    controller.handleRequest(requestFor(&quot;/login&quot;)
                            .withParameter(&quot;user&quot;, jbrains.getName())
                            .withParameter(&quot;password&quot;, &quot;don't matter&quot;)
                            .withEmptySession());

    assertRedirectedTo(&quot;/login&quot;);
    assertModelDoesntContain(&quot;user&quot;);
    assertModelContainsMessageWithKey(&quot;login.invalid&quot;);
    assertRequestDoesntContainParameters(&quot;user&quot;, &quot;password&quot;);
}&lt;/pre&gt;
&lt;p&gt;We could reveal more intent by extracting code into a new method named, say, &lt;code&gt;neverAuthenticates()&lt;/code&gt;. I&amp;#8217;m not sure about that, since I like uniformity in naming conventions.&lt;/p&gt;
&lt;blockquote&gt; &lt;p&gt;&lt;img alt=&quot;I have an idea!&quot; src=&quot;http://images.jbrains.ca/lightbulb-icon-transparent.gif&quot; style=&quot;float: left; width: 32px;&quot; /&gt;Hm&amp;#8230; maybe the method names should be &lt;code&gt;neverAuthenticates()&lt;/code&gt; and &lt;code&gt;alwaysAuthenticatesAs(User)&lt;/code&gt;. Actually, those are better. If this were a real project, I&amp;#8217;d change them, but I want to leave them as is so you can glimpse into my thought process. I hope you appreciate it, rather than finding it artificial or egotistical. You can&amp;#8217;t please everyone.&lt;/p&gt; &lt;/blockquote&gt;
&lt;p&gt;This is one case I might introduce a class called &lt;code&gt;NeverAuthenticates&lt;/code&gt; just to make it clearer what&amp;#8217;s happening. I&amp;#8217;m not a fan of the test knowing that &lt;code&gt;null&lt;/code&gt; means &amp;#8220;not authenticated&amp;#8221;.&lt;/p&gt;
&lt;blockquote&gt; &lt;p&gt;&lt;img alt=&quot;I have an idea!&quot; src=&quot;http://images.jbrains.ca/lightbulb-icon-transparent.gif&quot; style=&quot;float: left; width: 32px;&quot; /&gt;Hm. Maybe I should have separated returning the &lt;code&gt;User&lt;/code&gt; object from determining whether the user/password combination maps to a user. Even with small tests, they can be smaller.&lt;/p&gt; &lt;/blockquote&gt;
&lt;p&gt;Still, I hope this illustrates the difference between an alternate implementation and a fake, and explains why I prefer using fakes in my tests to alternate implementations.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/52';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/52&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 16, 2006  15:30
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 16 Aug 2006 15:30:10 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/52</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Refactoring: Replace Conditional with Polymorphism</title>
      <link>http://jbrains.ca/permalink/50</link>
      <description>&lt;div class='entry posting' id='entry-_posting_50'&gt;
&lt;div class='posting' id='content-_posting_50'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;While reading a draft of Lasse Koskela&amp;#8217;s upcoming &lt;em&gt;&lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; in Action&lt;/em&gt;, I came across a code sample that got me thinking about judging what is a code smell. As I&amp;#8217;ve doubtless written in the past, I like really simple rules, because I can follow them easily. In particular, I like simple rules that lead me to behave agreeably. I propose such a simple rule:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Replace any structure like this&lt;/p&gt;
&lt;pre&gt;
if (isFoo(someObject)) {
    doFoo(someObject);
}
else if (isBar(someObject)) {
    doBar(someObject);
}
...

&lt;/pre&gt;
&lt;p&gt;with something polymorphic.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Is this a good rule to follow all the time? No. Is this a good rule to follow all the time while learning about Object-Oriented Design? Absolutely.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/50';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/50&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 15, 2006  20:04
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/refactoring&quot;&gt;refactoring&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 15 Aug 2006 20:04:05 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/50</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>MCFE: First stop, Ottawa</title>
      <link>http://jbrains.ca/permalink/49</link>
      <description>&lt;div class='entry posting' id='entry-_posting_49'&gt;
&lt;div class='posting' id='content-_posting_49'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I am in lovely Oshawa, Ontario, stopped at the local Via Rail station, on my way to Ottawa by about 16:30 today. Tonight is the first stop the MacDonald-Cartier Freeway Experience, where I&amp;#8217;ll be both facilitating a planning session and giving a talk on planning at Cognos, located at 3755 Riverside Drive. All are welcome. For details, click the title of this entry.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/49';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/49&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 15, 2006  16:56
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/xpday&quot;&gt;xpday&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/planning&quot;&gt;planning&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 15 Aug 2006 16:56:53 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/49</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>If only TestNG were more like JUnit...</title>
      <link>http://jbrains.ca/permalink/48</link>
      <description>&lt;div class='entry posting' id='entry-_posting_48'&gt;
&lt;div class='posting' id='content-_posting_48'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Please don&amp;#8217;t interpret this as bad-mouthing TestNG. On the contrary, I like TestNG, even though I don&amp;#8217;t use it. I think there&amp;#8217;s plenty of room on the stage for complementary testing tools: JUnit, more rigid in its philosophy, and therefore more valuable as a design tool; and TestNG, more accommodating in its philosophy, and therefore more valuable as a testing tool. As I practise &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; more as a design activity than a testing activity, JUnit continues to be my tool of choice.&lt;/p&gt;
&lt;p&gt;That said, I had to share part of a weblog entry, because it&amp;#8217;s the first time I&amp;#8217;ve seen someone say, in essence, &amp;#8220;I wish TestNG were more like JUnit&amp;#8221;, and in particular, JUnit 3.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The only significant change is that I changed the &lt;code&gt;TestBase&lt;/code&gt; base class to extend from &lt;code&gt;org.testng.Assert&lt;/code&gt;, so you can access all the assertion methods without doing a static import.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I have to chuckle at this. One of the key design points in TestNG and JUnit 4 is no longer needing to extend a &lt;code&gt;TestCase&lt;/code&gt; class, which itself extends an &lt;code&gt;Assert&lt;/code&gt; class. Instead, use the static import feature of JUnit 5 to use the core assertion library in your tests. To see a respected programmer (Howard Lewis Ship!) make this change tells me that it&amp;#8217;s not just a bunch of people complaining that JUnit should be more like TestNG. Some people appreciate the design of JUnit 3, even some TestNG users. I like that.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/48';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/48&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 09, 2006  19:30
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 09 Aug 2006 19:30:24 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/48</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The MacDonald-Cartier Freeway Experience</title>
      <link>http://jbrains.ca/permalink/47</link>
      <description>&lt;div class='entry posting' id='entry-_posting_47'&gt;
&lt;div class='posting' id='content-_posting_47'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;The schedule is set for my speaking tour of Highway 401, also known as the MacDonald-Cartier Freeway, although I will only be on the portion stretching from downtown Toronto to downtown Montr&amp;eacute;al. Here is my speaking schedule. Please join us!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.mayford.ca&quot;&gt;Tuesday 8/15 at 7 PM, Ottawa, Cognos Inc.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.pyxis-tech.com/agilemontreal&quot;&gt;Wednesday 8/16 at 5:30 PM, Montr&amp;eacute;al, le &lt;span class=&quot;caps&quot;&gt;CRIM&lt;/span&gt;.&lt;/a&gt; (The presentation will be in English, mais je serai capable de r&amp;eacute;pondre aux questions pos&amp;eacute;es en fran&amp;ccedil;ais.)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.xptoronto.com&quot;&gt;Tuesday 8/22 at 7 PM, Toronto, Ryerson University.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/47';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/47&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 09, 2006  01:28
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/xpday&quot;&gt;xpday&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 09 Aug 2006 01:28:55 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/47</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Webinar at agitar.com</title>
      <link>http://jbrains.ca/permalink/46</link>
      <description>&lt;div class='entry posting' id='entry-_posting_46'&gt;
&lt;div class='posting' id='content-_posting_46'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Tonight I gave the first of two webinars on Test-Driven Development with J2EE. This is a condensed version of my popular tutorial, one which I have conducted at Agile 2006, XP 2006, Agile 2005, SD West 2005 and XP/Agile Universe 2004. This version has new, up-to-date content and provides a key insight into how to test complex J2EE applications almost entirely in memory. If you&amp;#8217;re interested, click the title of this entry to learn more. The next show is 10 AM ET Wednesday, August 9.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/46';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/46&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 09, 2006  01:17
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/xp2006&quot;&gt;xp2006&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2006&quot;&gt;agile 2006&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 09 Aug 2006 01:17:44 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/46</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>MTS: paragon of responsiveness? Surprisingly, yes.</title>
      <link>http://jbrains.ca/permalink/45</link>
      <description>&lt;div class='entry posting' id='entry-_posting_45'&gt;
&lt;div class='posting' id='content-_posting_45'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I am a customer of &lt;span class=&quot;caps&quot;&gt;MTS&lt;/span&gt; (Manitoba Telecommunications Services), because of the Academy of Learning we run in &lt;a href=&quot;http://www.dauphin.ca&quot;&gt;Dauphin, Manitoba&lt;/a&gt;. Recently I had to change the pre-authorized credit card payment settings, because we&amp;#8217;re switching from one dividends card to another. (If CIBC&amp;#8217;s Platinum Dividend card didn&amp;#8217;t have a ceiling on the number of rewards dollars they handed out per year, we wouldn&amp;#8217;t have to deal with this, but that&amp;#8217;s another story.) I had to fill in a form, which you can see by clicking the title of this weblog entry, in order to make those changes. The form allows me to specify any province (not just Manitoba, which probably accounts of 99% of their customers), but the validation ruleset for the phone number insists on the 204 area code, which is all of Manitoba. As a result, I can choose &amp;#8220;Ontario&amp;#8221; for the mailing address province, but cannot specify our phone number, which is in the 416 area code. I wrote it off as yet another example of poor domain modeling, and even mentioned it in the latest version of Test-Driven J2EE (now Test-Driven Enterprise Code) as an example of creating form validation problems for yourselves.&lt;/p&gt;
&lt;p&gt;I just received an e-mail from the nice folks at &lt;span class=&quot;caps&quot;&gt;MTS&lt;/span&gt; Allstream, reading in part:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I had someone look into the reason why the form will only allow phone numbers starting with &amp;#8216;204&amp;#8217;.  They checked into the requirements for the form, and have removed the edit on the field so you will be able to put in any phone number as well as &amp;#8216;Extra&amp;#8217; phone numbers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Awesome. I let them know that many of the teams I&amp;#8217;ve worked with wouldn&amp;#8217;t be nearly this responsive. How sad it is to be so impressed by this, but I&amp;#8217;m impressed. Good for them!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/45';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/45&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 04, 2006  20:04
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 04 Aug 2006 20:04:38 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/45</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>jbrains.ca is on the air</title>
      <link>http://jbrains.ca/permalink/44</link>
      <description>&lt;div class='entry posting' id='entry-_posting_44'&gt;
&lt;div class='posting' id='content-_posting_44'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/large_flag_of_canada.gif&quot; width=&quot;100&quot; style=&quot;float: right;&quot; /&gt;This web site is now also &lt;strong&gt;jbrains.ca&lt;/strong&gt;. If you&amp;#8217;ve met me, you know that I&amp;#8217;m a proud Canadian, but not in a way that is a synonym for &amp;#8220;anti-American&amp;#8221;. (I won&amp;#8217;t kid you: I used to be, but not any more.) I am especially proud to have brought XP Day North America first to Toronto, then Montr&amp;eacute;al. We are planning to hit Vancouver in 2007 and looking for other key Canadian locations. Finally, the Toronto community is working to help bring Agile 2008 to Toronto.&lt;/p&gt;
&lt;p&gt;I plan to attend CASCon, IBM&amp;#8217;s conference for its Centers for Advanced Studies. The Canadian Agile Network is meeting there, and I&amp;#8217;m finally going to have the chance to become involved. (They kept meeting in Banff, which was all right, but I could never join them.)&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/44';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/44&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
August 04, 2006  01:21
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 04 Aug 2006 01:21:03 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/44</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Two Ruby idioms</title>
      <link>http://jbrains.ca/permalink/43</link>
      <description>&lt;div class='entry posting' id='entry-_posting_43'&gt;
&lt;div class='posting' id='content-_posting_43'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I am working some more on the registration application for XP Day North America, and find myself wanting the &lt;a href=&quot;http://tinyurl.com/lfhwo&quot;&gt;ternary operator&lt;/a&gt;, which I generally do not like to use. As a result, I have discovered two interesting idioms, the first of which I like the other of which is, well, dubious.&lt;/p&gt;
&lt;p&gt;The first one is to replace this implementation of whether an order is taxable. At present, the design is a bit broken: an order can have a payer and an invoice, and while I&amp;#8217;m waiting to unify the payer and invoice into a single class, the invoice takes precedence over the payer for the purposes of determining whether to charge tax on the order. As I am Canadian, I should only charge tax to other Canadians, so even if all registrants in an order are Canadian, if the invoice is sent to someone outside Canada, the order ought not to be taxable. Here&amp;#8217;s the straightforward implementation of that method.&lt;/p&gt;

&lt;pre&gt;  def taxable?
    if invoice.nil? 
      return payer.taxable?
    else
      return invoice.taxable?
    end
  end&lt;/pre&gt;
&lt;p&gt;Notice that &lt;code&gt;payer&lt;/code&gt; and &lt;code&gt;invoice&lt;/code&gt; each understand &lt;code&gt;taxable?&lt;/code&gt;, so I can eliminate the &lt;code&gt;if&lt;/code&gt; statement by finding the first object that isn&amp;#8217;t &lt;code&gt;nil&lt;/code&gt;, looking first at the invoice, then the payer. This observation prompted me to type this new implementation.&lt;/p&gt;

&lt;pre&gt;    [invoice, payer].find { |each| !each.nil? }.taxable?&lt;/pre&gt;
&lt;p&gt;Aside from &lt;code&gt;!each.nil?&lt;/code&gt;, which I wish were &lt;code&gt;each.!nil?&lt;/code&gt; or some such, I find this idiom a bit nicer than the &lt;code&gt;if&lt;/code&gt; statement that came before it. I welcome your opinions.&lt;/p&gt;
&lt;p&gt;For the other idiom, I take my inspiration from Smalltalk. I have another method, which computes the tax amount, that asks the order whether it is taxable, returning either $0 or the subtotal times the tax rate. Here is the straightforward implementation.&lt;/p&gt;

&lt;pre&gt;  def tax
    if taxable?
      subtotal * tax_rate
    else
      Money.ca_dollar(0)
    end
  end&lt;/pre&gt;
&lt;p&gt;In Smalltalk, this would be&lt;/p&gt;

&lt;pre&gt;  Order&amp;gt;&amp;gt;tax  
    ^self.taxable
      ifTrue: [ self.subtotal * self.tax_rate ]
      ifFalse: [ 0 ]&lt;/pre&gt;
&lt;p&gt;Essentially, this is like mapping &lt;code&gt;true&lt;/code&gt; and &lt;code&gt;false&lt;/code&gt; to their respective blocks, then looking up the block using &lt;code&gt;self.taxable&lt;/code&gt; as the key. I liked this idea, so I wrote this (in Ruby now).&lt;/p&gt;

&lt;pre&gt;    { true =&amp;gt; subtotal * tax_rate, 
      false =&amp;gt; Money.ca_dollar(0) } [ taxable? ]&lt;/pre&gt;
&lt;p&gt;This idiom, I think, obscures more than it reveals, so while I like removing the &lt;code&gt;if&lt;/code&gt; statement, I&amp;#8217;m not sure I like the resulting code. Is there a way to write this that avoids the &lt;code&gt;if&lt;/code&gt; statement without resorting to this syntax?&lt;/p&gt;
&lt;p&gt;Worse, this only works because the hash values are, well, values. If they were closures, it might look something like this.&lt;/p&gt;

&lt;pre&gt;    { 
      true =&amp;gt; Proc.new { subtotal * tax_rate },
      false =&amp;gt; Proc.new { Money.ca_dollar(0) }
    }[ taxable? ].call&lt;/pre&gt;
&lt;p&gt;Given that I still need time to get used to closures, I&amp;#8217;m sure I got that wrong.&lt;/p&gt;
&lt;p&gt;I suppose this is the result of talking to someone at Agile 2006 who wants to run a programming session where flow-of-control statements are not allowed&amp;#8230; in &lt;i&gt;Java&lt;/i&gt;. It&amp;#8217;s a neat exercise, if nothing else.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/43';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/43&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 30, 2006  19:27
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 30 Jul 2006 19:27:17 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/43</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Logo contest</title>
      <link>http://jbrains.ca/permalink/42</link>
      <description>&lt;div class='entry posting' id='entry-_posting_42'&gt;
&lt;div class='posting' id='content-_posting_42'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I need a logo for &lt;strong&gt;jbrains.info&lt;/strong&gt;, now also &lt;strong&gt;jbrains.ca&lt;/strong&gt;. I would like to hold a contest for my readers and their friends who have artistic talent. Here are the requirements for all submissions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;one version suitable for use on posters,&lt;/li&gt;
&lt;li&gt;one version suitable for use on web site banners,&lt;/li&gt;
&lt;li&gt;one version suitable for use in print advertising,&lt;/li&gt;
&lt;li&gt;vector graphics format,&lt;/li&gt;
&lt;li&gt;color and black-and-white versions, unless you&amp;#8217;re using black-and-white only for effect.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I don&amp;#8217;t want to constrain your design, because I want your imagination to run wild, but I will prefer entries that suggest Canada without hitting me over the head with it. For example, a big red maple leaf, beaver or beer bottle in the middle is too much.&lt;/p&gt;
&lt;p&gt;Send your entries to &lt;strong&gt;logo at jbrains dot info&lt;/strong&gt;. First prize includes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;permanent advertisement on this site as the logo&amp;#8217;s designer,&lt;/li&gt;
&lt;li&gt;public acknowledgement at all my speaking engagements for the next year,&lt;/li&gt;
&lt;li&gt;free attendance to one XP Day North America event,&lt;/li&gt;
&lt;li&gt;free sponsorship for one XP Day North America event.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The attendance and sponsorship are transferable, in case the entrant doesn&amp;#8217;t need the advertising or has no real interest in extreme programming.&lt;/p&gt;
&lt;p&gt;The contest ends September 30, 2006 or later, if I haven&amp;#8217;t received an entry that I absolutely fall in love with.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/42';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/42&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 30, 2006  17:00
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 30 Jul 2006 17:00:19 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/42</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Stand-up/Daily Scrum: focus on achievement and commitment</title>
      <link>http://jbrains.ca/permalink/41</link>
      <description>&lt;div class='entry posting' id='entry-_posting_41'&gt;
&lt;div class='posting' id='content-_posting_41'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I&amp;#8217;ve just finished reading an article by Jason Yip collecting some patterns and smell related to the daily stand-up or Daily Scrum. Rather than review the article, I wanted to emphasize a point you can find in the article, but that I believe is not adequately highlighted.&lt;/p&gt;
&lt;p&gt;Here is one smell Jason did not mention that I have observed repeatedly: &lt;em&gt;Yesterday I worked on X. Today I&amp;#8217;ll continue working on X.&lt;/em&gt; You can smell this when more and more team members express their progress in terms of working on some vague, high-level unit of work, such as a larger story. This is especially a problem with teams whose average story takes several days to complete. The problem I have with reporting progress this way is that it tells me little about what&amp;#8217;s really happening. It&amp;#8217;s very easy to talk about the same X for several days, indicating that someone might be stuck and needs help.&lt;/p&gt;
&lt;p&gt;Rather than describe what you were or are working on, focus on what you &lt;em&gt;achieved&lt;/em&gt; yesterday and what you&amp;#8217;ve &lt;em&gt;committed&lt;/em&gt; to for today. This gives me a much better feeling of progress, and when someone says, &amp;#8220;I achieved nothing yesterday&amp;#8221;, but doesn&amp;#8217;t report any obstacles in their path, you &lt;em&gt;know&lt;/em&gt; it&amp;#8217;s time to ask some questions. Finally, by committing to something today, you are practising keeping your commitments. The more you do that, the more your team will do that, and your team probably needs to do much more of that. Even if your commitment is small, don&amp;#8217;t underestimate it. Think of this: &amp;#8220;If I get nothing else done today, I&amp;#8217;ll at least have done Y.&amp;#8221; Indeed, Y might be the only important thing you absolutely must complete today. If so, concentrate on it.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;ve encountered this smell on your team, then I hope my suggestion will help you. If you have alternate solutions to this problem, feel free to send me some details by e-mail.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/41';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/41&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 28, 2006  13:02
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 28 Jul 2006 13:02:26 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/41</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Add your notes: the Truth about Programmers and Testers</title>
      <link>http://jbrains.ca/permalink/40</link>
      <description>&lt;div class='entry posting' id='entry-_posting_40'&gt;
&lt;div class='posting' id='content-_posting_40'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Our discovery session entitled &amp;#8220;The Truth about Programmers and Testers&amp;#8221; created some wonderful discussion. We brainstormed a number of topics about the relationship between programmers and testers, broke into groups, discussed them, then reported results to the larger group. I am asking you now, if you have notes from that discussion, to post them. Click the title of this entry get started.&lt;/p&gt;
&lt;p&gt;Thank you for everyone who took the time to join us and explore this important topic. I will keep in touch about whether there is enough material for a paper.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/40';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/40&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 28, 2006  12:25
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2006&quot;&gt;agile 2006&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/writing&quot;&gt;writing&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 28 Jul 2006 12:25:56 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/40</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Webinar: Test-Driven Development in J2EE</title>
      <link>http://jbrains.ca/permalink/39</link>
      <description>&lt;div class='entry posting' id='entry-_posting_39'&gt;
&lt;div class='posting' id='content-_posting_39'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&lt;a href=&quot;http://www.agitar.com&quot;&gt;Agitar&lt;/a&gt; is hosting a complimentary live seminar based on my popular tutorial (now called) &amp;#8220;Test-Driven Enterprise Code&amp;#8221;. If you are interested in learning how to apply &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; effectively to enterprise applications, and avoid the typical pitfalls of the most comon approaches, then join us in August for an hour! Click the title of this entry to learn more.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/39';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/39&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 28, 2006  09:58
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 28 Jul 2006 09:58:16 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/39</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Test-Driven Enterprise Code: Wednesday at 1:30 PM</title>
      <link>http://jbrains.ca/permalink/37</link>
      <description>&lt;div class='entry posting' id='entry-_posting_37'&gt;
&lt;div class='posting' id='content-_posting_37'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I will be presenting a tutorial entitled &amp;#8220;Test-Driven Enterprise Code&amp;#8221; (formerly &amp;#8220;Test-Driven J2EE&amp;#8221;) on Wednesday at 1:30 PM at Agile 2006. In this tutorial, which combines lecture, demonstration and a question-and-answer period, I will share techniques I have uncovered, learned, developed and stolen to solve the fundamental problem of writing fast, small, easy-to-understand tests in the presence of a wrath of expensive, external resources and frameworks. This session complements the &amp;#8220;Agile Web Development&amp;#8221; hands-on session in which I participated on Monday. I hope you&amp;#8217;ll be able to join us, as Gareth Powell and Naresh Jain will join me in answering your questions for the last hour of the session.&lt;/p&gt;
&lt;p&gt;See you in the afternoon!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/37';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/37&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 26, 2006  06:31
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2006&quot;&gt;agile 2006&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 26 Jul 2006 06:31:27 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/37</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Extreme Test Makeover, Monday at 1:30 PM</title>
      <link>http://jbrains.ca/permalink/36</link>
      <description>&lt;div class='entry posting' id='entry-_posting_36'&gt;
&lt;div class='posting' id='content-_posting_36'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Although I had originally planned to hang out at Extreme Test Makeover most of the afternoon, plans change. I will be there during my &amp;#8220;official&amp;#8221; time slot after lunch, and if I manage to get away from my other responsibilities long enough, I&amp;#8217;ll spend some more time there. If you have a codebase that needs tests, &lt;em&gt;any&lt;/em&gt; kinds of tests, we have the makeover artists to help you out! We&amp;#8217;ll help improve the testability of your design and teach you a few tricks of our trade.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Are your tests disheveled, flabby, or unfocused? Bring them in for a makeover! We&amp;#8217;ll have makeover artists who are experts in unit and acceptance testing, with tools such as Fit, JUnit, NUnit, Watir, and more. This is a hands-on session&amp;mdash;bring your laptop with your tests and a development environment, running and ready to test. Or just come and observe how the experts work&amp;#8230;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/36';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/36&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 24, 2006  12:54
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2006&quot;&gt;agile 2006&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 24 Jul 2006 12:54:46 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/36</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Freebird</title>
      <link>http://jbrains.ca/permalink/35</link>
      <description>&lt;div class='entry posting' id='entry-_posting_35'&gt;
&lt;div class='posting' id='content-_posting_35'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;The &amp;#8220;Agile Web Development&amp;#8221; session got off to a rocky start, as all such sessions do&amp;mdash;setting up the attendees&amp;#8217; machines is never straightforward in spite of our best efforts. Still, once people got going, it went well. Gareth Powell and Pat Welsh of Ternary Software unveiled a small Java framework named &amp;#8220;Freebird&amp;#8221; that aids in doing something the Java EE platform has never seem to got right: making simple things easy. One of the things I&amp;#8217;ve often said about Java EE is that simple features are as painstaking and time-consuming as complex ones, due to all the configuration. Freebird aims to change that.&lt;/p&gt;
&lt;p&gt;Thanks to all the people who joined our session. Thanks to Gareth and Pat for inviting me. Thanks to Dmitri Dolguikh for also joining the staff for the afternoon. I had fun.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/35';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/35&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 24, 2006  12:48
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2006&quot;&gt;agile 2006&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 24 Jul 2006 12:48:49 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/35</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Agile 2006: &quot;Agile Web Development&quot; at 1:30 PM on Sunday</title>
      <link>http://jbrains.ca/permalink/34</link>
      <description>&lt;div class='entry posting' id='entry-_posting_34'&gt;
&lt;div class='posting' id='content-_posting_34'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;The first item on the program is the hands-on session &amp;#8220;Agile Web Development&amp;#8221;, where I&amp;#8217;m helping out the folks from Ternary Software. From the abstract:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This session is a fully hands-on guided opportunity to test-drive real software changes using both unit and acceptance level tests working with these frameworks. [&amp;#8230;]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;People attending this session are highly recommended to also attend Test-Driven J2EE: Life Outside the Container with J.B. Rainsberger for a more in-depth understanding of the principles and techniques involved.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;See you there.&lt;p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/34';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/34&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 23, 2006  16:22
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2006&quot;&gt;agile 2006&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 23 Jul 2006 16:22:20 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/34</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Arrived at Agile 2006</title>
      <link>http://jbrains.ca/permalink/33</link>
      <description>&lt;div class='entry posting' id='entry-_posting_33'&gt;
&lt;div class='posting' id='content-_posting_33'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;We made it, and it was a very dull flight&amp;mdash;just the way I like it.&lt;/p&gt;
&lt;p&gt;Now it&amp;#8217;s off to register, find some lunch and meet up with old friends. Be on the lookout for me and don&amp;#8217;t hesitate to introduce yourself!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/33';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/33&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 23, 2006  16:17
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile-2006&quot;&gt;agile 2006&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 23 Jul 2006 16:17:52 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/33</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>True object testing when using the file system</title>
      <link>http://jbrains.ca/permalink/32</link>
      <description>&lt;div class='entry posting' id='entry-_posting_32'&gt;
&lt;div class='posting' id='content-_posting_32'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Click the title of this entry to read about how Vincent Massol tests Java code that uses the file system. I&amp;#8217;m glad to know there&amp;#8217;s such a thing as the &lt;a href=&quot;http://jakarta.apache.org/commons/vfs&quot;&gt;&lt;span class=&quot;caps&quot;&gt;VFS&lt;/span&gt; library, part of Jakarta Commons&lt;/a&gt;. I imagine I would have done essentially the same thing Vincent has done. I think I would try using &lt;span class=&quot;caps&quot;&gt;VFS&lt;/span&gt; the next time I&amp;#8217;m doing file system-intensive work in Java.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/32';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/32&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 17, 2006  22:12
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/java&quot;&gt;java&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 17 Jul 2006 22:12:42 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/32</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Extreme Test Makeover at Agile 2006</title>
      <link>http://jbrains.ca/permalink/31</link>
      <description>&lt;div class='entry posting' id='entry-_posting_31'&gt;
&lt;div class='posting' id='content-_posting_31'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I am one of the &amp;#8220;makeover artists&amp;#8221; at Extreme Test Makeover for Agile 2006. If you&amp;#8217;re attending and would like some code made over to be more testable &lt;em&gt;and&lt;/em&gt; tested, please bring it with you to Agile 2006 Monday afternoon. I will try to hang out there for much of the day, but my &amp;#8220;official&amp;#8221; time slot is &lt;strong&gt;1:30 PM to 3:00 PM&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For more information, join the discussion at the &lt;a href=&quot;http://groups.yahoo.com/group/test-makeover&quot;&gt;Extreme Test Makeover Yahoo! group&lt;/a&gt;. See you there!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/31';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/31&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 17, 2006  20:22
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/junit&quot;&gt;junit&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2006&quot;&gt;agile 2006&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 17 Jul 2006 20:22:07 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/31</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Mr. Happy Object, or Useless Examples in Articles</title>
      <link>http://jbrains.ca/permalink/30</link>
      <description>&lt;div class='entry posting' id='entry-_posting_30'&gt;
&lt;div class='posting' id='content-_posting_30'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I recently answered a question on the &lt;a href=&quot;http://groups.yahoo.com/group/junit&quot;&gt;junit Yahoo! group&lt;/a&gt;. The questioner included text from an article about when to use class-level (&lt;code&gt;static&lt;/code&gt;) methods and when to use instance-level methods. While I don&amp;rsquo;t wish to single out the article&amp;rsquo;s author, I do wish to single out the article, because I found its example ludicrous. To give you an idea, here is some of the article&amp;rsquo;s example:&lt;/p&gt;

&lt;pre&gt;
public class MrHappyObject {
    private String _mood = _HAPPY;

    private final static String _HAPPY = &quot;happy&quot;;
    private final static String _ANNOYED = &quot;annoyed&quot;;
    private final static String _ANGRY = &quot;angry&quot;;

    public void printMood() {
        System.out.println(&quot;I am &quot; + _mood);
    }

    public void receivePinch() {
        if (_mood.equals(_HAPPY)) {
            _mood = _ANNOYED;
        }
        else {
            _mood = _ANGRY;
        }
    }

    public void receiveHug() 
        if (_mood.equals(_ANGRY)) {
            _mood = _ANNOYED;        
        }
        else {
            _mood = _HAPPY;
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;Mr. Happy Object?! What kind of example is that? I don&amp;rsquo;t mean to be rude, but an example like this seems to serve only to insult the reader&amp;rsquo;s intelligence. I also find it lazy, although I admit it&amp;rsquo;s better than examples with nonsense like &lt;code&gt;int a = 3; int b = 4;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Please, if you&amp;#8217;re writing articles with code, please make the code examples at least somewhat meaningful. Use concepts that your readers will generally be able to understand. One person&amp;#8217;s humor is another person&amp;#8217;s condescension.&lt;/p&gt;
&lt;p&gt;As a footnote, let me make it clear that this is &lt;span style=&quot;font-style: italic;&quot;&gt;not&lt;/span&gt; an indictment of the author of this article. Many more than he use nonsensical examples in their writing.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/30';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/30&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 14, 2006  03:17
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/writing&quot;&gt;writing&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 14 Jul 2006 03:17:08 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/30</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>This site's downtime</title>
      <link>http://jbrains.ca/permalink/29</link>
      <description>&lt;div class='entry posting' id='entry-_posting_29'&gt;
&lt;div class='posting' id='content-_posting_29'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;If you&amp;#8217;ve noticed this site has had some unusual downtime recently, I&amp;#8217;ve noticed that, too. It looks like some differences between my TextDrive account&amp;#8217;s environment (notably the &lt;code&gt;PATH&lt;/code&gt; variable) and &lt;code&gt;cron&lt;/code&gt;&amp;#8217;s environment mean that my Rails applications were not starting when the server restarts. I think we have that fixed now, so I hope to avoid the problem in the future. I apologize for any annoyance or inconvenience as a result.&lt;/p&gt;
&lt;p&gt;It would be nice, though, to have a way of running my scripts in the same environment as &lt;code&gt;cron&lt;/code&gt; runs on my TextDrive server. I&amp;#8217;ll ask the nice folks at TextDrive about that, and see what they say.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/29';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/29&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 13, 2006  20:22
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 13 Jul 2006 20:22:17 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/29</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Rails: associations, foreign keys and NOT NULL</title>
      <link>http://jbrains.ca/permalink/28</link>
      <description>&lt;div class='entry posting' id='entry-_posting_28'&gt;
&lt;div class='posting' id='content-_posting_28'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I&amp;#8217;m confused, and I welcome some help.&lt;/p&gt;
&lt;p&gt;The Rails application I am working on has a richer model than my weblog does, so I have had to work with associations between model objects more than I had to before. This, on its own, is not a problem. The problem occurs when I combine Rails associations with &lt;code&gt;NOT NULL&lt;/code&gt; foreign keys. It seems to be slowing me down.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s an example: when you register for &lt;a href=&quot;http://montreal2006.xpday.info&quot;&gt;XP Day Montreal 2006&lt;/a&gt;, you can request an invoice if your company is forward-thinking enough to pay your way. (I&amp;#8217;m just jabbing a little&amp;mdash;hold your cards and letters.) No problem: you enter your company&amp;#8217;s contact information and we e-mail them an invoice. So far, so good, but what happens when we consider what happens in the model&amp;#8230; and the database?&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s no surprise that an &lt;code&gt;Order has_one :invoice&lt;/code&gt; and that an &lt;code&gt;Invoice belongs_to :order&lt;/code&gt;, I hope. This means that table &lt;code&gt;invoices&lt;/code&gt; has a foreign key to &lt;code&gt;orders&lt;/code&gt;, referring to the latter&amp;#8217;s &lt;code&gt;id&lt;/code&gt; column. &lt;em&gt;Of course&lt;/em&gt;, an invoice shouldn&amp;#8217;t exist without an order to which to attach itself, so the foreign key is &lt;code&gt;NOT NULL&lt;/code&gt;. I would think this makes perfect sense, but I&amp;#8217;m finding it difficult to deal with in Rails. The problem comes when I try to attach the invoice to its order in my controller. I seem to have fallen into a chicken-and-egg problem.&lt;/p&gt;
&lt;p&gt;When someone requests an invoice, it&amp;#8217;s possible they don&amp;#8217;t type enough information in, so of course I have added &lt;code&gt;validate_presence_of&lt;/code&gt; for those attributes of &lt;code&gt;Invoice&lt;/code&gt;. Now the only way I know how to check whether the invoice is fully filled-in is to save it:&lt;/p&gt;
&lt;pre&gt;
  def request_invoice
    flash[:notice] = &quot;We have sent an invoice as requested.&quot;
    @invoice = Invoice.new(params[:invoice])
    if @invoice.save
      session[:order].invoice = @invoice
      RegistrationMailer.deliver_invoice(@invoice)
      redirect_to :action =&amp;gt; 'thank_you'
    else
      render :partial =&amp;gt; 'request_invoice'
    end
  end
&lt;/pre&gt;
&lt;p&gt;The problem is that when I try to invoke &lt;code&gt;Invoice#save&lt;/code&gt;, I get this:&lt;/p&gt;
&lt;pre&gt;
ActiveRecord::StatementInvalid: RuntimeError: ERROR     C23502  Mnull value in column &quot;order_id&quot; violates not-null constraint....
&lt;/pre&gt;
&lt;p&gt;Now, since I invoke &lt;code&gt;Invoice#save&lt;/code&gt; explicitly,  and before the invoice is attached to the order, the invoice&amp;#8217;s &lt;code&gt;order&lt;/code&gt; is &lt;code&gt;nil&lt;/code&gt;. Just before I attach the invoice to its order, the database complains that I&amp;#8217;m inserting a &lt;code&gt;NULL&lt;/code&gt; into a &lt;code&gt;NOT NULL&lt;/code&gt; column. I wouldn&amp;#8217;t have this problem if I didn&amp;#8217;t invoke &lt;code&gt;Invoice#save&lt;/code&gt;, but then I wouldn&amp;#8217;t validate the invoice&amp;#8217;s fields that way, either.&lt;/p&gt;
&lt;p&gt;Damned if I do&amp;#8230;&lt;/p&gt;
&lt;p&gt;From where I sit, here are my options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Remove the &lt;code&gt;NOT NULL&lt;/code&gt; constraint from the &lt;code&gt;order_id&lt;/code&gt; column, which I dislike, because a &lt;code&gt;NULL&lt;/code&gt; foreign key doesn&amp;#8217;t make sense here.&lt;/li&gt;
&lt;li&gt;Explicitly set the &lt;code&gt;:order&lt;/code&gt; attribute on the new invoice, which I dislike, because everything I&amp;#8217;ve read makes it look like I shouldn&amp;#8217;t have to do that.&lt;/li&gt;
&lt;li&gt;Validate the invoice another way, such as invoking &lt;code&gt;Invoice#validate&lt;/code&gt; directly. I&amp;#8217;m unsure of this, because I don&amp;#8217;t even know whether it&amp;#8217;ll work at all, and I&amp;#8217;ve never had to do explicit validation before, so it seems too low-level&amp;mdash;Rails ought to handle this for me, somehow.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So since I don&amp;#8217;t know what good Rails style is yet, I could use &lt;a href=&quot;mailto:me@jbrains.info&quot;&gt;some advice&lt;/a&gt;.&lt;/p&gt;
&lt;hr /&gt;
&lt;p style=&quot;font-size: 80%;&quot;&gt;I decided to invoke &lt;code&gt;Invoice#valid?&lt;/code&gt; instead of &lt;code&gt;Invoice#save&lt;/code&gt;, since that communicates best of the above options. If there&amp;#8217;s something obviously better that I should I have done, do tell me.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/28';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/28&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 08, 2006  03:01
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/rails&quot;&gt;rails&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 08 Jul 2006 03:01:18 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/28</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Rails annoyance: ActionMailer and nil</title>
      <link>http://jbrains.ca/permalink/27</link>
      <description>&lt;div class='entry posting' id='entry-_posting_27'&gt;
&lt;div class='posting' id='content-_posting_27'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I&amp;#8217;m test-driving some e-mails, checking that the recipients are computed correctly and I have come across some annoying behavior in &lt;code&gt;ActionMailer&lt;/code&gt;. I would be indebted to anyone who could explain this to me.&lt;/p&gt;
&lt;p&gt;When I pay for your registration, I want to be CCd on the e-mails involved; however, when I pay for my own registration, there is no need for a CC list, so I think it ought to be empty. As a result, here is the test I wrote:&lt;/p&gt;
&lt;pre&gt;
  def test_pending_recipients_self_pay
    jbrains = people(:jbrains)

    response = RegistrationMailer.create_pending(
                   :attendee =&amp;gt; jbrains, 
                   :payer =&amp;gt; jbrains)
    
    assert_equal [jbrains.email], response.to
    assert_equal [], response.cc
    assert_equal [RegistrationMailer::ORGANIZER_EMAIL], response.bcc
  end
&lt;/pre&gt;
&lt;p&gt;Unfortunately, &lt;code&gt;response.cc&lt;/code&gt; returns &lt;code&gt;nil&lt;/code&gt;, rather than &lt;code&gt;[]&lt;/code&gt;. This forces to write the test this way:&lt;/p&gt;
&lt;pre&gt;
  def test_pending_recipients_self_pay
    jbrains = people(:jbrains)

    response = RegistrationMailer.create_pending(
                   :attendee =&amp;gt; jbrains, 
                   :payer =&amp;gt; jbrains)
    
    assert_equal [jbrains.email], response.to
    assert_nil response.cc
    assert_equal [RegistrationMailer::ORGANIZER_EMAIL], response.bcc
  end
&lt;/pre&gt;
&lt;p&gt;Why, oh why have this silly behavior? Is this a Ruby idiom I just have to get used to? It seems downright careless to force me to worry about whether the &amp;#8220;cc&amp;#8221; list is nil.&lt;/p&gt;
&lt;p&gt;Am I missing something? Is there a method I can invoke that hides this craziness from me? Should I report this to the Rails project as a bug? Please let me know.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/27';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/27&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 04, 2006  23:44
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/rails&quot;&gt;rails&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 04 Jul 2006 23:44:52 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/27</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Review: Rails Recipes</title>
      <link>http://jbrains.ca/permalink/26</link>
      <description>&lt;div class='entry posting' id='entry-_posting_26'&gt;
&lt;div class='posting' id='content-_posting_26'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&lt;a href=&quot;http://tinyurl.com/rrmdg&quot;&gt;&lt;img style=&quot;float: right; width: 150px;&quot; src=&quot;http://images.amazon.com/images/P/0977616606.01._AA240_SCLZZZZZZZ_.jpg&quot; alt=&quot;Rails Recipes&quot; /&gt;&lt;/a&gt;&lt;p&gt;I am a novice Rails programmer, that much is certain. As a result, I&amp;#8217;m &lt;em&gt;quite&lt;/em&gt; happy to have Chad Fowler&amp;#8217;s &lt;em&gt;Rails Recipes&lt;/em&gt; by my side. I have been part of the beta program for this book, so I&amp;#8217;ve been reading it in parts for the past few months. It has been impressive, to say the least. As an author of my own &amp;#8220;recipes&amp;#8221; book, I am interested to see other authors&amp;#8217; version of the recipe format, just in case I am able to incorporate something they do into a future book of my own. While &lt;em&gt;Rails Recipes&lt;/em&gt; hasn&amp;#8217;t taught me much about writing a recipes book, it &lt;em&gt;has&lt;/em&gt; taught me an awful lot of great things about Rails.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;I look forward to using Chad&amp;#8217;s recipes in my current projects. I already have a couple of ideas, including prettying up my URLs and creating a custom form builder. If I had one criticism, it&amp;#8217;s the relative paucity of testing recipes. Writing Rails applications test-first is still a struggle for me, and I know there are those from whom I can learn. I would like the opportunity. (How many of you would like to come to Toronto to teach me?) I suppose I&amp;#8217;ll have to write a few testing recipes of my own. Stay tuned.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Overall: 4 out of 5 on the amazon.com scale.&lt;/p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/26';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/26&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 04, 2006  22:17
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/rails&quot;&gt;rails&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/review&quot;&gt;review&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 04 Jul 2006 22:17:56 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/26</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>See you at Agile 2006</title>
      <link>http://jbrains.ca/permalink/25</link>
      <description>&lt;div class='entry posting' id='entry-_posting_25'&gt;
&lt;div class='posting' id='content-_posting_25'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;To those of you attending Agile 2006, I look forward either to seeing you again or meeting you. Find me and say, &amp;#8220;Hello.&amp;#8221; Buying me a drink is always welcome.&lt;/p&gt;
&lt;p&gt;Here is my speaking or presenting schedule, in case you want to catch me in action:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Sunday 7/23&lt;/strong&gt; at 1:30 PM&amp;mdash;Hands-on #1, Agile Software Development, co-hosting with Gareth Powell and the folks from Ternary Software&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Monday 7/24&lt;/strong&gt; 11:00 AM onward&amp;mdash;Hands-on #2, Extreme Test Makeover&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tuesday 7/25&lt;/strong&gt; at 1:30 PM&amp;mdash;Discovery session #12, The Truth about Programmers and Testers&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wednesday 7/26&lt;/strong&gt; at 1:30 PM&amp;mdash;Tutorial #30, Test-Driven J2EE&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The rest of the time, I&amp;#8217;ll be in Open Space, attending other sessions or just generally hanging out. Naturally, in the evenings, I&amp;#8217;ll be partying.&lt;/p&gt;
&lt;p&gt;See you there!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/25';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/25&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 04, 2006  18:07
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile-2006&quot;&gt;agile 2006&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 04 Jul 2006 18:07:18 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/25</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>The 401 tour</title>
      <link>http://jbrains.ca/permalink/24</link>
      <description>&lt;div class='entry posting' id='entry-_posting_24'&gt;
&lt;div class='posting' id='content-_posting_24'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;In August I will be going on a three-city tour to promote XP Day Montreal 2006. I will be speaking in Ottawa, Montreal and Toronto at the local XP or Agile user groups. The topic of my talk is &lt;strong&gt;Steering the Ship: The Joy and Heartbreak of Planning&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Planning is easy: pick a direction, write stories, prioritize, estimate, project and it&amp;#8217;s clear we can ship something in November and we&amp;#8217;ll be done in 2008.&lt;/p&gt;
&lt;p&gt;Planning is hard: I need it all, I need it all now, you&amp;#8217;re the programmer&amp;#8212;you know what to do.&lt;/p&gt;
&lt;p&gt;So which is it? Let&amp;#8217;s find out. Whatever else happens, plan on planning.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For more information, stay tuned to this weblog, or visit the various user groups&amp;#8217; web sites or mailing lists.&lt;/p&gt;
&lt;p&gt;(If you&amp;#8217;re wondering what &amp;#8220;401&amp;#8221; means, it&amp;#8217;s the highway that stretches in part from Toronto, through Ottawa to Montreal. It would be funnier if you lived here.)&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/24';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/24&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 04, 2006  17:56
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/xpday&quot;&gt;xpday&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 04 Jul 2006 17:56:55 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/24</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>I'll let you run the business if you let me handle the 1s and 0s...</title>
      <link>http://jbrains.ca/permalink/23</link>
      <description>&lt;div class='entry posting' id='entry-_posting_23'&gt;
&lt;div class='posting' id='content-_posting_23'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I&amp;#8217;m a fan of &lt;a href=&quot;http://www.thedailywtf.com&quot;&gt;The Daily &lt;span class=&quot;caps&quot;&gt;WTF&lt;/span&gt;&lt;/a&gt;, even though much of the time, they show us things I&amp;#8217;ve never seen from co-workers or a client. Sometimes it&amp;#8217;s helpful to be reminded just how differently people think. Ordinarily, I join in with the chorus of people singing, &amp;#8220;What an idiot!&amp;#8221; A &lt;a href=&quot;http://thedailywtf.com/forums/thread/79265.aspx&quot;&gt;recent thread&lt;/a&gt;, however, got me thinking.&lt;/p&gt;
&lt;p&gt;If you don&amp;#8217;t want to go read the thread, here is a summary: both the Product Manager and then the Marketing Directory of some random company don&amp;#8217;t want to include build information in the software because the users might interpret &lt;code&gt;Release 2.8 Build 448&lt;/code&gt; as &amp;#8220;it took us 28 releases and 448 builds to get it right!&amp;#8221; Naturally, what follows are reactions like &lt;em&gt;What idiots!&lt;/em&gt; and &lt;em&gt;Support would have nightmares!&lt;/em&gt;. Eventually, though, someone pointed out that we could simply use the release date to uniquely identify versions of the product for support. That&amp;#8217;s simple enough.&lt;/p&gt;
&lt;p&gt;One person responded with this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;These people should not be making technology related decisions. I guess when 99.99% of the world is full of retards, then the last 0.01% are left to do all the heavy thinking&amp;#8230; I really think that product managers should be able to be fired by the engineering staff, not the other way around.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I wonder about this. Is this &lt;em&gt;really&lt;/em&gt; a technology-related decision? We are displaying information to the end users, and everything we display is part of the corporation&amp;#8217;s brand image. This is why we have splash screens and put logos into web forms. If it is customer-facing, it affects how the customer perceives the brand and so perhaps it&amp;#8217;s a business decision. In particular, it might be a marketing or public relations decision.&lt;/p&gt;
&lt;p&gt;Imagine how far we can take this, though.&lt;/p&gt;
&lt;p&gt;Which of these are business decisions and which are technical decisions?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Splash screens and logos on forms&lt;/li&gt;
&lt;li&gt;Build numbers or version identifiers&lt;/li&gt;
&lt;li&gt;Release notes&lt;/li&gt;
&lt;li&gt;Information written to log files&lt;/li&gt;
&lt;li&gt;Defect rates&lt;/li&gt;
&lt;li&gt;Simplicity of the design&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/23';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/23&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 04, 2006  16:16
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 04 Jul 2006 16:16:56 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/23</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Just To Be Clear: Rails and customized model relationships</title>
      <link>http://jbrains.ca/permalink/22</link>
      <description>&lt;div class='entry posting' id='entry-_posting_22'&gt;
&lt;div class='posting' id='content-_posting_22'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;This is the beginning of a new pseudo-column, titled &lt;span style=&quot;font-style: italic;&quot;&gt;Just To Be Clear&lt;/span&gt;. I intend to write about things I learn after either misunderstanding or finding unclear the existing documentation on the subject. In many cases, I simply don&amp;#8217;t read carefully enough, but in general, I try to make as few assumptions as possible, and when that happens, sometimes I find gaps in either the literature or in product documentation. When I find those things, I will share them with you, partly as Google bait for the next poor soul who goes down the same path I do.&lt;/p&gt;
&lt;p&gt;The first instalment of &lt;span style=&quot;font-style: italic;&quot;&gt;Just To Be Clear&lt;/span&gt; has to do with customizing model relationships in Rails. As you might know, you can easily express a parent-child relationship by adding foreign keys to the underlying database tables, then the appropriate use of &lt;code&gt;:has_one&lt;/code&gt;, &lt;code&gt;:has_many&lt;/code&gt; and &lt;code&gt;:belongs_to&lt;/code&gt;. (While there&amp;#8217;s more to it than that, I hope that&amp;#8217;s enough explanation for now.) If you follow the naming conventions, you can get away with just doing this, for example:&lt;/p&gt;

&lt;pre&gt;
class Order &amp;lt; ActiveRecord::Base
  belongs_to :person
end
&lt;/pre&gt;
&lt;p&gt;In your database, you&amp;#8217;ll have a table named &lt;code&gt;orders&lt;/code&gt; with a foreign key named &lt;code&gt;person_id&lt;/code&gt; that refers to the &lt;code&gt;people&lt;/code&gt; table&amp;#8217;s &lt;code&gt;id&lt;/code&gt; column. But the person to whom the order belongs isn&amp;#8217;t just&amp;nbsp;&lt;span style=&quot;font-style: italic;&quot;&gt;any&lt;/span&gt; old person, but rather the&amp;nbsp;&lt;span style=&quot;font-style: italic;&quot;&gt;payer&lt;/span&gt;. As a result, I&amp;#8217;d rather call this person the payer in my code. Consulting&amp;nbsp;&lt;a href=&quot;http://www.amazon.com/exec/obidos/tg/detail/-/097669400X/ref=ase_masterprogram-20&quot;&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Agile Web Development with Rails&lt;/span&gt;&lt;/a&gt;, I find I can do this:&lt;/p&gt;

&lt;pre&gt;
class LineItem &amp;lt; ActiveRecord::Base
  belongs_to :paid_order,
             :class_name =&amp;gt; &quot;Order&quot;,
             :foreign_key =&amp;gt; &quot;order_id&quot;,
             :conditions =&amp;gt; &quot;paid_on is not null&quot;
end
&lt;/pre&gt;
&lt;p&gt;That seems simple enough, but I want to name my foreign key &lt;code&gt;payer_id&lt;/code&gt;, so Rails will &lt;span style=&quot;font-style: italic;&quot;&gt;probably&lt;/span&gt; understand that an order&amp;#8217;s &lt;code&gt;payer&lt;/code&gt; should correspond to the column &lt;code&gt;payer_id&lt;/code&gt;. It does everything else magically, so why not? I tried this:&lt;/p&gt;

&lt;pre&gt;
class Order &amp;lt; ActiveRecord::Base
  belongs_to :payer, :class_name =&amp;gt; &quot;Person&quot;
end
&lt;/pre&gt;
&lt;p&gt;Well, it didn&amp;#8217;t work. After 15 minutes of playing around in the Rails console, I noticed that my order objects had both a &lt;code&gt;payer_id&lt;/code&gt; and a &lt;code&gt;person_id&lt;/code&gt;, so while the &lt;code&gt;payer&lt;/code&gt; attribute was correctly assigned, the payer&amp;#8217;s id was assigned to &lt;code&gt;person_id&lt;/code&gt;, and not &lt;code&gt;payer_id&lt;/code&gt;. When I tried to save my order, the database would understandably complain about my trying to save a &lt;code&gt;NULL&lt;/code&gt; value in the &lt;code&gt;payer_id&lt;/code&gt; column.&lt;/p&gt;
&lt;p&gt;So, &lt;span style=&quot;font-style: italic;&quot;&gt;just to be clear&lt;/span&gt;, Rails&amp;#8217; magic does not extend to knowing that the relationship &lt;code&gt;:payer&lt;/code&gt; corresponds to a foreign key column &lt;code&gt;payer_id&lt;/code&gt;; instead, it assumes the foreign key column name follows the model class name convention, which in this case is &lt;code&gt;person_id&lt;/code&gt;. If you want the behavior I want, you &lt;span style=&quot;font-style: italic;&quot;&gt;need&lt;/span&gt; to specify the &lt;code&gt;:foreign_key&lt;/code&gt; option.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/22';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/22&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
July 01, 2006  20:20
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/rails&quot;&gt;rails&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/just-to-be-clear&quot;&gt;just to be clear&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 01 Jul 2006 20:20:11 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/22</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>This is why we pair (or, I am colossally stupid)</title>
      <link>http://jbrains.ca/permalink/21</link>
      <description>&lt;div class='entry posting' id='entry-_posting_21'&gt;
&lt;div class='posting' id='content-_posting_21'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I would like to publicly thank Anthony Williams for telling me the obvious reason why this weblog&amp;#8217;s font looked five sizes too big with Internet Explorer. This screenshot should say it all:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://images.jbrains.ca/IeFontSizeProblemMadeObvious.jpg&quot; /&gt;&lt;br /&gt;
&lt;p&gt;When I changed the second &amp;lt;h2&amp;gt; to &amp;lt;/h2&amp;gt;, the page magically looked normal in Internet Explorer.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;I would also like to think Anthony for introducing me to the Tidy plugin for Safari. With its help, I have eliminated all the errors and warnings from my main weblog page. I will be even happier once such a plugin appears for Camino.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Anthony, I owe you a beer.&lt;/p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/21';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/21&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 30, 2006  02:49
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 30 Jun 2006 02:49:05 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/21</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>CSS, Internet Explorer... I give up</title>
      <link>http://jbrains.ca/permalink/20</link>
      <description>&lt;div class='entry posting' id='entry-_posting_20'&gt;
&lt;div class='posting' id='content-_posting_20'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;For the moment, this site does not support Internet Explorer. Although I use the site stylesheet on three different sites, IE does not seem to render the pages on this site correctly. Since I don&amp;#8217;t know what to do, I&amp;#8217;m going to stop trying for now. Do not bother trying to visit this site with IE, as you won&amp;#8217;t be able to read it. At least there&amp;#8217;s an apologetic message awaiting you if you try. For now, it&amp;#8217;s the best I can do.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/20';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/20&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 28, 2006  01:52
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 28 Jun 2006 01:52:25 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/20</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>This weblog has a defect</title>
      <link>http://jbrains.ca/permalink/19</link>
      <description>&lt;div class='entry posting' id='entry-_posting_19'&gt;
&lt;div class='posting' id='content-_posting_19'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Today I tried to show someone an article on my weblog. When we navigated there with Internet Explorer, we were surprised to see very, very large letters. The font on IE appears to be about 5 times as large as it renders with Camino or Firefox. I don&amp;#8217;t know what the problem is yet, but I&amp;#8217;m dealing with it now. In a few moments, I&amp;#8217;m going to add an alert to the site that detects IE and says, &amp;#8220;Sorry, there&amp;#8217;s a defect here that makes this site look weird in IE. Please try another browser until we fix the problem. We&amp;#8217;re working on it.&amp;#8221; I hope to have fixed the problem in the next hour or so. We&amp;#8217;ll see.&lt;/p&gt;
&lt;p&gt;I suppose I could say I didn&amp;#8217;t test enough, but I&amp;#8217;ve never seen this kind of problem before, so I couldn&amp;#8217;t possibly have anticipated it. The good news is this: I&amp;#8217;m about to learn something.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/19';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/19&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 27, 2006  23:29
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 27 Jun 2006 23:29:14 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/19</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>10 ways to guarantee your presentation is a dismal failure</title>
      <link>http://jbrains.ca/permalink/18</link>
      <description>&lt;div class='entry posting' id='entry-_posting_18'&gt;
&lt;div class='posting' id='content-_posting_18'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Have you ever wondered what makes great presenters great? I do, and while I don&amp;#8217;t have the secrets to greatness, I can provide a recipe for disaster. You might not have to do all these things in the same presentation to fail miserably, but certainly if you have the discipline to do them all, only failure can possibly follow.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Show up late&lt;/span&gt;. I imagine few things show less respect for an audience than not showing up on time. If you have problems during your presentation, they will typically be less inclined to give you the benefit of the doubt. Some will dismiss you as a bozo, and you might not enjoy that.&lt;/li&gt;
	&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Make lame jokes about showing up late&lt;/span&gt;. You might think you&amp;#8217;re lightening the mood or injective some levity, but subconsciously, you&amp;#8217;re probably just trying to deflect responsibility to someone or something else. If you&amp;#8217;re late, you&amp;#8217;re late&amp;mdash;admit it, apologize, then move on.&lt;/li&gt;
	&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Prepare, a little&lt;/span&gt;. The less you prepare, the less likely you&amp;#8217;ll be able to handle problems during your presentation, and the less likely your words will hang together and make sense as a whole.&lt;/li&gt;
	&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Assume your equipment will work&lt;/span&gt;. I use a Mac for my presentations, and so I usually ask the host whether I should expect any problems connecting to their projector. It is important to distinguish, &amp;#8220;No, there will not be any problems&amp;#8221; from &amp;#8220;I don&amp;#8217;t see any reason why there should be a problem.&amp;#8221; The first indicates that previous presenters have successfully connected with their Mac, and the second indicates that no-one knows what will happen. Especially in the second case, prepare for the worst to happen.&lt;/li&gt;
	&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Don&amp;#8217;t have back-up materials&lt;/span&gt;. When the worst happens and you can&amp;#8217;t use your visual material, you need some kind of back-up plan, whether it&amp;#8217;s to ignore the material entirely, draw on a whiteboard or something else.&lt;/li&gt;
	&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Let technical problems distract you&lt;/span&gt;. When your visuals fail you, it&amp;#8217;s back to execute your back-up plan and move forward. If you let the problems distract you, then you won&amp;#8217;t be present for your audience and they will notice. Put yourself in the frame of mind of someone that doesn&amp;#8217;t have visual equipment at all, that way you won&amp;#8217;t be tempted to &amp;#8220;resume the normal program&amp;#8221; if, by some minor miracle, things work themselves out. Concentrate on your message and do your best to present it.&lt;/li&gt;
	&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Try to fix technical problems while continuing to present&lt;/span&gt;. Even if your audience somehow doesn&amp;#8217;t notice when you&amp;#8217;re distracted, they will&amp;nbsp;&lt;span style=&quot;font-style: italic;&quot;&gt;certainly&lt;/span&gt; notice when you half-ignore them. If you really want to solve your technical problems, excuse yourself, take the time to concentrate on fixing the problem, then fix it. If after a minute or two you have no solution, then ignore the visuals and move on. Do not, however, talk to the computer or projector as thought it were the audience. If you&amp;#8217;re going to talk to the audience, then give them your full attention.&lt;/li&gt;
	&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Make lame jokes to cover your frustration&lt;/span&gt;. While I wouldn&amp;#8217;t go so far as to say, &amp;#8220;Never let &amp;#8217;em see you sweat,&amp;#8221; being passive-aggressive in your reaction to your frustration is no good either. Your audience will understand if you&amp;#8217;re frustrated, but they want you to get past it and say what you came to say. Making jokes to cover your frustration helps you remain distracted by it, and as I&amp;#8217;ve already said here, that keeps your attention divided, and the audience will not appreciate that.&lt;/li&gt;
	&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Forget your key premise&lt;/span&gt;. What worse outcome from frustration could there be than forgetting your key premise? The audience has already put up with your late arrival, your inability to get over technical problems, and now you leave them wondering just what on earth you were talking about. Can it get any worse?&lt;/li&gt;
	&lt;li&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Just give up&lt;/span&gt;. Your audience wants you to succeed. If you let yourself, you can almost feel them pulling for you, in spite of all the problems you&amp;#8217;ve gone through in front of them. The audience deserves your best effort, so giving up near the end, rather than collecting yourself and getting over the finish line is a cop out. If you plan to do that, then don&amp;#8217;t accept the next invitation to speak.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For direction and suggestions on great presenting, I heartily recommend following the advice of people like &lt;a href=&quot;http://blog.guykawasaki.com/&quot;&gt;Guy Kawasaki&lt;/a&gt; and &lt;a href=&quot;http://www.presentationzen.com&quot;&gt;Garr Reynolds&lt;/a&gt;, as well as watching presentations from dynamic speakers like Steve Jobs.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/18';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/18&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 25, 2006  15:18
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/xp2006&quot;&gt;xp2006&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sun, 25 Jun 2006 15:18:17 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/18</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Test-Driven J2EE... the apology</title>
      <link>http://jbrains.ca/permalink/17</link>
      <description>&lt;div class='entry posting' id='entry-_posting_17'&gt;
&lt;div class='posting' id='content-_posting_17'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I would like to apologize to those who attended my tutorial at XP 2006. It seems I suffered from food poisoning at breakfast, and it wasn&amp;#8217;t until about 30 minutes into my tutorial that I began to feel the full effects. After one day of violent illness and one day of recovery, I&amp;#8217;m rejoining the conference today (Monday). I appreciate your understanding and hope that I can make this experience up to you at a later date. If you have any suggestions on what I can do, please e-mail me to let me know (me at jbrains dot info).&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/17';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/17&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 19, 2006  05:04
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Mon, 19 Jun 2006 05:04:26 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/17</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Test-Driven J2EE at XP 2006... the presentation</title>
      <link>http://jbrains.ca/permalink/16</link>
      <description>&lt;div class='entry posting' id='entry-_posting_16'&gt;
&lt;div class='posting' id='content-_posting_16'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Click the title of this entry for the presentation slides for Test-Driven J2EE from XP 2006.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/16';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/16&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 17, 2006  07:51
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/xp2006&quot;&gt;xp2006&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 17 Jun 2006 07:51:46 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/16</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Test-Driven J2EE at XP 2006... corrected</title>
      <link>http://jbrains.ca/permalink/15</link>
      <description>&lt;div class='entry posting' id='entry-_posting_15'&gt;
&lt;div class='posting' id='content-_posting_15'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have uploaded an improved version of the Test-Driven J2EE project in response to a defect I released. (Shame on me!) If you receive this error message when you deploy:&lt;/p&gt;

&lt;pre&gt;18:25:30,078 ERROR [MainDeployer] Could not create deployment: file:/C:/jboss-4.0.4/server/all/deploy/coffee.war&amp;lt;br&amp;gt;org.jboss.ws.WSException: java.lang.ClassNotFoundException: org.apache.cactus.server.ServletTestRedirector&lt;/pre&gt;
&lt;p&gt;this means that I left some configuration behind related to Cactus. Since I don&amp;#8217;t include Cactus in the project, it cannot deploy properly. You can either change the file &lt;code&gt;conf/coffee.war/web.xml&lt;/code&gt; to remove the references to Cactus or download the project archive again (by clicking the title of this entry).&lt;/p&gt;
&lt;p&gt;I apologize for the confusion. See you at 9 AM!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/15';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/15&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 16, 2006  23:18
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/xp2006&quot;&gt;xp2006&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 16 Jun 2006 23:18:28 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/15</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Live from Oulu</title>
      <link>http://jbrains.ca/permalink/14</link>
      <description>&lt;div class='entry posting' id='entry-_posting_14'&gt;
&lt;div class='posting' id='content-_posting_14'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;We have arrived in Oulu, and are now on the hunt for some power adapters to accommodate the plethora of electronics we have brought with us. This is the one part of the trip we&amp;#8217;ve done a poor job of planning.&lt;/p&gt;
&lt;p&gt;So we are at the hotel. For anyone else attending XP 2006 who has arrived, feel free to e-mail me (me at jbrains dot info) and let me know whether you&amp;#8217;re interested in getting together for food or drinks sometime in the next few hours.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/14';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/14&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 16, 2006  12:20
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/xp2006&quot;&gt;xp2006&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 16 Jun 2006 12:20:09 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/14</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>A complaint about OpenOffice Impress? (Maybe not.)</title>
      <link>http://jbrains.ca/permalink/13</link>
      <description>&lt;div class='entry posting' id='entry-_posting_13'&gt;
&lt;div class='posting' id='content-_posting_13'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have just spent the past 30 minutes cleaning up about 50 presentation slides. Most of the clean-up was related to re-applying a standard layout to all the slides, something that Open Office&amp;#8217;s Impress application doesn&amp;#8217;t allow me to do in bulk. This meant clicking on each slide, re-applying the layout, then moving to the next. As I was doing this, I first thought, &lt;span style=&quot;font-style: italic;&quot;&gt;Why doesn&amp;#8217;t Impress make this easier?&lt;/span&gt; My second thought was &lt;span style=&quot;font-style: italic;&quot;&gt;Why do I have so many slides?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I believe it&amp;#8217;s too late to fix this for tomorrow, since it&amp;#8217;s easier to skip over slides than it is to move that content into a new format for my attendees to use, but I think I need to address this problem before Agile 2006 in July. We&amp;#8217;ll see how disciplined I am. (Care to wager?)&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/13';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/13&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 16, 2006  12:17
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/speaking&quot;&gt;speaking&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/xp2006&quot;&gt;xp2006&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/presenting&quot;&gt;presenting&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 16 Jun 2006 12:17:02 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/13</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>An observation about Helsinki</title>
      <link>http://jbrains.ca/permalink/12</link>
      <description>&lt;div class='entry posting' id='entry-_posting_12'&gt;
&lt;div class='posting' id='content-_posting_12'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;After 8 hours aboard a Finnair flight, I&amp;#8217;m happy to be in Helsinki. To say the flight was uncomfortable would be a mild understatement, so it&amp;#8217;s a good thing I slept through 6 of the 8 hours. I am sitting in an airport cafe, sipping cappuccino while Sarah tours the shops. My first bit of mild culture shock is the proliferation of blond people: after years of living in ethnically-diverse Toronto, I am struck by the relative homogeneity of the people here. Of course, this is entirely a superficial observation, but it strikes me nonetheless. In about 3 hours we will arrive in Oulu. I look forward to reaching the hotel and resting before trying to find fellow conference-goers for a late lunch or some early drinks. In the meantime, I&amp;#8217;m working a little on improving the presentation material for Test-Driven J2EE, mostly by shortening it.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/12';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/12&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 16, 2006  12:15
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Fri, 16 Jun 2006 12:15:48 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/12</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Test-Driven J2EE at XP 2006</title>
      <link>http://jbrains.ca/permalink/11</link>
      <description>&lt;div class='entry posting' id='entry-_posting_11'&gt;
&lt;div class='posting' id='content-_posting_11'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;For those of you attending my Test-Driven J2EE tutorial Saturday morning at XP 2006, here are rough-and-ready instructions for preparing your machine to work. If you don&amp;#8217;t bring a laptop with you, don&amp;#8217;t worry, you can pair with someone else!&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Install Eclipse 3.1.1 (sorry, it has to be that version).&lt;/li&gt;
	&lt;li&gt;Create a new workspace, just to avoid overwriting any settings you care about.&lt;/li&gt;
	&lt;li&gt;Under &lt;span style=&quot;font-weight: bold;&quot;&gt;Installed JREs&lt;/span&gt;, choose &lt;span class=&quot;caps&quot;&gt;JDK&lt;/span&gt; 1.4 (not &lt;span class=&quot;caps&quot;&gt;JDK&lt;/span&gt; 1.5).&lt;/li&gt;
	&lt;li&gt;Install the Web Tools Platform (&lt;span class=&quot;caps&quot;&gt;WTP&lt;/span&gt;) from update site http://download.eclipse.org/webtools/updates/, then restart the workbench when prompted to do so.&lt;/li&gt;
	&lt;li&gt;Install &lt;a href=&quot;http://sourceforge.net/project/showfiles.php?group_id=22866&amp;amp;package_id=16942&amp;amp;release_id=416591&quot;&gt;JBoss 4.0.4&lt;/a&gt; from jboss.org.&lt;/li&gt;
	&lt;li&gt;Install &lt;a href=&quot;http://download.jboss.org/jbosside/builds/release/1.5.1.GA/all/JBossIDE-1.5.1.GA-ALL.zip&quot;&gt;JBoss-&lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt; 1.5.1 GA All Plugins&lt;/a&gt; by unzipping the package, then copying the contents into the &lt;code&gt;plugins&lt;/code&gt; and &lt;code&gt;features&lt;/code&gt; directories of your Eclipse installation.&lt;/li&gt;
	&lt;li&gt;Download &lt;a href=&quot;http://www.jbrains.ca/TestDrivenJ2EE.zip&quot;&gt;this Eclipse project&lt;/a&gt;, then unzip it to your file system.&lt;/li&gt;
	&lt;li&gt;Import the project into your workspace, calling the project &lt;span style=&quot;font-weight: bold;&quot;&gt;TestDrivenJ2EE&lt;/span&gt;.&lt;/li&gt;
	&lt;li&gt;Open the project&amp;#8217;s properties, choose &lt;span style=&quot;font-weight: bold;&quot;&gt;Packaging configuration&lt;/span&gt;, then enable packaging.&lt;/li&gt;
	&lt;li&gt;Run all the tests in the source folder &lt;code&gt;tests/source&lt;/code&gt;. &lt;span style=&quot;font-style: italic;&quot;&gt;Ignore one warning in XMLTestCase, since this is a defect in either the JUnit test runner or XMLUnit.&lt;/span&gt;&lt;/li&gt;
	&lt;li&gt;Run packaging for the project. (Right-click the project, choose &lt;span style=&quot;font-weight: bold;&quot;&gt;Run packaging&lt;/span&gt;.)&lt;/li&gt;
	&lt;li&gt;Create a JBoss test server through the &lt;span style=&quot;font-weight: bold;&quot;&gt;Debug&amp;#8230;&lt;/span&gt; menu.&lt;/li&gt;
	&lt;li&gt;Deploy the project to your new test server. &lt;blockquote&gt;If this step fails with an error message about &lt;code&gt;ServletTestRedirector&lt;/code&gt;, then you have an older version of the Eclipse project. Download it again. See &lt;a href=&quot;http://www.jbrains.info/postings/read/15&quot;&gt;this entry&lt;/a&gt; for details.&lt;/blockquote&gt;&lt;/li&gt;
	&lt;li&gt;Start the JBoss server (in Debug mode).&lt;/li&gt;
	&lt;li&gt;Run all the tests in the source folder &lt;code&gt;livetests/source&lt;/code&gt;. All the tests should pass.&lt;/li&gt;
	&lt;li&gt;Open a browser and go to &lt;code&gt;http://localhost:8080/coffee&lt;/code&gt;. You should see a Register link. Try playing around with the application.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you&amp;#8217;re unsure how to perform any of these steps, dive in and read some documentation. If you&amp;#8217;re completely unfamiliar with Eclipse, then it might be better to pair with someone else in the tutorial, if you prefer not to learn Eclipse at this point.&lt;/p&gt;
&lt;p&gt;See you Saturday morning!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/11';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/11&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 15, 2006  19:12
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 15 Jun 2006 19:12:59 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/11</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Heading to Finland for XP 2006</title>
      <link>http://jbrains.ca/permalink/10</link>
      <description>&lt;div class='entry posting' id='entry-_posting_10'&gt;
&lt;div class='posting' id='content-_posting_10'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Well, my wife and I are making the final preparations for our flight to Oulu, Finland for XP 2006. This is my first time attending the European XP conference, so I&amp;#8217;m looking forward to the new experience. We had such fun traveling to Paris for XP Day France 2006, so I&amp;#8217;m hoping for more of the same in beautiful Oulu.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ll be presenting Test-Driven J2EE at the conference, as well as an experience report and sitting on a panel discussion about Agile Software and Open Source. I enjoy being so involved in the conference, but I&amp;#8217;m mostly looking forward to the after-conference activities: sitting in pubs chatting with colleagues over drinks. To me, this is the real value of these conferences. Many of my fellow attendees agree. What&amp;#8217;s more is that I&amp;#8217;ll get to meet many members of the European XP community that I only know from the mailing lists. I look forward to meeting you!&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ll try to chronicle my experience at XP 2006, but I might be too busy doing it to write about it. That&amp;#8217;s how it goes!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/10';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/10&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 15, 2006  16:32
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 15 Jun 2006 16:32:11 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/10</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Ruby: concatenation or interpolation?</title>
      <link>http://jbrains.ca/permalink/9</link>
      <description>&lt;div class='entry posting' id='entry-_posting_9'&gt;
&lt;div class='posting' id='content-_posting_9'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I have a question about Ruby coding standards. As I read more Ruby code, I see a haphazard combination of string concatenation and interpolation, sometimes in the same line of code.&lt;/p&gt;
&lt;pre&gt;
def nice_title
  (title || works[0].nice_title) +
  &quot; (#{publisher.name}, #{year})&quot;
end
&lt;/pre&gt;
&lt;p&gt;(from David A. Black, &lt;a href=&quot;http://www.amazon.com/exec/obidos/tg/detail/-/1932394699/ref=ase_masterprogram-20&quot;&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Ruby on Rails&lt;/span&gt;&lt;/a&gt;, page 409.)&lt;/p&gt;
&lt;p&gt;Wouldn&amp;#8217;t this method be better written like so?&lt;/p&gt;
&lt;pre&gt;
def nice_title
  &quot;#{title || works[0].nice_title} (#{publisher.name}, #{year})&quot;
end
&lt;/pre&gt;
&lt;p&gt;This is no slight against David&amp;mdash;his book is excellent, and I&amp;#8217;ll be reviewing it soon&amp;mdash;but it seems odd to mix concatenation and interpolation together like this. If you&amp;#8217;re a Ruby programmer and have an opinion on this issue, please click the title of this entry and send me your thoughts.&lt;/p&gt;
&lt;p&gt;It boils down to this question:&amp;nbsp;I tend favor interpolation over concatentation. Is there any specific reason not to do this?&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/9';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/9&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 07, 2006  22:31
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 07 Jun 2006 22:31:31 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/9</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>That's unacceptable</title>
      <link>http://jbrains.ca/permalink/8</link>
      <description>&lt;div class='entry posting' id='entry-_posting_8'&gt;
&lt;div class='posting' id='content-_posting_8'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I don&amp;#8217;t think there are two more useless words in the English language, especially when strung together, as &amp;#8220;that&amp;#8217;s unacceptable&amp;#8221;. One colleague tells me those words are merely a cry for help. The person who utters them is often trying to tell you, &amp;#8220;That creates a problem I don&amp;#8217;t know how to solve&amp;#8221;, but is unable to bring himself to say that.&lt;/p&gt;
&lt;p&gt;I am interested in stories about a situation where someone said &amp;#8220;That&amp;#8217;s unacceptable&amp;#8221;, but it turned out all right. I&amp;#8217;d like to know how someone in that situation handled those words and turned them into a problem-solving resource or merely helped the speaker admit his underlying problem.&lt;/p&gt;
&lt;p&gt;If you have such a story, please send e-mail to unacceptable at jbrains dot info.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/8';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/8&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 07, 2006  16:32
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/people&quot;&gt;people&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 07 Jun 2006 16:32:48 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/8</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Annoying personality flaw</title>
      <link>http://jbrains.ca/permalink/7</link>
      <description>&lt;div class='entry posting' id='entry-_posting_7'&gt;
&lt;div class='posting' id='content-_posting_7'&gt;
&lt;div style='text-align: justify'&gt;
&lt;blockquote&gt;Without getting into all the details and causing any one person too much embarassment, I think the problem is that I&amp;#8217;m a Mac user and, as a result, have an annoying personality flaw where I just want things to work.&lt;/blockquote&gt;
&lt;p&gt;Thanks to &lt;a href=&quot;http://blog.alancfrancis.com&quot;&gt;Alan Francis&lt;/a&gt; for this one. I think I have the same flaw.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/7';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/7&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 06, 2006  17:41
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/mac&quot;&gt;mac&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 06 Jun 2006 17:41:11 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/7</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>This is why we pair...</title>
      <link>http://jbrains.ca/permalink/6</link>
      <description>&lt;div class='entry posting' id='entry-_posting_6'&gt;
&lt;div class='posting' id='content-_posting_6'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I was flipping through &lt;a href=&quot;http://manuals.rubyonrails.com/read/book/5&quot;&gt;A Guide to Testing the Rails&lt;/a&gt;&amp;mdash;can I use that metaphor with e-documents?&amp;mdash;and I ran across an interesting line of code:&lt;/p&gt;
&lt;pre&gt;
destinations = destinations.collect{|x| approved.collect{|y| (x==y ? x : nil)}}.flatten.compact
&lt;/pre&gt;
&lt;p&gt;It took me a few moments to parse it and begin to understand it. I think someone was in a hurry. Isn&amp;#8217;t this just this?&lt;/p&gt;
&lt;pre&gt;
destinations = destinations.select { | x | approved.include?(x) }
&lt;/pre&gt;
&lt;p&gt;I&amp;#8217;m not saying the author is a bad programmer. Quite the opposite: even good programmers need to pair to avoid doing things the long way.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/6';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/6&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 03, 2006  19:43
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/agile&quot;&gt;agile&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 03 Jun 2006 19:43:11 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/6</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Faking methods in Ruby</title>
      <link>http://jbrains.ca/permalink/4</link>
      <description>&lt;div class='entry posting' id='entry-_posting_4'&gt;
&lt;div class='posting' id='content-_posting_4'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;A design technique I use frequently is &lt;em&gt;faking&lt;/em&gt; methods: reimplementing a method in a way that makes the current test easy to write. This can be returning a hardcoded answer, throwing a hardcoded exception or causing some other process to occur. Whatever it is, it&amp;#8217;s generally simpler than what the production implementation of that collaborator does. When testing an object that collaborates with others, I often fake some of the others&amp;#8217; methods to see how the object under test reacts. This is easy when objects are loosely coupled: faking a method on an interface is as easy as falling out of bed, thanks to &lt;a href=&quot;http://www.jmock.org&quot;&gt;JMock&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When the &amp;#8220;collaborator&amp;#8221; is the object under test itself, though, things become a little more interesting. Frequently I have to test objects that have &lt;a href=&quot;http://www.objectmentor.com/resources/articles/srp&quot;&gt;too many responsibilities&lt;/a&gt;, and when that happens, I often have to resort to a technique called &lt;a href=&quot;http://www.amazon.com/exec/obidos/tg/detail/-/0131177052/ref=ase_masterprogram-20&quot;&gt;Subclass to Test&lt;/a&gt;. (I don&amp;#8217;t have my copy handy, so I can&amp;#8217;t quote the page, but it&amp;#8217;s in there.) As good a legacy code technique as that is, I am&amp;nbsp;&lt;span style=&quot;font-style: italic;&quot;&gt;always&lt;/span&gt; nervous when I subclass the class under test, so assuming I can change the code, I usually go through these steps:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Subclass to test [&lt;span class=&quot;caps&quot;&gt;WELC&lt;/span&gt;, &lt;a href=&quot;#beggingForWelc&quot;&gt;???&lt;/a&gt;]&lt;/li&gt;
	&lt;li&gt;Replace inheritance with delegation [Refactoring, 352]&lt;/li&gt;
	&lt;li&gt;Extract interface (from the new collaborator) [Refactoring, 341]&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now I can fake the interface and all is well. As a result, I am able to move the design one step further in the direction it wants to go: towards being loosely coupled and easy to test. The bad news is that this is quite a bit more involved than simply subclassing to test. While subclassing to test is smelly&amp;mdash;I find myself forgetting exactly what I&amp;#8217;m testing&amp;mdash;it is straightforward, and to be preferred as long as it doesn&amp;#8217;t get out of control. (I should trust myself more.)&lt;/p&gt;
&lt;p&gt;I found myself wanting to do this while work on my weblog, which you might know is a Rails application. In particular, I wanted to test some special handling of request parameters in my controller: in order to tag my weblog entries with different categories, I have checkboxes for each category, so I can check as many as I want for a particular entry. Based on my limited knowledge of Rails, when submitting a form, I get a hash that looks something like this: &lt;/p&gt;

&lt;pre&gt;{&quot;categories&quot; =&amp;gt; {&quot;0&quot; =&amp;gt; &quot;1&quot;, &quot;1&quot; =&amp;gt; &quot;0&quot;, &quot;2&quot; =&amp;gt; &quot;0&quot;, &quot;3&quot; =&amp;gt; &quot;1&quot;, ...}}&lt;/pre&gt;
&lt;p&gt;The keys in the innermost hash are category IDs and the values are &amp;#8220;1&amp;#8221; for &lt;span style=&quot;font-style: italic;&quot;&gt;checked&lt;/span&gt; and &amp;#8220;0&amp;#8221; for &lt;span style=&quot;font-style: italic;&quot;&gt;unchecked&lt;/span&gt;. I wanted to convert these into a collection of &lt;code&gt;Category&lt;/code&gt; objects, so that I could create the corresponding &lt;code&gt;Tag&lt;/code&gt;s when I create the &lt;code&gt;Posting&lt;/code&gt;. &lt;span style=&quot;font-style: italic;&quot;&gt;Naturally&lt;/span&gt;, I test-drove converting the hash structure into an array of &lt;code&gt;Category&lt;/code&gt; objects. Since I don&amp;#8217;t know how where classes belong in this brave new world, I put the production code directly in the &lt;code&gt;TestCase&lt;/code&gt; class, like so:&lt;/p&gt;

&lt;pre&gt;
class ParseCategoriesForPostingTest &amp;lt; Test::Unit::TestCase
  # Tests omitted for brevity...

  def selected_categories(params)
    params[&quot;categories&quot;].reject { | key, value | value == &quot;0&quot; } 
  end
 
  def selected_category_ids(params)
    selected_categories(params).keys.collect { | each | each.to_i }
  end
 
  def categories_chosen(params)
    chosen_ids = selected_category_ids(params)
    Category.find(:all).select { | each | chosen_ids.include?(each.id) }
  end
end
&lt;/pre&gt;
&lt;p&gt;I sense two bad smells: (1) production code among the tests, and (2) duplicating the parameter &lt;code&gt;params&lt;/code&gt;. The first of these smells was easy to handle: I moved these methods into the controller, as utility methods.&lt;/p&gt;

&lt;pre&gt;
class PostingsController &amp;lt; ApplicationController
  # Code omitted for brevity...

  # Simplifying method; a bridge to the ugly utility methods
  def categories_chosen
    self.class.categories_chosen(params)
  end
  
  def self.selected_categories(params)
    params[&quot;categories&quot;].reject { | key, value | value == &quot;0&quot; }  
  end
  
  def self.selected_category_ids(params)
    selected_categories(params).keys.collect { | each | each.to_i }
  end
  
  def self.categories_chosen(params)
    chosen_ids = selected_category_ids(params)
    Category.find(:all).select { | each | chosen_ids.include?(each.id) }
  end
end
&lt;/pre&gt;
&lt;p&gt;The other smell took a little more thought to handle. In Java, I would introduce a new class called &lt;code&gt;PostingsRequest&lt;/code&gt; that wraps the incoming request and interprets the request parameters in a business-friendly way. The new class &lt;code&gt;PostingsRequest&lt;/code&gt; would have a method &lt;code&gt;categoriesChosen()&lt;/code&gt; that returns the collection of &lt;code&gt;Category&lt;/code&gt; objects, just as I want. I could have done this in Ruby, but I wanted to find a more Rubyesque solution. As often happens, I needed to sleep on it. Early in the morning, I had a Ruby&lt;span style=&quot;font-style: italic;&quot;&gt;ish&lt;/span&gt; solution: introduce a module called &lt;code&gt;PostingsRequest&lt;/code&gt; and mix it in to the &lt;code&gt;PostingsController&lt;/code&gt;. The new module would be a home for these utility methods, and they would no longer need to be utility methods.&amp;nbsp;&lt;/p&gt;

&lt;pre&gt;
module PostingsRequest
  def selected_categories
    params[&quot;categories&quot;].reject { | key, value | value == &quot;0&quot; }  
  end
  
  def selected_category_ids
    selected_categories.keys.collect { | each | each.to_i }
  end
  
  def categories_chosen
    chosen_ids = selected_category_ids
    Category.find(:all).select { | each | chosen_ids.include?(each.id) }
  end
  
  # Depends on method 'params', returning a hash of request parameters
end
&lt;/pre&gt;
&lt;p&gt;Now, I certainly did &lt;span style=&quot;font-style: italic;&quot;&gt;not&lt;/span&gt; need to introduce a module to do this. I could have simply made these methods instance methods on the controller and be done with it, but it bothers me a little that a Rails controller has this extra responsibility of representing the incoming request parameters (through the method params). As a result, I didn&amp;#8217;t want to make things worse by tacking on more responsibilities, so I pushed that out to a module that the controller can mix in.&lt;/p&gt;
&lt;p&gt;So how do I test this? It&amp;#8217;s easy to test the controller, because it provides the &lt;code&gt;params&lt;/code&gt; method, but the module does not define it. In essence, the &lt;code&gt;params&lt;/code&gt; method is deferred (in the Eiffel sense&amp;mdash;think abstract if you&amp;#8217;re a Java programmer). I&amp;nbsp;&lt;span style=&quot;font-style: italic;&quot;&gt;could&lt;/span&gt; define the method to raise &amp;#8220;Thou shalt implement me&amp;#8221;, but I don&amp;#8217;t want to run the risk of accidentally replacing someone else&amp;#8217;s well-meaning definition of the method, such as in the case of including multiple modules. I would hate for the&amp;nbsp;&lt;span style=&quot;font-style: italic;&quot;&gt;order&lt;/span&gt; of including modules to matter! (This is part of a larger concern about programming with open classes. I prefer not to do anything that might lead to undue confusion. I&amp;#8217;m sure I&amp;#8217;ll become more comfortable later.) Then it struck me: thanks to &lt;a href=&quot;http://www.amazon.com/exec/obidos/tg/detail/-/1932394699/ref=ase_masterprogram-20&quot;&gt;David Black&lt;/a&gt;, I know I can implement &lt;code&gt;params&lt;/code&gt; with an object method, and &lt;span style=&quot;font-style: italic;&quot;&gt;differently for each test&lt;/span&gt;! &lt;a href=&quot;http://tinyurl.com/pkkrz&quot;&gt;Bingo&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;
class ParseCategoriesForPostingTest &amp;lt; Test::Unit::TestCase
  include PostingsRequest
  
  fixtures :categories
  
  def test_none
    # A crude kind of subclass to test
    def self.params
      {&quot;categories&quot;=&amp;gt;{&quot;1&quot;=&amp;gt;&quot;0&quot;, &quot;2&quot;=&amp;gt;&quot;0&quot;, &quot;3&quot;=&amp;gt;&quot;0&quot;, &quot;4&quot;=&amp;gt;&quot;0&quot;, &quot;5&quot;=&amp;gt;&quot;0&quot;}}
    end
    assert_set_equal [], categories_chosen
  end
  
  def test_one
    def self.params
      {&quot;categories&quot;=&amp;gt;{&quot;1&quot;=&amp;gt;&quot;0&quot;, &quot;2&quot;=&amp;gt;&quot;1&quot;, &quot;3&quot;=&amp;gt;&quot;0&quot;, &quot;4&quot;=&amp;gt;&quot;0&quot;, &quot;5&quot;=&amp;gt;&quot;0&quot;}}
    end
    assert_set_equal [Category.find(2)], categories_chosen
  end
  
  def test_many
    def self.params
      {&quot;categories&quot;=&amp;gt;{&quot;1&quot;=&amp;gt;&quot;0&quot;, &quot;2&quot;=&amp;gt;&quot;1&quot;, &quot;3&quot;=&amp;gt;&quot;0&quot;, &quot;4&quot;=&amp;gt;&quot;1&quot;, &quot;5&quot;=&amp;gt;&quot;1&quot;}}
    end
    assert_set_equal [Category.find(2), Category.find(4), Category.find(5)], categories_chosen
  end

  def test_collect_many_category_ids
    def self.params
      {&quot;categories&quot;=&amp;gt;{&quot;1&quot;=&amp;gt;&quot;0&quot;, &quot;2&quot;=&amp;gt;&quot;1&quot;, &quot;3&quot;=&amp;gt;&quot;0&quot;, &quot;4&quot;=&amp;gt;&quot;1&quot;, &quot;5&quot;=&amp;gt;&quot;1&quot;}}
    end
    assert_set_equal [2, 4, 5], selected_category_ids
  end
  
  def test_selected_categories
    def self.params
      {&quot;categories&quot;=&amp;gt;{&quot;1&quot;=&amp;gt;&quot;0&quot;, &quot;2&quot;=&amp;gt;&quot;1&quot;, &quot;3&quot;=&amp;gt;&quot;0&quot;, &quot;4&quot;=&amp;gt;&quot;1&quot;, &quot;5&quot;=&amp;gt;&quot;1&quot;}}
    end
    assert_equal({&quot;2&quot;=&amp;gt;&quot;1&quot;, &quot;4&quot;=&amp;gt;&quot;1&quot;, &quot;5&quot;=&amp;gt;&quot;1&quot;}, selected_categories)
  end
end
&lt;/pre&gt;
&lt;p&gt;Now it&amp;#8217;s true that this is &lt;span style=&quot;font-style: italic;&quot;&gt;essentially&lt;/span&gt; Subclass to Test, but I find it much less intrusive in Ruby than I did in Java. Somehow, it&amp;#8217;s less frightening, so I&amp;#8217;m going to try it for a while to see where it breaks down. Maybe it will; maybe it won&amp;#8217;t. One thing is certain: it&amp;#8217;s much less work than it is in Java!&lt;/p&gt;
&lt;p&gt;&lt;a name=&quot;beggingForWelc&quot;&gt;&lt;/a&gt;I lost my copy of &lt;span style=&quot;font-style: italic;&quot;&gt;Working Effectively with Legacy Code&lt;/span&gt; in the great flood of &amp;#8216;05. If you have a copy kicking around, I&amp;#8217;ll take it off your hands.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/4';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/4&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 01, 2006  22:32
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/rails&quot;&gt;rails&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/testing&quot;&gt;testing&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 01 Jun 2006 22:32:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/4</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Goodbye, ugly URL</title>
      <link>http://jbrains.ca/permalink/3</link>
      <description>&lt;div class='entry posting' id='entry-_posting_3'&gt;
&lt;div class='posting' id='content-_posting_3'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;To everyone who has subscribed to my weblog&amp;#8217;s feed at a &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; specifying port 8728, you can switch to &lt;a href=&quot;http://www.jbrains.ca/weblog/rss&quot;&gt;http://www.jbrains.ca/weblog/rss&lt;/a&gt;. I apologize for the inconvenience. I don&amp;#8217;t suspect port 8728 will move any time soon, but I make no guarantee that you will find the weblog on that port forever.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/3';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/3&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
June 01, 2006  20:40
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 01 Jun 2006 20:40:51 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/3</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Ruby annoyance: Hash#reject and Hash#select</title>
      <link>http://jbrains.ca/permalink/2</link>
      <description>&lt;div class='entry posting' id='entry-_posting_2'&gt;
&lt;div class='posting' id='content-_posting_2'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I love Ruby&amp;mdash;I really do.&lt;/p&gt;
&lt;p&gt;Now that I have begun doing serious work in Ruby, I am running into things I don&amp;#8217;t quite like about the language. This is the first &amp;#8220;Ruby Annoyance&amp;#8221;, and it&amp;#8217;s a small one, but a strange one, because it&amp;#8217;s a direct breach of the &lt;em&gt;Principle of Least Surprise&lt;/em&gt;. It sure surprises me!&lt;/p&gt;
&lt;p&gt;I have a bunch of checkboxes on a web page, and when the user submits the form, I get a hash mapping database IDs to &amp;#8220;0&amp;#8221; or &amp;#8220;1&amp;#8221; (for &amp;#8220;off&amp;#8221; and &amp;#8220;on&amp;#8221;, respectively). I need to convert this hash to an array of &lt;code&gt;Category&lt;/code&gt; objects. To do this, I first convert the hash to an array of category IDs as numbers. After fiddling around for a while, I have code like this:&lt;/p&gt;
&lt;pre&gt;
params[&quot;categories&quot;].reject { | key, value | value != &quot;1&quot; }.keys.collect { | each | each.to_i }
&lt;/pre&gt;
&lt;p&gt;So far, so good: remove the hash items whose value isn&amp;#8217;t &amp;#8220;on&amp;#8221;, grab the keys, then convert each to an integer. Very functional programming-esque of me. (Some days I think I get it.) Still, I prefer positive to negative code, so I&amp;#8217;d like to replace &lt;code&gt;reject&lt;/code&gt; with &lt;code&gt;select&lt;/code&gt;, so I try this:&lt;/p&gt;
&lt;pre&gt;
params[&quot;categories&quot;].select { | key, value | value == &quot;1&quot; }.keys.collect { | each | each.to_i }
&lt;/pre&gt;
&lt;p&gt;My test fails, with this: &lt;code&gt;Exception: undefined method `keys' for [[&quot;2&quot;, &quot;1&quot;], [&quot;4&quot;, &quot;1&quot;], [&quot;5&quot;, &quot;1&quot;]]:Array&lt;/code&gt;. Now &lt;em&gt;that&lt;/em&gt; is surprising: &lt;code&gt;reject&lt;/code&gt; returns a new hash with the offending items removed, but &lt;code&gt;select&lt;/code&gt; returns a 2d array?!&lt;/p&gt;
&lt;p&gt;As always with this kind of thing, I&amp;#8217;m sure &lt;em&gt;someone&lt;/em&gt; thought this was a good idea, but since &lt;code&gt;select&lt;/code&gt; and &lt;code&gt;reject&lt;/code&gt; are supposed to be partitioning functions, shouldn&amp;#8217;t their return types be the same? In other words, if I merge the results of &lt;code&gt;select&lt;/code&gt; and &lt;code&gt;reject&lt;/code&gt; (with the same predicate, of course), I should get back the original hash. I can&amp;#8217;t say with authority that this is how Smalltalk behaves, but I&amp;#8217;d be surprised if it doesn&amp;#8217;t.&lt;/p&gt;
&lt;p&gt;So, for now, I shall stick with the double negative &amp;#8220;reject all entries whose value is not &amp;#8216;1&amp;#8217;&amp;#8221;, in spite of the fact that I abhor it. Using &lt;code&gt;select&lt;/code&gt; forces me to traverse a 2d array, rather than sending &lt;code&gt;keys&lt;/code&gt; to the subhash.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ll stick with the double negative. How annoying.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/2';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/2&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 31, 2006  16:52
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/rails&quot;&gt;rails&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/ruby&quot;&gt;ruby&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/article&quot;&gt;article&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Wed, 31 May 2006 16:52:37 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/2</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Welcome to the new weblog!</title>
      <link>http://jbrains.ca/permalink/1</link>
      <description>&lt;div class='entry posting' id='entry-_posting_1'&gt;
&lt;div class='posting' id='content-_posting_1'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;I am proud to announce my new weblog, tentatively titled &lt;strong&gt;Can&amp;#8217;t stop the learning&lt;/strong&gt;. After several months of procrastinating and approximately 3 days of work, I have managed to hit version 0.1 of my own weblog software, written on &lt;a href=&quot;http://www.rubyonrails.org&quot;&gt;Ruby on Rails&lt;/a&gt;. The experience, at times annoying, has nevertheless being mostly positive. This is a very nice platform on which to work.&lt;/p&gt;
&lt;p&gt;Old weblog entries will migrate over here as time and desire permit. Until then, use the navigation links to go over to &lt;a href=&quot;http://www.diasparsoftware.com/weblog&quot;&gt;diasparsoftware.com&lt;/a&gt; to read my previous weblog.&lt;/p&gt;
&lt;p&gt;This software will go through some changes as the days and weeks roll on, so I don&amp;#8217;t recommend bookmarking individual entries. Bookmark the weblog instead, as URLs might change underneath you.&lt;/p&gt;
&lt;p&gt;Choose the &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt; icon in the menu for the new &lt;span class=&quot;caps&quot;&gt;RSS&lt;/span&gt; feed.&lt;/p&gt;
&lt;p&gt;Thank you to all my faithful readers and to those who created the technology upon which this humble application sits. Great job!&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/1';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/1&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
May 23, 2006  04:00
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Tue, 23 May 2006 04:00:03 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/1</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Services</title>
      <link>http://jbrains.ca/permalink/224</link>
      <description>&lt;div class='entry posting' id='entry-_posting_224'&gt;
&lt;div class='posting' id='content-_posting_224'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;&lt;a href=&quot;/training&quot;&gt;Training&lt;/a&gt; &amp;middot; &lt;a href=&quot;/coaching&quot;&gt;Coaching&lt;/a&gt; &amp;middot; &lt;a href=&quot;/speaking&quot;&gt;Speaking&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My name is J. B. Rainsberger and I provide a variety of services in four main areas: improving individual habits, improving teamwork and improving the flow of value, teaching others to coach.&lt;/p&gt;
&lt;p&gt;I work with programmers, testers, business analysts, and product owners to improve their day-to-day work habits. I help programmers sharpen their design skills. I show them a model of simple design that includes rules they can follow to develop a deep understanding of modular design. Armed with this model, programmers build more flexible, easier-to-maintain systems. I help testers find their most effective role in the organization. Rather than simply executing someone else&amp;#8217;s test plan, I show testers key techniques and heuristics that help them become better agents of the business. I help business analysts and product owners satisfy their customers more. I teach them how to eliminate unnecessary features from their product plans and how to work effectively with programmers and testers to deliver the most valuable features sooner. I also help individuals in any role improve their overall effectiveness with key personal planning techniques. I help them avoid rework, avoid being stalled and the general feeling of hopelessness that comes with too much work and too little time.&lt;/p&gt;
&lt;p&gt;I help teams manage their workload, understand the value of healthy conflict, and take full benefit of their variety of styles, knowledge and perspectives. I use two well-known models of teamwork (Five Dysfunctions and the Wexler-Sibbett model) to help teams develop working agreements, charter projects, understand their role, understand the scope of their responsibility and feel comfortable holding each other to account for fulfilling their responsibilities. The result is a team that works better together and produces better results over time. Sometimes the result includes a re-alignment of people on teams.&lt;/p&gt;
&lt;p&gt;I help organizations measure and improve the flow of value at any scale. We can focus on small processes, including promoting features to production, building the software and gathering requirements; or we can look at larger processes, including funding projects, handling support issues and bringing new features to market quickly. I use concepts from the Theory of Constraints to identify the roadblocks to realizing revenue for products and services, then help decide how to measure the problem, what it means to solve the problem, and how much of the problem to solve. I emphasize increasing the flow of value over cutting costs, because there tends to be a much higher ceiling on revenue than the lowest floor on costs.&lt;/p&gt;
&lt;p&gt;I help others learn how to teach and coach effectively through role-playing, practice presenting, and discussions about specific situations they encounter. As I learn to act as a more effective instructor and coach, I share what I learn with others. I use techniques described by &lt;a href=&quot;http://www.edwardtufte.com&quot;&gt;Edward Tufte&lt;/a&gt; and &lt;a href=&quot;http://www.presentationzen.com&quot;&gt;Garr Reynolds&lt;/a&gt; to present information effectively. I use ideas from &lt;a href=&quot;http://geraldmweinberg.com&quot;&gt;Gerald Weinberg&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Virginia_Satir&quot;&gt;Virginia Satir&lt;/a&gt; to inform my communication style and coaching philosophy. I also find benefit from parts of Appreciative Inquiry, the Dreyfus Model of Skills Acquisition, The Power of Full Engagement, and The Five Dysfunctions of a Team, among others.&lt;/p&gt;
&lt;p&gt;I provide these services through a combination of consulting, coaching, and training. You should consider consulting or coaching when you know the symptoms, but not the cure. I will help you decide what results matter, decide how to measure progress towards improving those results, and decide on a plan to achieve those results. You should consider training when you&amp;#8217;ve chosen the cure, but don&amp;#8217;t know how to administer it.&lt;/p&gt;
&lt;p&gt;Tim Gallwey, in &lt;a href=&quot;http://tinyurl.com/c8ylek&quot;&gt;&lt;em&gt;The Inner Game of Work&lt;/em&gt;&lt;/a&gt; points out the difference between coaching and training.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The process for reaching your potential is called coaching. The process for increasing your potential is called training.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I can work with you to outline a consulting or coaching engagement that would benefit you. Among the training I can deliver are courses like these:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Introduction to XP or Agile practices&lt;/li&gt;
	&lt;li&gt;XP or Agile project kickoff&amp;mdash;iteration 1 of your project&lt;/li&gt;
	&lt;li&gt;Mastering Modular Design with Test-Driven Development&lt;/li&gt;
	&lt;li&gt;From Concept to Cash: Deliver Software Sooner&lt;/li&gt;
	&lt;li&gt;Delivering The Minimum Marketable Feature&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are just a few examples. I prefer to work with you directly to design a course that meets your needs, which could include elements of the services I have outlined above.&lt;/p&gt;
&lt;p&gt;I offer my services primarily in English, mais je parle aussi assez de fran&#231;ais pour pouvoir entendre et r&#233;pondre aux questions pos&#233;es en fran&#231;ais, y de vez en cuando, ser&#225; posible de comunicar en espa&#241;ol, especialmente si me hablan lentamente.&lt;/p&gt;
&lt;p&gt;I look forward to the opportunity to work with you. Please contact me at the email address at the top of this page to find out more. I provide my services through Diaspar Software Services, a Canadian software consulting company.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/training&quot;&gt;Training&lt;/a&gt; &amp;middot; &lt;a href=&quot;/coaching&quot;&gt;Coaching&lt;/a&gt; &amp;middot; &lt;a href=&quot;/speaking&quot;&gt;Speaking&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/224';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/224&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 01, 2005  00:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/training&quot;&gt;training&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/services&quot;&gt;services&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coaching&quot;&gt;coaching&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/consulting&quot;&gt;consulting&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 01 Jan 2005 00:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/224</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Comments on Test-Driven Development training</title>
      <link>http://jbrains.ca/permalink/245</link>
      <description>&lt;div class='entry posting' id='entry-_posting_245'&gt;
&lt;div class='posting' id='content-_posting_245'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Here are some comments from students who have taken my courses on test-driven development and modular design techniques. I have been asked to protect the names of most of the commenters.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Joe, I had the good fortune to spend four days in your &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; course at Obtiva in September (2009) and still hear you saying these words every time I&amp;#8217;ve written a line of code since: &amp;#8220;Remove duplication and fix bad names&amp;#8221;. I scribbled it down as you said it during the course but have only come to realise its importance in the subsequent months. My code and confidence has improved because of it!&lt;/em&gt; &amp;#8211; J.M.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I think that I&amp;#8217;ve learned more in this training class than I have in my entire professional programming career. I thought that was very successful in giving us the information that we need in an easily digestable way.&lt;/em&gt; &amp;#8211; C.H.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Joe has an amazing grasp on test-driven development and JUnit and has probably the most extensive Java knowledge of any person I have met. I feel that the information and practices that he gave us in the course will be invaluable.&lt;/em&gt; &amp;#8211; B.O.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The course is definitely an eye-opener, even to those versed in traditional &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; mindset; it gives the opportunity to view &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; from a bit of a different angle, and can only improve upon already learned patterns.&lt;/em&gt; &amp;#8211; C.S.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Joe&amp;#8217;s class was a real eye-opener.  I knew we could do things better from a development perspective, but Joe gave me a glimpse of just how much.  What I liked most about the class is that it wasn&amp;#8217;t presented as a &amp;#8216;silver bullet&amp;#8217;, but a better approach requiring dedication and discipline.&lt;/em&gt; &amp;#8211; R.M.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/245';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/245&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 01, 2004  00:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/training&quot;&gt;training&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 01 Jan 2004 00:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/245</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>I have received your request and am working on it</title>
      <link>http://jbrains.ca/permalink/273</link>
      <description>&lt;div class='entry posting' id='entry-_posting_273'&gt;
&lt;div class='posting' id='content-_posting_273'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Thank you for contacting me about engaging my services. Please allow two full business days for a response.&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/273';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/273&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 01, 2004  00:00
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 01 Jan 2004 00:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/273</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Engaging my services in October 2009</title>
      <link>http://jbrains.ca/permalink/274</link>
      <description>&lt;div class='entry posting' id='entry-_posting_274'&gt;
&lt;div class='posting' id='content-_posting_274'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;Thank you for your interest in engaging my services in early October 2009. Please send me a request with this form.&lt;/p&gt;
&lt;form method=&quot;POST&quot; action=&quot;http://fp1.formmail.com/cgi-bin/fm192&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;_pid&quot; value=&quot;118344&quot;&gt;&lt;/input&gt;
&lt;input type=&quot;hidden&quot; name=&quot;_fid&quot; value=&quot;85LXID61&quot;&gt;&lt;/input&gt;
&lt;input type=&quot;hidden&quot; name=&quot;recipient&quot; value=&quot;2&quot;&gt;&lt;/input&gt;
&lt;p&gt;&lt;b&gt;Name:&lt;/b&gt; &lt;input type=&quot;text&quot; name=&quot;realname&quot; size=40&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;E-Mail:&lt;/b&gt; &lt;input type=&quot;text&quot; name=&quot;email&quot; size=40&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;City:&lt;/b&gt; &lt;input type=&quot;text&quot; name=&quot;city&quot; size=40&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Preferred dates:&lt;/b&gt; &lt;input type=&quot;text&quot; name=&quot;preferred_date&quot; size=40&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;A few things I should know:&lt;/b&gt;&lt;br/&gt;&lt;textarea rows=&quot;4&quot; cols=&quot;60&quot; name=&quot;comments&quot;&gt;&lt;/textarea&gt;&lt;/p&gt;
&lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;Send email&quot;&gt;&lt;/p&gt;
&lt;/form&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/274';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/274&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 01, 2004  00:00
&lt;/span&gt;
&amp;nbsp;

&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Thu, 01 Jan 2004 00:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/274</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
    <item>
      <title>Make your tests work for you: Europe, October 1-2 or 5-6, 2009</title>
      <link>http://jbrains.ca/permalink/275</link>
      <description>&lt;div class='entry posting' id='entry-_posting_275'&gt;
&lt;div class='posting' id='content-_posting_275'&gt;
&lt;div style='text-align: justify'&gt;
&lt;p&gt;You&amp;#8217;ve written dozens, or perhaps hundreds, of tests for your codebase, but you still find bugs.&lt;/p&gt;
&lt;p&gt;You&amp;#8217;re written hundreds of tests for your codebase, and now nobody will run them because they take 15 minutes to execute.&lt;/p&gt;
&lt;p&gt;You&amp;#8217;ve written hundreds of tests for your codebase, and now when you try to add one line of code to one of your classes, that causes twelve of your tests to fail. It would take only two minutes to change the code, but two hours to fix the tests.&lt;/p&gt;
&lt;p&gt;To cope, you&amp;#8217;ve started writing fewer tests. You&amp;#8217;ve noticed a rise in defects. You&amp;#8217;re worried that all the work you&amp;#8217;ve done to write those tests will amount to nothing.&lt;/p&gt;
&lt;p&gt;I can help.&lt;/p&gt;
&lt;p&gt;My name is J. B. Rainsberger and I specialize in helping groups work past the first obstacle for people who practice test-driven or behavior-driven development and reach their first plateau of achievement. If you have been learning &lt;span class=&quot;caps&quot;&gt;TDD&lt;/span&gt; or &lt;span class=&quot;caps&quot;&gt;BDD&lt;/span&gt; for several months and have written a few hundred tests, then I can help you work through the problems I&amp;#8217;ve seen people in your position have.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;When I change data in our test data set, I have to fix a dozen tests for old features.&lt;/li&gt;
	&lt;li&gt;Our tests get in the way of refactoring: I make one small change and it causes 15 tests to fail.&lt;/li&gt;
	&lt;li&gt;We find bugs, even though all our tests pass.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;#8217;ve seen many groups have these same problems, and I find the same root cause every time: they do not understand how to interpret these problems as weaknesses in their design. I can teach you how to do that.&lt;/p&gt;
&lt;p&gt;Take advantage of working with a world-class practitioner and consultant whose specializes in making your tests work for you without having to pay for travel expenses.&lt;/p&gt;
&lt;p&gt;I will find myself in Paris, France in early October, and I would like the opportunity to share my solutions to these problems with you. I can make myself available for one-day or two-day engagements on 1-2 October or 5-6 October. If I can reach you by train in about four hours, then I&amp;#8217;d like to work with you. You can show me how your tests have started working against you and I can share the secrets to making them work for you again.&lt;/p&gt;
&lt;p&gt;To get started, please visit &lt;a href=&quot;http://www.jbrains.ca/october2009&quot;&gt;http://www.jbrains.ca/october2009&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div style='text-align: right; margin: 0px 0px 0px 0px; padding: 0px 0px 0px 0px'&gt;
&lt;p&gt;


      &lt;script type=&quot;text/javascript&quot;&gt;
      digg_url = 'http://jbrains.ca/permalink/275';
      digg_skin = &quot;compact&quot;;
      &lt;/script&gt;
      &lt;script src=&quot;http://digg.com/tools/diggthis.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
    

      &lt;script type=&quot;text/javascript&quot;&gt;
      reddit_url = &quot;http://jbrains.ca/permalink/275&quot;;
      &lt;/script&gt;
      &lt;script type=&quot;text/javascript&quot; src=&quot;http://www.reddit.com/button.js?t=1&quot;&gt;&lt;/script&gt;
    
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p class='meta'&gt;
&lt;span class='date'&gt;
January 01, 2000  00:00
&lt;/span&gt;
&amp;nbsp;
&lt;a href=&quot;http://jbrains.ca/category/named/rails&quot;&gt;rails&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/coding-standards&quot;&gt;coding standards&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/design&quot;&gt;design&lt;/a&gt;, &lt;a href=&quot;http://jbrains.ca/category/named/extreme-programming&quot;&gt;extreme programming&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
</description>
      <pubDate>Sat, 01 Jan 2000 00:00:00 GMT</pubDate>
      <guid>http://jbrains.ca/permalink/275</guid>
      <author>me@jbrains.ca (J. B. Rainsberger)</author>
    </item>
  </channel>
</rss>
