<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Object Mentor Blog</title>
    <link>http://blog.objectmentor.com</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Rudimentary TDD with XCode and Objective-C</title>
      <description>We have a potential client that would like us to teach a &lt;span class="caps"&gt;TDD&lt;/span&gt; class in several languages simultaneously:
	&lt;ul&gt;
	&lt;li&gt;Java&lt;/li&gt;
		&lt;li&gt;JavaScript&lt;/li&gt;
		&lt;li&gt;C++&lt;/li&gt;
		&lt;li&gt;Objective-C&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;In turns out that for what we teach in our &lt;span class="caps"&gt;TDD&lt;/span&gt; class, Java, C++ and Objective-C can be taught at the same time fairly easily. JavaScript, however, not so much. It is a very different (great, but different) beast.&lt;/p&gt;


	&lt;p&gt;In fact I could add C# to the mix as well, but I&amp;#8217;d have to leave out &lt;span class="caps"&gt;LINQ&lt;/span&gt; and Lambdas.&lt;/p&gt;


	&lt;p&gt;In any case, to teach a class like that, I prefer to have the students do a bit of preliminary work so that they know how to set up their environments. When there&amp;#8217;s just one language, I do this on the fly. But when there&amp;#8217;s 3, I don&amp;#8217;t want 2/3rds of the class waiting while 1/3rd learns how to create a basic project supporting &lt;span class="caps"&gt;TDD&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;The last time I used Objective-C was in 1991, so I needed to figure out how to do this in the environment it is most likely to be used. This turned out to be a bit more work than I expected. I found it all using the good old google-machine, but in pieces. Since there really wasn&amp;#8217;t a great (in my opinion) one-stop place that clearly laid out all of the steps, &lt;a href="http://schuchert.wikispaces.com/tdd.objectivec.XCodeProjectSetup"&gt;I created one&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;This is in a early state. If you have comments, I&amp;#8217;d appreciate them. I&amp;#8217;ll probably add more. (If you&amp;#8217;d like to see more, let me know that as well.) At this point, the basics are pretty much there, so I don&amp;#8217;t actually need to do anything else. However, I have taken this just a bit further: &lt;a href=http://schuchert.wikispaces.com/tdd.objectivec.AFirstProject"&gt;This is the top-level of the tutorial&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Again, comments and suggestions welcome.&lt;/p&gt;</description>
      <pubDate>Mon, 08 Feb 2010 18:24:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:76caf33c-893e-4e12-9803-e4f2992165ba</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/02/08/rudimentary-tdd-with-xcode-and-objective-c</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>objective</category>
      <category>c</category>
      <category>xcode</category>
      <category>ocunit</category>
    </item>
    <item>
      <title>CppUTest Recent Experiences</title>
      <description>&lt;h2&gt;Background&lt;/h2&gt;
Mid last year I ported several exercises from Java to C++. At that time, I used CppUTest 1.x and Boost 1.38. Finally, half a year later, it was time to actually brush the dust off those examples and make sure they still work.&lt;p/&gt;

	&lt;p&gt;They didn&amp;#8217;t. Bit rot. Or user error. Not sure which.&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;Bit rot&lt;/b&gt;: bits decay to the point where things start failing. Compiled programs&lt;i&gt; &lt;b&gt;do&lt;/b&gt;&lt;/i&gt; have a half-life.&lt;p/&gt;
&lt;b&gt;User Error&lt;/b&gt;: maybe things were not checked in as clean as I remember. Though I suspect they were, I don&amp;#8217;t really have any evidence to prove it, so I have to leave that option available.&lt;/p&gt;


	&lt;p&gt;To add to the mix, I decided to upgrade to CppUTest 2.x and to the latest version of the Boost library (1.41). I think that broke many several things. But the fixes were simple, once I figured out what I needed to do.&lt;/p&gt;


&lt;h2&gt;The Fixes&lt;/h2&gt;
What follows are the three things I needed to do to get CppUTest 2.0, Boost and those exercises playing nicely together.&lt;p/&gt;

&lt;h3&gt;Header File Include Order&lt;/h3&gt;
First, I used to have the header file for the CppUTest Test Harness, &lt;CppUTest/TestHarness.h&gt; included first. It seems logical, but it caused all sorts of problems with CppUTest 2. That header file, includes a file, that ultimately includes something that uses macros to redefine new and delete. This is done so the testing framework can do simple memory tracking, which lets you know if your unit tests contains memory leaks.&lt;p/&gt;

	&lt;p&gt;I like this feature. Sure, it&amp;#8217;s simple and light-weight, but it coves a lot of ground for a little hassle. The hassle? Include that header file last, instead of first. Problem Solved. Well at least the code compiles without hundreds of errors.&lt;p/&gt;&lt;/p&gt;


&lt;h3&gt;Boost Shared Pointer&lt;/h3&gt;
Rather than hold pointers directly, I used the boost shared pointer class for a light-weight way to manage memory allocation. This is something I would do on a real project as well.&lt;p/&gt;

	&lt;p&gt;Somehow, the updated memory tracking in CppUTest 2.0 found something I had missed when using CppUTest 1.0.&lt;/p&gt;


	&lt;p&gt;I need to be able to control the date, so I have a simple date factory. By default, the date factory, when asked for the current date, returns the current date. Several unit tests want to simulate different dates. E.g., check out a book on one day, return it 14 days later. To do that, I manipulate the date factory (a form of dependency injection). This works fine, but by default the date factory is allocated using new.&lt;p/&gt;&lt;/p&gt;


When I replaced the existing date factory, I was not resetting it after the test. It turns out that this did not break anything because I was &amp;#8220;lucky&amp;#8221;. (Actually unlucky, I like things to&lt;i&gt; &lt;b&gt;fail fast&lt;/b&gt;&lt;/i&gt;.) CppUTest caught this in the form of not deallocating memory correctly:
	&lt;ul&gt;
	&lt;li&gt;I want to replace behavior&lt;/li&gt;
		&lt;li&gt;To do so I used polymorphism&lt;/li&gt;
		&lt;li&gt;Polymorphism in C++ requires virtual methods (please don&amp;#8217;t correct me by suggesting that overloading is polymorphism, that is an opinion with which I strongly disagree)&lt;/li&gt;
		&lt;li&gt;Methods are only virtually dispatched via references or pointers&lt;/li&gt;
		&lt;li&gt;References cannot be changed, so I must use a pointer if I want a substitutable factory, which I wanted&lt;/li&gt;
		&lt;li&gt;Pointers suggest dynamic memory allocation&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;To fix this, I updated the setup method to store the original date factory in an attribute and then I updated the teardown method to restore the original date factory from that attribute. That I missed this suggests that my test suite is not adequate. I did not fix this problem for no good reason other than I was porting existing tests, so I left it as is. For the context it will not cause a problem. Pragmatic or lazy? You decide.&lt;p/&gt;&lt;/p&gt;


&lt;h3&gt;One Time Allocation&lt;/h3&gt;
Here is a simple utility that uses Boost dates and regex:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_cpp "&gt;ptime DateUtil::dateFromString(const string &amp;amp;dateString) {
  boost::regex e(&amp;quot;^(\\d{1,2})/(\\d{1,2})/(\\d{4})$&amp;quot;);
  string replace(&amp;quot;\\3/\\1/\\2&amp;quot;);
  string isoDate = boost::regex_replace(dateString, e, replace, boost::match_default | boost::format_sed);
  return ptime(date(from_string(isoDate)));
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Now this is somewhat simplistic code. So be it, it serves the purposes of the exercise. I can think of ways to fix this, but there&amp;#8217;s an underling issue that exists if you use the regex library from Boost.&lt;p/&gt;&lt;/p&gt;


	&lt;p&gt;When you use the library, it allocates (in this example) 10 blocks of memory. If you read the documentation (I did), it&amp;#8217;s making space for its internal state machine for regex evaluation. This is done once and then kept around.&lt;p/&gt;&lt;/p&gt;


So what&amp;#8217;s the problem? Well, when I run my tests, the first test that happens to exercise this block of code reports some memory allocation issues:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;c:\projects\cppppp\dependencyinversionprinciple\dependencyinversionprinciple\pat
rongatewaytest.cpp:34: error: Failure in TEST(PatronGateway, AddAFew)
        Memory leak(s) found.
Leak size: 1120 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &amp;quot;
?&amp;quot;
Leak size: 16 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: ?a&amp;quot;
Leak size: 20 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &amp;quot;&#234;&#224;4&amp;quot;
Leak size: 52 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &#228;4&amp;quot;
Leak size: 4096 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &amp;quot;&amp;quot;
Leak size: 52 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &amp;quot;&#234;&#226;4&amp;quot;
Leak size: 20 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: ~4&amp;quot;
Leak size: 32 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &amp;quot;?&#224;4&amp;quot;
Leak size: 32 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &amp;quot;h~4&amp;quot;
Leak size: 80 Allocated at: &amp;lt;unknown&amp;gt; and line: 0. Type: &amp;quot;new&amp;quot; Content: &amp;quot;&#234;&#228;4&amp;quot;
Total number of leaks:  10&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This is a false positive. This is a one-time allocation and a side-effect of C++ memory allocation and static initialization.&lt;p/&gt;&lt;/p&gt;


	&lt;p&gt;There is a way to &amp;#8220;fix&amp;#8221; this. You use a command line option, -r, to tell the command line test runner to run the tests twice. If the allocation problem happens the first time but not the second time, then the tests are &amp;#8220;OK&amp;#8221;.&lt;p/&gt;&lt;/p&gt;


I didn&amp;#8217;t want to do this. 
	&lt;ul&gt;
	&lt;li&gt;The tests do take some time to run (30 seconds maybe, but still that doubles the time)&lt;/li&gt;
		&lt;li&gt;The output is ugly&lt;/li&gt;
		&lt;li&gt;It&amp;#8217;s off topic for what the exercise is trying to accomplish&lt;/li&gt;
	&lt;/ul&gt;


I tried a few different options but ultimately I went with simply calling that method before using the command line test runner. So I changed my main from:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_cpp "&gt;#include &amp;lt;CppUTest/CommandLineTestRunner.h&amp;gt;

int main(int argc, char **argv) {
  return CommandLineTestRunner::RunAllTests(argc, argv);
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

To this:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_cpp "&gt;#include &amp;quot;DateUtil.h&amp;quot;
#include &amp;lt;CppUTest/CommandLineTestRunner.h&amp;gt;

/** ************************************************************
    The boost regex library allocates several blocks of memory
    for its internal state machine. That memory is listed as a 
    memory leak in the first test that happens to use code that
    uses the boost regext library. To avoid having to run the
    tests twice using the -r option, we instead simply force
    this one-time allocation before starting test execution.
    *********************************************************** **/

void forceBoostRegexOneTimeAllocation() {
  DateUtil::dateFromString(&amp;quot;1/1/1980&amp;quot;);
}

int main(int argc, char **argv) {
  forceBoostRegexOneTimeAllocation();
  return CommandLineTestRunner::RunAllTests(argc, argv);
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Since this one-time allocation happens before any of the tests run, it is no longer reported as a problem by CppUTest.&lt;/p&gt;


	&lt;p&gt;Before I introduced this &amp;#8220;fix&amp;#8221;, I spent quite a bit of time to verify that each of the 10 allocations were done by one of the three lines dealing with regex code in my DateUtil class. I used a conditional breakpoint and looked at the stack trace. (I know, using the debugger is considered a code smell, but not all smells are bad.)&lt;/p&gt;


&lt;h3&gt;Conclusion&lt;/h3&gt;
I still like CppUTest. I&amp;#8217;ve used a few C++ unit testing tools but there are several I have not tried. I don&amp;#8217;t have enough face-time with C++ for this to be an issue. I am not terribly comfortable with the order of includes sensitivity. I&amp;#8217;m not sure if that would scale.&lt;p/&gt;

	&lt;p&gt;I do appreciate the assistance with memory checking, though dealing with false positives can be a bit of a hassle. There was another technique, that of expressing the number of allocations. But in this case, that simply deferred the reporting of memory leaks to after test execution. In any case, I do like this. I&amp;#8217;m not sure how well it would scale so it leaves me a bit uneasy.&lt;p/&gt;&lt;/p&gt;


	&lt;p&gt;If you happen to be using these tools, hope this helps. If not, and you are using C++, what can you say about your experiences with using this or other unit testing tools?&lt;/p&gt;</description>
      <pubDate>Thu, 04 Feb 2010 13:42:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:3b1ab465-7276-4c72-9361-9103092a7ca5</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/02/04/cpputest-recent-experiences</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>c</category>
      <category>boost</category>
      <category>memory</category>
      <category>allocation</category>
    </item>
    <item>
      <title>Software on the Cheap</title>
      <description>&lt;p&gt;When it comes to software, you get what you pay for.&lt;/p&gt;


	&lt;p&gt;Have you ever stopped to wonder how much a line of code costs?  
It ought to be easy to figure out.&lt;/p&gt;


	&lt;p&gt;In the last 14 months, I have written about 20KSLOC in FitNesse.  Of course that was part time.  My real job is running Object Mentor, consulting, teaching, mentoring, writing, and a whole load of other things.  Programming takes up perhaps 15% of my time.&lt;/p&gt;


	&lt;p&gt;On the other hand most programmers have lots of other things to do.  They go to meetings, and then they go to more meetings.  When they are done with those meetings, they go to meetings.  And then there are the meetings to go to.  Oh yeah, and then there&amp;#8217;s all the fiddling around with time accounting tools, and horrific source code control systems that perform like a salamander crawling through frozen mud.&lt;/p&gt;


	&lt;p&gt;So, maybe 15% isn&amp;#8217;t such a bad ratio.&lt;/p&gt;


	&lt;p&gt;The loaded rate (Salary plus everything else) for a typical programmer is on the order of $200K. (I know that sounds like a lot, but you can look it up.) So $200K / (20KSLOC / 14mo * 12mo) = $11.66/SLOC.&lt;/p&gt;


	&lt;p&gt;Let&amp;#8217;s look at one of those lines: &lt;code&gt;StringBuffer nameBuffer = new StringBuffer();&lt;/code&gt;
Does that look like $11.66 to you?  Would you pay that much for it?  Well, don&amp;#8217;t answer yet, because for each &lt;code&gt;StringBuffer&lt;/code&gt; line you buy, you get &lt;code&gt;import java.lang.StringBuffer;&lt;/code&gt; absolutely free!&lt;/p&gt;


	&lt;p&gt;Some factories pay their employees a &amp;#8220;piece rate&amp;#8221;.  Would you accept $11.66 per line of code instead of a salary? Of course it couldn&amp;#8217;t just be any old line of code.  It&amp;#8217;d have to be tested!&lt;/p&gt;


	&lt;p&gt;Hey, I bet all programmers would do &lt;span class="caps"&gt;TDD&lt;/span&gt; if we paid them a piece rate!&lt;/p&gt;


	&lt;h2&gt;Down to business.&lt;/h2&gt;


	&lt;p&gt;The point of that silly analysis was to demonstrate that software is &lt;em&gt;expensive&lt;/em&gt;.  Even the dumbest little app will likely require more than 1,000 lines of code; and that means it could cost $12K to write!&lt;/p&gt;


	&lt;p&gt;Imagine that you aren&amp;#8217;t a programmer, but you have a clever idea for a new website that&amp;#8217;ll make you a zillion dollars.  You&amp;#8217;ve storyboarded it all out.  You&amp;#8217;ve worked out all the details.  Now all you need is some high-school kid to zip out the code for you. Right?  Hell, you could pay him minimum wage!  The little twerp would be happy to get it!&lt;/p&gt;


	&lt;p&gt;That tragic comedy is altogether too common.  Too many people have borrowed money against their father&amp;#8217;s retirement account to fund a terrible implementation of a good idea.  Appalled at how much the reputable firms charge per hour ($100 or more) they go looking for a cheap solution.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;After all, this software is &lt;em&gt;simple&lt;/em&gt;.&amp;#8221; Or so the reasoning goes.  &amp;#8220;It&amp;#8217;s not like we&amp;#8217;re trying to send a rocket to the moon or anything.  And, besides, those expensive guys were just out to cheat us.  Software just isn&amp;#8217;t that hard to write.&amp;#8221;  Uh huh.&lt;/p&gt;


	&lt;p&gt;So the poor schmuck finds some freshman in college, or maybe a bored housewife who read a book on &lt;span class="caps"&gt;HTML&lt;/span&gt; last year and created a cute website to show off her kittens. Have these programmers heard about &lt;span class="caps"&gt;TDD&lt;/span&gt;?  Have they heard about Design Patterns?  Principles?  How about source code control?&lt;/p&gt;


	&lt;p&gt;Clearly they haven&amp;#8217;t.  They&amp;#8217;re going to sling a bunch of horrific code together, without any tests, versioning, or control.  The project will start well, with exciting initial results.  But then it will slowly grind to a halt, while the cash continues out the door unabated.&lt;/p&gt;


	&lt;p&gt;In the end the website isn&amp;#8217;t going to get built (and the poor schmuck&amp;#8217;s father won&amp;#8217;t be retiring as soon as he thought). It will be a disaster that will either be terminated, or will require double or triple the investment to get right.&lt;/p&gt;


	&lt;h2&gt;The Bottom Line.&lt;/h2&gt;


	&lt;p&gt;The bottom line is that, when it comes to software, you get what you pay for.  If you want good software done well, then you are going to pay for it, and it will probably cost you $12/line or more.  And, believe me, that&amp;#8217;s the &lt;em&gt;cheapest&lt;/em&gt; way to get your software done.&lt;/p&gt;


	&lt;p&gt;If you go out hunting for the cheap solution, then you&amp;#8217;re going to end up paying more, and losing time.  Software is one of those things that costs a fortune to write well, and double that to write poorly.  If you go for cheap, you&amp;#8217;re going to pay double; and maybe even triple.&lt;/p&gt;</description>
      <pubDate>Mon, 01 Feb 2010 16:17:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:85351364-b4f5-4faa-af8a-4fb1f604ecae</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2010/02/01/software-on-the-cheap</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>Makefiles, what are you doing with them?</title>
      <description>&lt;p&gt;Half a year ago, I took some exercises written in Java and ported them to C++. At that time I punted on writing makefiles and decided to reply on an &lt;span class="caps"&gt;IDE&lt;/span&gt; (Visual Studio). That worked fine but recently we almost had a customer that was going to take this class and, bless their heart, use the command line.&lt;/p&gt;


	&lt;p&gt;Turns out they are going to use visual studio, so I can shelve this, but I figured I&amp;#8217;d get feedback on what I have created for a makefile. Since I have not written a makefile for 12ish years, I figured things have changed. They have, but I suspect they have even more.&lt;/p&gt;


	&lt;p&gt;What follows are my environment assumptions and the makefile. I&amp;#8217;d appreciate any suggestions.&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;FWIW&lt;/span&gt;, I wrote this makefile because it turns out fully building all files takes longer than just building what has changed. I know this seems obvious, but it is not always the case with small projects like this. There is some point where the project becomes big enough to warrant dependency-based building. The exercise meets that criteria. Sometimes the time taken to evaluate build changes is enough overhead that it can be safely removed in lieu of a full build. This is a consideration when creating custom build files for legacy-based refactoring efforts.&lt;/p&gt;


&lt;b&gt;Environment&lt;/b&gt;
	&lt;ul&gt;
	&lt;li&gt;Generic Unix&lt;/li&gt;
		&lt;li&gt;zsh &amp;#8211; though any shell will do really &lt;/li&gt;
		&lt;li&gt;g++&lt;/li&gt;
		&lt;li&gt;gnu make&lt;/li&gt;
		&lt;li&gt;This source base will still be used in Visual Studio but not this makefile&lt;/li&gt;
		&lt;li&gt;CppUTest used for unit testing tool&lt;/li&gt;
		&lt;li&gt;Provide default location for CppUTest, which can be overridden by environment variable&lt;/li&gt;
		&lt;li&gt;Boost library installed in /usr/local/include and /usr/local/lib (reasonable assumption or should I go ahead and allow this to be configured easily in the makefile &amp;#8211; what&amp;#8217;s your opinion?)&lt;/li&gt;
		&lt;li&gt;Project is small enough that all headers and source files are in the same directory (should I build the .o&amp;#8217;s and put them in another directory to hide them?)&lt;/li&gt;
	&lt;/ul&gt;


&lt;b&gt;Current Makefile&lt;/b&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;ifdef CPP_U_TEST
    CppUTest_base = $(CPP_U_TEST)
else
    CppUTest_base = $(wildcard ~/src/cpputest)
endif

LIB_DIRS = -L$(CppUTest_base)/lib
INC_DIRS = -I$(CppUTest_base)/include
LIBS = -lCppUTest -lboost_date_time -lboost_regex -lboost_thread
CFLAGS = -g $(INC_DIRS) 
LDFLAGS = $(LIB_DIRS) $(LIBS)
CC = g++
SRCS := $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)
OUT = run_all_tests
DEP_DIR = dependencies

all: $(OBJS)
    $(CC) $(CFLAGS) $(LDFLAGS) -o $(OUT) $(OBJS)

clean:
    @rm -rf $(DEP_DIR) $(OBJS) $(OUT)

-include $(SRCS:.cpp=$(dep_dir)/.d)

.cpp.o:
    @if [ ! -d $(DEP_DIR) ] ; then mkdir $(DEP_DIR) ; fi
    $(CC) -c $(CFLAGS) -o $@ $&amp;lt; 
    @$(CC) -MM $(CFLAGS) $*.cpp &amp;gt; $(DEP_DIR)/$*.d&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Wed, 27 Jan 2010 09:02:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:2e89212d-2630-4f8c-ac26-b1c8091cd19c</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/01/27/makefiles-what-are-you-doing-with-them</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>c</category>
      <category>makefile</category>
      <category>gnu</category>
      <category>build</category>
    </item>
    <item>
      <title>Mocking Mocking and Testing Outcomes.</title>
      <description>&lt;p&gt;The number of mocking frameworks has proliferated in recent years.  This pleases me because it is a symptom that testing in general, and &lt;span class="caps"&gt;TDD&lt;/span&gt; in particular, have become prevalent enough to support a rich panoply of third-party products.&lt;/p&gt;


	&lt;p&gt;On the other hand, all frameworks carry a disease with them that I call &lt;em&gt;The Mount Everest Syndrome&lt;/em&gt;: &amp;#8220;I use it because it&amp;#8217;s there.&amp;#8221;  The more mocking frameworks that appear, the more I see them enthusiastically used.  Yet the prolific use of mocking frameworks is a rather serious design smell&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Lately I have seen several books and articles that present &lt;span class="caps"&gt;TDD&lt;/span&gt; through the lens of a mocking framework.  If you were a newbie to &lt;span class="caps"&gt;TDD&lt;/span&gt;, these writings might give you the idea that &lt;span class="caps"&gt;TDD&lt;/span&gt; was defined by the use of mocking tools, rather than by the &lt;a href="http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd"&gt;disciplines&lt;/a&gt; of &lt;span class="caps"&gt;TDD&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;So when should use use a mocking framework?  The answer is the same for any other framework.  You use a framework only when that framework will give you a significant advantage.&lt;/p&gt;


	&lt;p&gt;Why so austere?  Why shouldn&amp;#8217;t you use frameworks &amp;#8220;just because they are there&amp;#8221;?  Because frameworks &lt;em&gt;always&lt;/em&gt; come with a cost.  They must be learned by the author, and by all the readers.  They become part of the configuration and have to be maintained.  They must be tracked from version to version.  But perhaps the most significant reason is that once you have a hammer, everything starts to look like a nail.  The framework will put you into a constraining mindset that prevents you from seeing other, better solutions.&lt;/p&gt;


Consider, for example, this lovely bit of code that I&amp;#8217;ve been reviewing recently.  It uses the Moq framework to initialize a test double:
&lt;pre&gt;&lt;code&gt;
var vehicleMock = Mocks.Create&amp;lt;IClientVehicle&amp;gt;()
 .WithPersistentKey()
 .WithLogicalKey().WithLogicalName()
 .WithRentalSessionManager(rsm =&amp;gt;
    {
      var rs = Mocks.Create&amp;lt;IRentalSession&amp;gt;();
      rsm.Setup(o =&amp;gt; o.GetCurrentSession()).Returns(rs.Object);
      rsm.Setup(o =&amp;gt;
       o.GetLogicalKeyOfSessionMember(It.IsAny&amp;lt;string&amp;gt;(),
        It.IsAny&amp;lt;int&amp;gt;())).Returns("Rental");
    })
 .AddVehicleMember&amp;lt;IRoadFactory&amp;gt;()
 .AddVehicleMember&amp;lt;IRoadItemFactory&amp;gt;(rf =&amp;gt; rf.Setup(t =&amp;gt; 
    t.CreateItems(It.IsAny&amp;lt;IRoad&amp;gt;())).Returns(pac))
 .AddVehicleMember&amp;lt;ILegacyCorporateRental&amp;gt;()
 .AddVehicleMember&amp;lt;IRentalStation&amp;gt;(
    m =&amp;gt; m.Setup(k =&amp;gt; k.Facility.FacilityID).Returns(0))
 .AddVehicleMember&amp;lt;IRoadManager&amp;gt;(m=&amp;gt;
    m.Setup(k=&amp;gt;k.GetRoundedBalanceDue(25,It.IsAny&amp;lt;IRoad&amp;gt;())).Returns(25));
&lt;/code&gt;&lt;/pre&gt;
Some of you might think I&amp;#8217;m setting up a straw-man.  I&amp;#8217;m not.  I realize that bad code can be written in any language or framework, and that you can&amp;#8217;t blame the language or framework for bad code.  
&lt;p/&gt;&lt;p/&gt;
The point I am making is that code like this was &lt;em&gt;the way&lt;/em&gt; that all unit tests in this application were written.  The team was new to &lt;span class="caps"&gt;TDD&lt;/span&gt;, and they got hold of a tool, and perhaps read a book or article, and decided that &lt;span class="caps"&gt;TDD&lt;/span&gt; was done by using a mocking tool.  This team is not the first team I&amp;#8217;ve seen who have fallen into this trap.  In fact, I think that the &lt;span class="caps"&gt;TDD&lt;/span&gt; industry as a whole has fallen into this trap to one degree or another.

	&lt;p&gt;Now don&amp;#8217;t get me wrong.  I like mocking tools.  I use them in Ruby, Java, and .Net. I think they provide a convenient way to make test-doubles in situations where more direct means are difficult.&lt;/p&gt;


For example, I recently wrote the following unit test in FitNesse using the Mockito framework.  
&lt;pre&gt;&lt;code&gt;
  @Before
  public void setUp() {
    manager = mock(GSSManager.class);
    properties = new Properties();
  }

  @Test
  public void credentialsShouldBeNullIfNoServiceName() throws Exception {
    NegotiateAuthenticator authenticator = 
      new NegotiateAuthenticator(manager, properties);
    assertNull(authenticator.getServerCredentials());
    verify(manager, never()).createName(
      anyString(), (Oid) anyObject(), (Oid) anyObject());
  }
&lt;/code&gt;&lt;/pre&gt;
The first line in the &lt;code&gt;setUp&lt;/code&gt; function is lovely.  It&amp;#8217;s kind of hard to get prettier than that.  Anybody reading it understands that &lt;code&gt;manager&lt;/code&gt; will be a mock of the &lt;code&gt;GSSManager&lt;/code&gt; class.  
&lt;p/&gt;&lt;p/&gt;
It&amp;#8217;s not too hard to understand the test itself.  Apparently we are happy to have the &lt;code&gt;manager&lt;/code&gt; be a dummy object with the constraint that &lt;code&gt;createName&lt;/code&gt; is never called by &lt;code&gt;NegotiateAuthenticator&lt;/code&gt;.  The &lt;code&gt;anyString()&lt;/code&gt; and &lt;code&gt;anyObject()&lt;/code&gt; calls are pretty self explanatory.

	&lt;p&gt;On the other hand, I wish I could have said this:&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;assertTrue(manager.createNameWasNotCalled());&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;That statement does not require my poor readers to understand anything about Mockito.  Of course it does require me to hand-roll a manager mock.  Would that be hard?  Let&amp;#8217;s try.&lt;/p&gt;


First I need to create a dummy.  
&lt;pre&gt;&lt;code&gt;
  private class MockGSSManager extends GSSManager {
    public Oid[] getMechs() {
      return new Oid[0];
    }

    public Oid[] getNamesForMech(Oid oid) throws GSSException {
      return new Oid[0];
    }

    public Oid[] getMechsForName(Oid oid) {
      return new Oid[0];
    }

    public GSSName createName(String s, Oid oid) throws GSSException {
      return null;
    }

    public GSSName createName(byte[] bytes, Oid oid) throws GSSException {
      return null;
    }

    public GSSName createName(String s, Oid oid, Oid oid1) throws GSSException {
      return null;
    }

    public GSSName createName(byte[] bytes, Oid oid, Oid oid1) throws GSSException {
      return null;
    }

    public GSSCredential createCredential(int i) throws GSSException {
      return null;
    }

    public GSSCredential createCredential(GSSName gssName, int i, Oid oid, int i1) throws GSSException {
      return null;
    }

    public GSSCredential createCredential(GSSName gssName, int i, Oid[] oids, int i1) throws GSSException {
      return null;
    }

    public GSSContext createContext(GSSName gssName, Oid oid, GSSCredential gssCredential, int i) throws GSSException {
      return null;
    }

    public GSSContext createContext(GSSCredential gssCredential) throws GSSException {
      return null;
    }

    public GSSContext createContext(byte[] bytes) throws GSSException {
      return null;
    }

    public void addProviderAtFront(Provider provider, Oid oid) throws GSSException {
    }

    public void addProviderAtEnd(Provider provider, Oid oid) throws GSSException {
    }
  }
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&amp;#8220;Oh, ick!&amp;#8221; you say.  Yes, I agree it&amp;#8217;s a lot of code.  On the other hand, it took me just a single keystroke on my &lt;span class="caps"&gt;IDE&lt;/span&gt; to generate all those dummy methods.  (In IntelliJ it was simply command-I to implement all unimplemented methods.)  So it wasn&amp;#8217;t particularly hard.  And, of course, I can put this code somewhere where nobody had to look at it unless they want to.  It has the advantage that anybody who knows Java can understand it, and can look right at the methods to see what they are returning.  No &amp;#8220;special&amp;#8221; knowledge of the mocking framework is necessary.&lt;/p&gt;


Next, let&amp;#8217;s&amp;#8217; make a test double that does precisely what this test needs.
&lt;pre&gt;&lt;code&gt;
  private class GSSManagerSpy extends MockGSSManager {
    public boolean createNameWasCalled;

    public GSSName createName(String s, Oid oid) throws GSSException {
      createNameWasCalled = true;
      return null;
    }
  }
&lt;/code&gt;&lt;/pre&gt;
Well, that just wasn&amp;#8217;t that hard.  It&amp;#8217;s really easy to understand too. 

Now, let&amp;#8217;s rewrite the test.
&lt;pre&gt;&lt;code&gt;
  @Test
  public void credentialsShouldBeNullIfNoServiceNameWithHandRolledMocks() throws Exception {
    NegotiateAuthenticator authenticator = new NegotiateAuthenticator(managerSpy, properties);
    assertNull(authenticator.getServerCredentials());
    assertFalse(managerSpy.createNameWasCalled);
  }
&lt;/code&gt;&lt;/pre&gt;
Well, that test is just a &lt;em&gt;load&lt;/em&gt; easier to read than &lt;code&gt;verify(manager, never()).createName(anyString(), (Oid) anyObject(), (Oid) anyObject());&lt;/code&gt;.
&lt;p/&gt;&lt;p/&gt;
&amp;#8220;But Uncle Bob!&amp;#8221; I hear you say.  &amp;#8220;That scenario is too simple.  What if there were lots of dependencies and things&amp;#8230;&amp;#8221; 

I&amp;#8217;m glad you asked that question, because the very next test is just such a situation.  
&lt;pre&gt;&lt;code&gt;
  @Test
  public void credentialsShouldBeNonNullIfServiceNamePresent() throws Exception {
    properties.setProperty("NegotiateAuthenticator.serviceName", "service");
    properties.setProperty("NegotiateAuthenticator.serviceNameType", "1.1");
    properties.setProperty("NegotiateAuthenticator.mechanism", "1.2");
    GSSName gssName = mock(GSSName.class);
    GSSCredential gssCredential = mock(GSSCredential.class);
    when(manager.createName(anyString(), (Oid) anyObject(), (Oid) anyObject())).thenReturn(gssName);
    when(manager.createCredential((GSSName) anyObject(), anyInt(), (Oid) anyObject(), anyInt())).thenReturn(gssCredential);
    NegotiateAuthenticator authenticator = new NegotiateAuthenticator(manager, properties);
    Oid serviceNameType = authenticator.getServiceNameType();
    Oid mechanism = authenticator.getMechanism();
    verify(manager).createName("service", serviceNameType, mechanism);
    assertEquals("1.1", serviceNameType.toString());
    assertEquals("1.2", mechanism.toString());
    verify(manager).createCredential(gssName, GSSCredential.INDEFINITE_LIFETIME, mechanism, GSSCredential.ACCEPT_ONLY);
    assertEquals(gssCredential, authenticator.getServerCredentials());
  }
&lt;/code&gt;&lt;/pre&gt;
Now I&amp;#8217;ve got three test doubles that interact with each other; and I am verifying that the code under test is manipulating them all correctly.  I &lt;em&gt;could&lt;/em&gt; create hand-rolled test doubles for this; but the wiring between them would be scattered in the various test-double derivatives.  I&amp;#8217;d also have to write a significant number of accessors to get the values of the arguments to &lt;code&gt;createName&lt;/code&gt; and &lt;code&gt;createCredential&lt;/code&gt;.  In short, the hand-rolled test-double code would be harder to understand than the Mockito code.  The Mockito code puts the whole story in one simple test method rather than scattering it hither and yon in a plethora of little derivatives.
&lt;p/&gt;&lt;p/&gt;
What&amp;#8217;s more, since it&amp;#8217;s clear that I should use a mocking framework for this test, I think I should be consistent and use if for &lt;em&gt;all&lt;/em&gt; the tests in this file.   So the hand-rolled &lt;code&gt;MockGSSManager&lt;/code&gt; and &lt;code&gt;ManagerSpy&lt;/code&gt; are history.

	&lt;p&gt;&amp;#8220;But Uncle Bob, aren&amp;#8217;t we always going to have dependencies like that?  So aren&amp;#8217;t we &lt;em&gt;always&lt;/em&gt; going to have to use a mocking framework?&amp;#8221;&lt;/p&gt;


	&lt;p&gt;That, my dear reader, is the real point of this blog.  The answer to that salient questions is a profound: &amp;#8220;&lt;strong&gt;No!&lt;/strong&gt;&amp;#8220;&lt;/p&gt;


	&lt;p&gt;Why did I have to use Mockito for these tests?  Because the number of objects in play was large.  The module under test (&lt;code&gt;NegotiateAuthenticator&lt;/code&gt;) used &lt;code&gt;GSSName&lt;/code&gt;, &lt;code&gt;GSSCredential&lt;/code&gt;, and &lt;code&gt;GSSManager&lt;/code&gt;.  In other words the coupling between the module under test and the test itself was high.  (I see lightbulbs above some of your heads.) That&amp;#8217;s right, boys and girls, we don&amp;#8217;t want coupling to be high!&lt;/p&gt;


	&lt;p&gt;It is the high coupling between modules and tests that creates the need for a mocking framework.  This high coupling is also the cause of the dreaded &amp;#8220;Fragile Test&amp;#8221; problem.  How many tests break when you change a module?  If the number is high, then the coupling between your modules and tests in high.  Therefore, I conclude that those systems that make prolific use of mocking frameworks are likely to suffer from fragile tests.&lt;/p&gt;


	&lt;p&gt;Of the 277 unit test files in FitNesse, only 11 use Mockito.  The reason for small number is two-fold.  First, we test outcomes more often than we test mechanisms.  That means we test how a small group of classes behaves, rather than testing the dance of method calls between those classes.  The second reason is that our test doubles have no middle class.  They are either very simple stubs and spies or they are moderately complex fakes.&lt;/p&gt;


	&lt;p&gt;Testing outcomes is a traditional decoupling technique.  The test doesn&amp;#8217;t care &lt;em&gt;how&lt;/em&gt; the end result is calculated, so long as the end result is correct.  There may be a dance of several method calls between a few different objects; but the test is oblivious since it only checks the answer.  Therefore the tests are not strongly coupled to the solution and are not fragile.&lt;/p&gt;


	&lt;p&gt;Keeping middle-class test doubles (i.e. Mocks) to a minimum is another way of decoupling.  Mocks, by their very nature, are coupled to mechanisms instead of outcomes.  Mocks, or the setup code that builds them, have deep knowledge of the inner workings of several different classes.  That knowledge is the very definition of high-coupling.&lt;/p&gt;


	&lt;p&gt;What is a &amp;#8220;moderately complex fake&amp;#8221; and why does it help to reduce coupling?  One example within FitNesse is &lt;code&gt;MockSocket&lt;/code&gt;.  (The name of this class is historical.  Nowadays it should be called &lt;code&gt;FakeSocket&lt;/code&gt;.)  This class derives from &lt;code&gt;Socket&lt;/code&gt; and implements all its methods either to remember what was sent to the socket, or to allow a user to read some canned data.  This is a &amp;#8220;fake&amp;#8221; because it simulates the behavior of a socket.  It is not a mock because it has no coupling to any mechanisms.  You don&amp;#8217;t ask it whether it succeeded or failed, you ask it to send or recieve a string.  This allows our unit tests to test outcomes rather than mechanisms.&lt;/p&gt;


	&lt;p&gt;The moral of this story is that the point at which you start to really need a mocking framework is the very point at which the coupling between your tests and code is getting too high.  There are times when you can&amp;#8217;t avoid this coupling, and those are the times when mocking frameworks &lt;em&gt;really&lt;/em&gt; pay off.  However, you should strive to keep the coupling between your code and tests low enough that you don&amp;#8217;t need to use the mocking framework very often.&lt;/p&gt;


	&lt;p&gt;You do this by testing outcomes instead of mechanisms.&lt;/p&gt;</description>
      <pubDate>Sat, 23 Jan 2010 11:32:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:b863ec60-399c-430f-8e82-78e54684cae4</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2010/01/23/mocking-mocking-and-testing-outcomes</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Design Principles</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>Dependency Injection Inversion</title>
      <description>&lt;p&gt;Dependency Injection is all the rage.  There are several frameworks that will help you inject dependencies into your system.  Some use &lt;span class="caps"&gt;XML&lt;/span&gt; (God help us) to specify those dependencies.  Others use simple statements in code.  In either case, the goal of these frameworks is to help you create instances without having to resort to &lt;code&gt;new&lt;/code&gt; or Factories.&lt;/p&gt;


	&lt;p&gt;I think these frameworks are great tools.  But I also think you should carefully restrict how and where you use them.&lt;/p&gt;


	&lt;p&gt;Consider, for example, this simple example using Google&amp;#8217;s Guice framework.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
 public class BillingApplication {
   public static void main(String[] args) {
    Injector injector = Guice.createInjector(new BillingModule());
    BillingService billingService = injector.getInstance(BillingService.class);
    billingService.processCharge(2034, "Bob");
  }
 }
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;My goal is to create an instance of &lt;code&gt;BillingService&lt;/code&gt;.  To do this, I first get an &lt;code&gt;Injector&lt;/code&gt; from Guice.  Then I use the &lt;code&gt;injector&lt;/code&gt; to get an instance of my &lt;code&gt;BillingService&lt;/code&gt; class.  What&amp;#8217;s so great about this?  Well, take a look at the constructor of the &lt;code&gt;BillingService&lt;/code&gt; class.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
class BillingService {
  private CreditCardProcessor processor;
  private TransactionLog transactionLog;

  @Inject
  BillingService(CreditCardProcessor processor, TransactionLog transactionLog) {
    this.processor = processor;
    this.transactionLog = transactionLog;
  }

  public void processCharge(int amount, String id) {
    boolean approval = processor.approve(amount, id);
    transactionLog.log(
      String.format("Transaction by %s for %d %s",
      id, amount, approvalCode(approval)));
  }

  private String approvalCode(boolean approval) {
    return approval?"approved":"denied";
  }
}

&lt;/code&gt;&lt;/pre&gt;
Oh ho!  The &lt;code&gt;BillingService&lt;/code&gt; constructor requires two arguments!  A &lt;code&gt;CreditCardProcessor&lt;/code&gt; and a &lt;code&gt;TransactionLog&lt;/code&gt;.  How was the &lt;code&gt;main&lt;/code&gt; program able to create an instance of &lt;code&gt;BillingService&lt;/code&gt; without those two arguments?  That&amp;#8217;s the magic of Guice (and of all Dependency Injection frameworks).  Guice knows that the &lt;code&gt;BillingService&lt;/code&gt; needs those two arguments, and it knows how to create them.  Did you see that funky &lt;code&gt;@Inject&lt;/code&gt; attribute above the constructor?  That&amp;#8217;s how it got connected into Guice.

	&lt;p&gt;And here&amp;#8217;s the magic module that tells Guice how to create the arguments for the &lt;code&gt;BillingService&lt;/code&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
public class BillingModule extends AbstractModule {
  protected void configure() {
    bind(TransactionLog.class).to(DatabaseTransactionLog.class);
    bind(CreditCardProcessor.class).to(MyCreditCardProcessor.class);
  }
}

&lt;/code&gt;&lt;/pre&gt;
Clever these Google-folk!  The two &lt;code&gt;bind&lt;/code&gt; functions tell Guice that whenever we need an instance of a &lt;code&gt;TransactionLog&lt;/code&gt; it should use an instance of &lt;code&gt;DatabaseTransactionLog&lt;/code&gt;.  Whenever it needs a &lt;code&gt;CreditCardProcessor&lt;/code&gt; it should use an instance of &lt;code&gt;MyCreditCardProcessor&lt;/code&gt;.

	&lt;p&gt;Isn&amp;#8217;t that cool!  Now you don&amp;#8217;t have to build factories.  You don&amp;#8217;t have to use &lt;code&gt;new&lt;/code&gt;.  You just tell Guice how to map interfaces to implementations, and which constructors to inject those implementations in to, and then call &lt;code&gt;Injector.getInstance(SomeClass.class);&lt;/code&gt; and voila!  You have your instance automatically constructed for you.  Cool.&lt;/p&gt;


	&lt;p&gt;Well, yes it&amp;#8217;s cool.  On the other hand, consider this code:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
public class BillingApplicationNoGuice {
  public static void main(String[] args) {
    CreditCardProcessor cp = new MyCreditCardProcessor();
    TransactionLog tl = new DatabaseTransactionLog();
    BillingService bs = new BillingService(cp, tl);
    bs.processCharge(9000, "Bob");
  }
}

&lt;/code&gt;&lt;/pre&gt; 
Why is this worse?  It seems to me it&amp;#8217;s better.

	&lt;p&gt;&lt;em&gt;But Uncle Bob&lt;/em&gt;, you&amp;#8217;ve violated &lt;span class="caps"&gt;DIP&lt;/span&gt; by creating concrete instances!&lt;/p&gt;


	&lt;p&gt;True, but you have to mention concrete instances somewhere.  &lt;code&gt;main&lt;/code&gt; seems like a perfectly good place for that.  Indeed, it seems better than hiding the concrete references in &lt;code&gt;BillingModule&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;I don&amp;#8217;t want a bunch of secret modules with &lt;code&gt;bind&lt;/code&gt; calls scattered all around my code.  I don&amp;#8217;t want to have to hunt for the particular &lt;code&gt;bind&lt;/code&gt; call for the &lt;code&gt;Zapple&lt;/code&gt; interface when I&amp;#8217;m looking at some module.  I want to know where all the instances are created.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;But Uncle Bob&lt;/em&gt;, You&amp;#8217;d know where they are because this is a &lt;em&gt;Guice&lt;/em&gt; application.&lt;/p&gt;


	&lt;p&gt;I don&amp;#8217;t want to write a &lt;em&gt;Guice&lt;/em&gt; application.  Guice is a framework, and I don&amp;#8217;t want framework code smeared all through my application.  I want to keep frameworks nicely decoupled and at arms-length from the main body of my code.  I don&amp;#8217;t want to have &lt;code&gt;@Inject&lt;/code&gt; attributes everywhere and &lt;code&gt;bind&lt;/code&gt; calls hidden under rocks.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;But Uncle Bob&lt;/em&gt;, What if I want to get an instance of &lt;code&gt;BillingService&lt;/code&gt; from deep in the bowels of my application?  With Guice I can just say &lt;code&gt;injector.getInstance(BillingService.class);&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;True, but I don&amp;#8217;t want to have &lt;code&gt;createInstance&lt;/code&gt; calls scattered all through my code.  I don&amp;#8217;t want Guice to be poured all over my app. I want my app to be clean, not soaked in Guice.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;But Uncle Bob&lt;/em&gt;, That means I have to use &lt;code&gt;new&lt;/code&gt; or factories, or pass globals around.&lt;/p&gt;


	&lt;p&gt;You think the &lt;code&gt;injector&lt;/code&gt; is not a global?  You think &lt;code&gt;BillingService.class&lt;/code&gt; is not a global?  There will always be globals to deal with.  You can&amp;#8217;t write systems without them.  You just need to manage them nicely.&lt;/p&gt;


	&lt;p&gt;And, no, I don&amp;#8217;t have to use &lt;code&gt;new&lt;/code&gt; everywhere, and I don&amp;#8217;t need factories.  I can do something as simple as:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
public class BillingApplicationNoGuice {
  public static void main(String[] args) {
    CreditCardProcessor cp = new MyCreditCardProcessor();
    TransactionLog tl = new DatabaseTransactionLog();
    BillingService.instance = new BillingService(cp, tl);

    // Deep in the bowels of my system.
    BillingService.instance.processCharge(9000, "Bob");
  }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;em&gt;But Uncle Bob&lt;/em&gt;, what if you want to create many instances of &lt;code&gt;BillingService&lt;/code&gt; rather than just that one singleton?

	&lt;p&gt;Then I&amp;#8217;d use a factory, like so:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
public class BillingApplication {
   public static void main(String[] args) {
    Injector injector = Guice.createInjector(new BillingModule());
    BillingService.factory = new BillingServiceFactory(injector);

    // Deep in the bowels of my code.
    BillingService billingService = BillingService.factory.make();
    billingService.processCharge(2034, "Bob");
  }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;em&gt;But Uncle Bob&lt;/em&gt;, I thought the whole idea was to avoid factories!

	&lt;p&gt;Hardly.  After all, Guice is just a big factory.  But you didn&amp;#8217;t let me finish.  Did you notice that I passed the Guice injector into the factory?  Here&amp;#8217;s the factory implementation.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
public class BillingServiceFactory extends AbstractModule {
  private Injector injector;

  public BillingServiceFactory(Injector injector) {
    this.injector = injector;
  }

  protected void configure() {
    bind(TransactionLog.class).to(DatabaseTransactionLog.class);
    bind(CreditCardProcessor.class).to(MyCreditCardProcessor.class);
  }

  public BillingService make() {
    return injector.getInstance(BillingService.class);
  }
}

&lt;/code&gt;&lt;/pre&gt;
I like this because now all the Guice is in one well understood place.  I don&amp;#8217;t have Guice all over my application.  Rather, I&amp;#8217;ve got factories that contain the Guice.  Guicey factories that keep the Guice from being smeared all through my application.  

	&lt;p&gt;What&amp;#8217;s more, if I wanted to replace Guice with some other DI framework, I know exactly what classes would need to change, and how to change them.  So I&amp;#8217;ve kept Guice uncoupled from my application.&lt;/p&gt;


	&lt;p&gt;Indeed, using this form allows me to defer using Guice until I think it&amp;#8217;s necessary.  I can just build the factories the good old &lt;span class="caps"&gt;GOF&lt;/span&gt; way until the need to externalize dependencies emerges.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;But Uncle Bob&lt;/em&gt;, don&amp;#8217;t you think Dependency Injection is a good thing?&lt;/p&gt;


	&lt;p&gt;Of course I do.  Dependency Injection is just a special case of Dependency Inversion.  I think Dependency Inversion is so important that I want to invert the dependencies on Guice!  I don&amp;#8217;t want lots of concrete Guice dependencies scattered through my code.&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;BTW&lt;/span&gt;, did you notice that I was using Dependency Injection even when I wasn&amp;#8217;t using Guice at all?  This is nice and simple &lt;em&gt;manual&lt;/em&gt; dependency injection.  Here&amp;#8217;s that code again in case you don&amp;#8217;t want to look back:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;

public class BillingApplicationNoGuice {
  public static void main(String[] args) {
    CreditCardProcessor cp = new MyCreditCardProcessor();
    TransactionLog tl = new DatabaseTransactionLog();
    BillingService bs = new BillingService(cp, tl);
    bs.processCharge(9000, "Bob");
  }
}

&lt;/code&gt;&lt;/pre&gt;
Dependency Injection doesn&amp;#8217;t require a framework; it just requires that you invert your dependencies and then construct and pass your arguments to deeper layers.   Consider, for example, that the following test works just fine in &lt;em&gt;all&lt;/em&gt; the cases above.  It does not rely on Guice, it only relies on the fact that dependencies were inverted and can be injected into &lt;code&gt;BillingService&lt;/code&gt;

&lt;pre&gt;&lt;code&gt;

public class BillingServiceTest {
  private LogSpy log;

  @Before
  public void setup() {
    log = new LogSpy();
  }

  @Test
  public void approval() throws Exception {
    BillingService bs = new BillingService(new Approver(), log);
    bs.processCharge(9000, "Bob");
    assertEquals("Transaction by Bob for 9000 approved", log.getLogged());
  }

  @Test
  public void denial() throws Exception {
    BillingService bs = new BillingService(new Denier(), log);
    bs.processCharge(9000, "Bob");
    assertEquals("Transaction by Bob for 9000 denied", log.getLogged());    
  }
}

class Approver implements CreditCardProcessor {
  public boolean approve(int amount, String id) {
    return true;
  }
}

class Denier implements CreditCardProcessor {
  public boolean approve(int amount, String id) {
    return false;
  }
}

class LogSpy implements TransactionLog {
  private String logged;

  public void log(String s) {
    logged = s;
  }

  public String getLogged() {
    return logged;
  }
}

&lt;/code&gt;&lt;/pre&gt;
Also notice that I rolled my own Test Doubles (we used to call them mocks, but we&amp;#8217;re not allowed to anymore.)  It would have been tragic to use a mocking framework for such a simple set of tests.

	&lt;p&gt;Most of the time the best kind of Dependency Injection to use, is the manual kind.  Externalized dependency injection of the kind that Guice provides is appropriate for those classes that you &lt;em&gt;know&lt;/em&gt; will be extension points for your system.&lt;/p&gt;


	&lt;p&gt;But for classes that aren&amp;#8217;t obvious extension points, you will simply know the concrete type you need, and can create it at a relatively high level and inject it down as an interface to the lower levels.  If, one day, you find that you need to externalize that dependency, it&amp;#8217;ll be easy because you&amp;#8217;ve already inverted and injected it.&lt;/p&gt;</description>
      <pubDate>Sun, 17 Jan 2010 12:42:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:00f97566-88ff-41a0-a0b1-4baee8225dc0</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2010/01/17/dependency-injection-inversion</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Design Principles</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>UI Test Automation Tools are Snake Oil</title>
      <description>&lt;p&gt;It happens over and over again.  I visit a team and I ask about their testing situation.  We talk about unit tests, exploratory testing, the works.  Then, I ask about automated end-to-end testing and they point at a machine in the corner.  That poor machine has an installation of some highly-priced per seat testing tool (or an open source one, it doesn&amp;#8217;t matter), and the chair in front of it is empty.  We walk over,  sweep the dust away from the keyboard, and load up the tool.  Then, we glance through their set of test scripts and try to run them.  The system falls over a couple of times and then they give me that sheepish grin and say &amp;#8220;we tried.&amp;#8221;  I say, &amp;#8220;don&amp;#8217;t worry, everyone does.&amp;#8221;  

&lt;p&gt;It&amp;#8217;s a very familiar &amp;#8216;rabbit hole&amp;#8217; in the industry.  It&amp;#8217;s sort of like the old days when you&amp;#8217;d find a couple of classes generated by a &lt;span class="caps"&gt;CASE&lt;/span&gt; tool in every code base you visited if you  looked hard enough.  People started with the merry notion that they were going to round-trip code with some &lt;span class="caps"&gt;CASE&lt;/span&gt; tool and they learned (like most lucky teams do) that it just doesn&amp;#8217;t pay for itself, it&amp;#8217;s not worth the time or the frustration.  UI Test Automation tools are in the same category.  Personally, I think that in this day and age selling them is irresponsible.  Developing them open-source?  Well, let your conscience be your guide, but really, even though people can use them responsibly, they hardly ever do because these tools are sold with a dream, a very seductive and dangerous one.

&lt;h2&gt;The Dream&lt;/h2&gt;

&lt;p&gt;Janet comes into work in the morning and she sits down at her super-duper testing console.  She presses a button and the testing system springs to life.  The application comes up all at once across ten monitors.  Cursors move, selections are made (silently) and tests run against the user interface magically, as if some eager set of ghost elves took control, mischievously burrowing through the nooks and crannies of the application, running scripts to completion, and making little notes whenever there is a failure.  Janet sits back in her chair, waiting for the elves to report back to her.  She stirs her coffee gently.

&lt;h2&gt;The Reality&lt;/h2&gt;

&lt;p&gt;Janet hasn&amp;#8217;t gone home yet.  It&amp;#8217;s 2AM and she has to report completion of all her test cases at a meeting in the morning.  She thinks she&amp;#8217;s past the last configuration issue but she&amp;#8217;s not sure.  For the last hour, she&amp;#8217;s been trying to make sure that a particular button is pressed at step 14 of her script, but quirky latency on the server is preventing it from happening consistently.  Sadly, she has to run the script from the beginning each time.  Oh, and five hours ago she discovered UI changes which invalidated 30% of the regression tests.  Most of the changes were easy but she still has 12 cases to go and her 9AM meeting looms ahead of her.

&lt;p&gt;This gap between the dream and the reality is not a matter of flawed execution, it&amp;#8217;s endemic.  Here&amp;#8217;s the scoop.

&lt;h2&gt;UI Test Automation Tools are Brittle&lt;/h2&gt;

&lt;p&gt;You might not think this is fair but it is, really.  I haven&amp;#8217;t seen one of these tools yet which isn&amp;#8217;t susceptible to missed events or timing madness.  It just happens.  The fact of the matter is, it is hard to sit on the outside of an application an instrument it.  It&amp;#8217;s a very technology sensitive problem.  You need to hook into either the OS or the browser or both.  Neither are ever really built from the ground up for that sort of access.

&lt;h2&gt;UI Based Testing Is Not the Solution That Vendors Imply It Is&lt;/h2&gt;

&lt;p&gt;This is the big issue, the one which really hurts the industry.  The fact of the matter is that UI based testing should be used for UIs: that&amp;#8217;s it.  You should not be testing your full application end-to-end through a UI Testing tool.  First of all, that sort of testing couples some of the most important tests in your system to one of the most volatile parts of it.  It&amp;#8217;s easy for us to see business logic as volatile, but really, the UI is the thing which twists and ripples in the winds of change. When customers want new features, often those features involve new workflows.  When usability experts discover better ways of models of interaction, an agile business seizes upon them and makes the changes&amp;#8212;if they can.  You&amp;#8217;d be surprised at the number of applications which continue to sport out of day user interfaces simply because the development organization is terrified of throwing away all of their regression tests which (by the way) go through the UI.  Even if you&amp;#8217;re not a consultant like me, visiting teams and seeing their development processes, you can see hints from the outside.  Think of every website or shrink-wrap application which has &amp;#8220;the same old workflow&amp;#8221; and a UI that has become more cluttered over the years.  Often it&amp;#8217;s because of that lock-in.

&lt;h2&gt;UI Based Testing Takes More Staff and Time Than You Expect&lt;/h2&gt;

&lt;p&gt;This, really, is the most common failure case.  It&amp;#8217;s the case which explains the dust on the testing box&amp;#8217;s keyboard.  Someone, usually disconnected from the development organization, decides that &amp;#8220;hey, we need to solve the testing problem.  We have too many people doing manual testing.  It&amp;#8217;s taking forever.&amp;#8221;  So, they do their research, find a vendor with with a good licensing model and a good pitch and then they push it on the development organization.  They are, of course, looking to reduce staff so when they realize that translating all of those manual tests to the tool is very labor-intensive, they are taken aback.  But, of course, it is just a temporary cost, right? But, then it takes far longer than they expect.  Remember Janet&amp;#8217;s story?  It&amp;#8217;s really hard to catch up with a UI-Based testing tool.  It&amp;#8217;s hard to even stay in place with one.  Typically it takes a number of people to do UI-Based automated testing for a development team in sync with an iteration and worse, they&amp;#8217;ll always lag behind a bit because you can&amp;#8217;t really write UI-based tests ahead of time the way you can with &lt;span class="caps"&gt;FIT&lt;/span&gt; and other beneath-the-UI testing tools. From what I&amp;#8217;ve seen UI-based testing, done diligently, takes the effort of about one tester for every two to three developers.  That&amp;#8217;s what it seems to cost amortized across all of the maintenance of UI-induced test breakage. Oh, and by the way, if think you are going to save labor using record and playback?  Nope, you aren&amp;#8217;t.  It doesn&amp;#8217;t work.

&lt;h2&gt;Solutions&lt;/h2&gt;

&lt;p&gt;The fact of the matter is, you can use these tools effectively, but in a very narrow space.  It&amp;#8217;s nice to be able to test the UI&amp;#8212;by itself.  However, this sort of thing &lt;a href=http://www.computer.org/portal/web/csdl/doi/10.1109/MS.2005.110&gt;requires an architectural change&lt;/a&gt;. 

&lt;p&gt; In general, UIs are too volatile for end-to-end testing.  Teams that do it well, typically develop a small task-focused scripting layer and build tests on top if it so that the actual tests don&amp;#8217;t touch the UI directly.  But, if they happen across that technique, they are lucky. Still, it isn&amp;#8217;t an ideal solution. You really want to be &lt;i&gt;below&lt;/i&gt; the UI working against an &lt;span class="caps"&gt;API&lt;/span&gt; which exposes the business logic.  And, because of that nearly mystical synergy between testability and good design, that &lt;span class="caps"&gt;API&lt;/span&gt; layer is often useful for many things other than testing.

&lt;h2&gt;Conclusion/Challenge&lt;/h2&gt; 

&lt;p&gt;I recognize that I&amp;#8217;ve been rather vicious in the this blog.  If you develop these tools for a living, you might not think it&amp;#8217;s fair. But consider this.  If you don&amp;#8217;t think I&amp;#8217;m being fair, take a look at how your tools are marketed.  In particular, show me where the product literature discourages end-to-end testing through the tool.  Otherwise, well, you know, you are probably developing snake-oil.</description>
      <pubDate>Mon, 04 Jan 2010 05:35:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:b8d700fd-4c7c-4e3c-8d6f-d91710d990d4</guid>
      <author>Michael Feathers</author>
      <link>http://blog.objectmentor.com/articles/2010/01/04/ui-test-automation-tools-are-snake-oil</link>
      <category>Michaels Musings</category>
    </item>
    <item>
      <title>The Polyglot Tester</title>
      <description>&lt;p&gt;Behavior Driven Development, and it&amp;#8217;s emphasis on the &lt;em&gt;Given&lt;/em&gt; / &lt;em&gt;When&lt;/em&gt; / &lt;em&gt;Then&lt;/em&gt; structure of specification has been well accepted by many parts of the software industry.  Tools such as JBehave, Cucumber, GivWenZen, have taken a prominent role, and rightly so.  After all, it&amp;#8217;s hard to argue with the elegance of simple statements such as:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Given that I am a user named Bob with password xyzzy
&lt;br/&gt;When I log in with username Bob and password xyzzy
&lt;br/&gt;Then I should see &amp;#8220;Welcome Bob, you have logged in&amp;#8221;.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Yes, it&amp;#8217;s hard to argue with it, but argue I shall&amp;#8230;&lt;/p&gt;


	&lt;p&gt;The &lt;span class="caps"&gt;BDD&lt;/span&gt; style is very pretty.  Certainly business people can easily read and write it.  Moreover, the &lt;span class="caps"&gt;BDD&lt;/span&gt; style provides a conceptual framework within which automated test specification and be efficiently composed. Better still, the &lt;span class="caps"&gt;BDD&lt;/span&gt; tools provide a powerful parsing mechanism that conveniently translates the natural &lt;span class="caps"&gt;GWT&lt;/span&gt; statements into function calls to be executed as tests.&lt;/p&gt;


	&lt;p&gt;The problem is that the &lt;span class="caps"&gt;BDD&lt;/span&gt; style is simply not appropriate for all, or even most kinds of tests.  Why?  Because it&amp;#8217;s &lt;em&gt;wordy&lt;/em&gt;.  Consider:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Given a Juke box that shows 0 credits
&lt;br/&gt;When I deposit .25
&lt;br/&gt;Then the Juke Box shows 1 credit.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Given a Juke box that shows 0 credits.
&lt;br/&gt;When I deposit 1.00
&lt;br/&gt;Then the Juke Box shows 5 credits.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Given a Juke Box that shows 0 credits.
&lt;br/&gt;When I deposit 5.00
&lt;br/&gt;Then the Juke Box shows 30 credits.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;How is this better than:&lt;/p&gt;


	&lt;h3&gt;Jukebox Credit Table&lt;/h3&gt;


	&lt;table&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;strong&gt;Deposit&lt;/strong&gt;&lt;/td&gt;
			&lt;td&gt;&lt;strong&gt;Credits&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;25&lt;/td&gt;
			&lt;td&gt;1&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;1.00&lt;/td&gt;
			&lt;td&gt;5&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;5.00&lt;/td&gt;
			&lt;td&gt;30&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;




	&lt;ul&gt;
	&lt;li&gt;Which of the two is the more elegant?  &lt;/li&gt;
		&lt;li&gt;Which of the two is easier to read?  &lt;/li&gt;
		&lt;li&gt;If you were looking for a specification error, in which of the two would you be more likely to find it?&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;I think the answers are rather obvious.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;There is value in brevity.  &lt;/li&gt;
		&lt;li&gt;There is elegance in sparseness.  &lt;/li&gt;
		&lt;li&gt;Elaborate wordy structures are not always the best approach.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;OK, I can hear the complaints starting to bubble up already; so hold on.  I&amp;#8217;m not arguing against &lt;span class="caps"&gt;BDD&lt;/span&gt;.  I really like the &lt;span class="caps"&gt;GWT&lt;/span&gt; style.  And Yes, I realize that many of the &lt;span class="caps"&gt;BDD&lt;/span&gt; testing tools allow you to compress your tests into tables so that you can avoid the wordiness.&lt;/p&gt;


	&lt;p&gt;My issue is not with the tools.  My issue is with the idea that &lt;span class="caps"&gt;BDD&lt;/span&gt; is the only true way, and that all tests should be expressed in &lt;span class="caps"&gt;GWT&lt;/span&gt; format forever and ever amen.&lt;/p&gt;


	&lt;p&gt;Is this a strawman?  Unfortunately not.  In my travels over the last several years, I have seen this attitude showing up over and over again.  Someone will write a suite of complex tests using &lt;span class="caps"&gt;GWT&lt;/span&gt; style, without realizing that they could shorten it by a factor of 10 or so by recomposing it into a simple table.&lt;/p&gt;


	&lt;p&gt;Actually my issue &lt;em&gt;is&lt;/em&gt; with the tools.  Cucumber, for example, is written around &lt;em&gt;Given&lt;/em&gt;, &lt;em&gt;When&lt;/em&gt;, &lt;em&gt;Then&lt;/em&gt;.  If you use Cucumber, or JBehave, or any of the other &lt;span class="caps"&gt;BDD&lt;/span&gt; tools, you &lt;em&gt;think&lt;/em&gt; in &lt;span class="caps"&gt;GWT&lt;/span&gt; and find it hard to even express something as simple as the table above.&lt;/p&gt;


	&lt;p&gt;Consider, for example, the following strange test.  It measures how well the juke box selects random songs based upon their popularity.  More popular songs should be played more often than less popular songs.  You might specify it this way in &lt;span class="caps"&gt;GWT&lt;/span&gt; style.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Given a Juke box with 1 credit
&lt;br/&gt;When the user presses &amp;#8220;You Decide&amp;#8221; 
&lt;br/&gt;Then the juke box will randomly choose a song based on its ranking.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Now this is a perfectly good statement of intent, and I&amp;#8217;d certainly want it to turn green if I ran the test.  However, if this turns green, what have we really learned?  The test result does not really tell us whether or not the selection algorithm is accurate.  The &lt;span class="caps"&gt;GWT&lt;/span&gt; statements above are really just hand-waving statements that loudly say &lt;em&gt;Trust Me&lt;/em&gt; without necessarily verifying anything.&lt;/p&gt;


	&lt;p&gt;Now look at the following tables.&lt;/p&gt;


	&lt;table&gt;
		&lt;tr&gt;
			&lt;td&gt;Repeat you decide 10000 times and count results&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Average credits should ~=1.3&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;




&lt;p/&gt;

	&lt;table&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;strong&gt;Song&lt;/strong&gt;&lt;/td&gt;
			&lt;td&gt;&lt;strong&gt;Times played&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Stairway to Heaven&lt;/td&gt;
			&lt;td&gt;880 &amp;lt; _ &amp;lt; 1120&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;In-a-godda-da-vida&lt;/td&gt;
			&lt;td&gt;1880 &amp;lt; _ &amp;lt; 2120&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Viva La Vida&lt;/td&gt;
			&lt;td&gt;2880 &amp;lt; _ &amp;lt; 3120&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Incense and Peppermint&lt;/td&gt;
			&lt;td&gt;880 &amp;lt; _ &amp;lt; 1120&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Comfortably Numb&lt;/td&gt;
			&lt;td&gt;2880 &amp;lt; _ &amp;lt; 3120&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;




&lt;p/&gt;

	&lt;p&gt;Perhaps you don&amp;#8217;t like the magic numbers.  There are ways to deal with that, but they are beyond the scope of this blog.  So let&amp;#8217;s forget about the magic-ness of the numbers for the moment.  When you run this test you see something like this:&lt;/p&gt;


	&lt;table&gt;
		&lt;tr&gt;
			&lt;td&gt;Repeat you decide 10000 times and count results&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Average credits should &lt;span style="color:green;"&gt;1.295 ~=1.3&lt;/span&gt;&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;




&lt;p/&gt;

	&lt;table&gt;
		&lt;tr&gt;
			&lt;td&gt;&lt;strong&gt;Song&lt;/strong&gt;&lt;/td&gt;
			&lt;td&gt;&lt;strong&gt;Times played&lt;/strong&gt;&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Stairway to Heaven&lt;/td&gt;
			&lt;td&gt;&lt;span style="color:green;"&gt;880 &amp;lt; 998 &amp;lt; 1120&lt;/span&gt;&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;In-a-godda-da-vida&lt;/td&gt;
			&lt;td&gt;&lt;span style="color:green;"&gt;1880 &amp;lt; 2007 &amp;lt; 2120&lt;/span&gt;&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Viva La Vida&lt;/td&gt;
			&lt;td&gt;&lt;span style="color:green;"&gt;2880 &amp;lt; 2950 &amp;lt; 3120&lt;/span&gt;&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Incense and Peppermint&lt;/td&gt;
			&lt;td&gt;&lt;span style="color:green;"&gt;880 &amp;lt; 1019 &amp;lt; 1120&lt;/span&gt;&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Comfortably Numb&lt;/td&gt;
			&lt;td&gt;&lt;span style="color:green;"&gt;2880 &amp;lt; 3026 &amp;lt; 3120&lt;/span&gt;&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;




&lt;p/&gt;

	&lt;p&gt;It&amp;#8217;s hard to argue that the green-ness is hand-waving.  Nothing here says: &lt;em&gt;Trust Me&lt;/em&gt;.  You can see that the selection algorithm is random, and is weighted properly.&lt;/p&gt;


	&lt;p&gt;Now I&amp;#8217;m certain that we could construct a set of &lt;span class="caps"&gt;GWT&lt;/span&gt; statements that captures the above semantics perfectly; but why would we?  The simple tables express the intent in a format that is simpler and more accessible than &lt;span class="caps"&gt;GWT&lt;/span&gt;.&lt;/p&gt;


	&lt;h2&gt;Conclusion&lt;/h2&gt;


	&lt;p&gt;As programmers we have already learned that we must be polyglots. If you want to write a rails system you&amp;#8217;d better know ruby, haml, css, erb, xml, etc.  If you want to write a &lt;span class="caps"&gt;J2EE&lt;/span&gt; system, you&amp;#8217;d better know Java, &lt;span class="caps"&gt;JSP&lt;/span&gt;, HTML, &lt;span class="caps"&gt;XML&lt;/span&gt;, CSS, etc.&lt;/p&gt;


	&lt;p&gt;Testers also need to be polyglots.  Writing in a single style such as &lt;span class="caps"&gt;GWT&lt;/span&gt; is not going to cut it.  &lt;span class="caps"&gt;GWT&lt;/span&gt; has it&amp;#8217;s place, but it&amp;#8217;s not sufficient.  Other testing languages are also useful.  Therefore testing tools need to be polyglot tools.&lt;/p&gt;</description>
      <pubDate>Sat, 19 Dec 2009 11:22:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:0c3c7428-9f2b-42ac-90f3-24f20733dc99</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/12/19/the-polyglot-tester</link>
    </item>
    <item>
      <title>Name that refactoring: 2 - Version 2</title>
      <description>&lt;p&gt;A few updates applied to the second name that refactoring. Note that I&amp;#8217;m using a star to represent a problem dependency. It is the &amp;#8220;star&amp;#8221; of the refactoring. I&amp;#8217;m looking for a better image. I could go with a database icon, but the principle is more general than that. The cloud was confusing. So if you have an idea, please let me know what it is!&lt;/p&gt;


	&lt;p&gt;Again, thanks for taking a look and giving me the feedback.&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 0: Problematic Dependency&lt;/i&gt;&lt;/b&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-0.png/109818239/NameThatRefactoring_2-0.png"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 1: Capture dependency in a single class&lt;/i&gt;&lt;/b&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-1.png/109818237/NameThatRefactoring_2-1.png"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 2: Raise the abstraction to a domain-level interface&lt;/i&gt;&lt;/b&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-2.png/109818235/NameThatRefactoring_2-2.png" /&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 3: Introduce test doubles as needed&lt;/i&gt;&lt;/b&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-3.png/109818233/NameThatRefactoring_2-3.png" /&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 16 Dec 2009 02:14:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:8a78598f-7598-49e9-85c3-415b4afb89f3</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/12/16/name-that-refactoring-2-version-2</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>refactoring</category>
      <category>TDD</category>
      <category>picture</category>
      <category>writing</category>
    </item>
    <item>
      <title>Name that refactoring: 1 - Version 2</title>
      <description>&lt;p&gt;Here is an update to the first name that refactoring based on feedback. How about this?&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 0: Method with embedded dependency&lt;/b&gt;&lt;/i&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_1-1.png/109816073/NameThatRefactoring_1-1.png"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 1:Extract method to move dependency to another method&lt;/b&gt;&lt;/i&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_1-2.png/109816629/NameThatRefactoring_1-2.png"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 2: Subclass and override method with new code that does not have original dependency&lt;/b&gt;&lt;/i&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_1-3.png/109816627/NameThatRefactoring_1-3.png"/&gt;&lt;/p&gt;


	&lt;p&gt;So what do you think? Better or worse?&lt;/p&gt;


	&lt;p&gt;What about using the star in other image? In general, the star could represent the dependency we&amp;#8217;re trying to get rid of.&lt;/p&gt;</description>
      <pubDate>Wed, 16 Dec 2009 01:43:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:f54168c7-20d6-4c62-ba6f-7de62ec2295d</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/12/16/name-that-refactoring-1-version-2</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>refactoring</category>
      <category>TDD</category>
      <category>picture</category>
      <category>writing</category>
    </item>
    <item>
      <title>Name that refactoring: 2</title>
      <description>&lt;p&gt;Ok, so I&amp;#8217;m getting good feedback on the first picture. Now for a series of pictures.&lt;/p&gt;


	&lt;p&gt;How do you interpret this series?&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 0&lt;/b&gt;&lt;/i&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-1.png/109310773/NameThatRefactoring_2-1.png"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 1&lt;/b&gt;&lt;/i&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-2.png/109310771/NameThatRefactoring_2-2.png"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 2&lt;/b&gt;&lt;/i&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-3.png/109310769/NameThatRefactoring_2-3.png"/&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;Step 3&lt;/b&gt;&lt;/i&gt;&lt;p/&gt;
&lt;img src="http://schuchert.wikispaces.com/file/view/NameThatRefactoring_2-4.png/109310767/NameThatRefactoring_2-4.png"/&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 13 Dec 2009 22:51:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:f612878a-68b6-427b-bca5-78783f70c884</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/12/13/name-that-refactoring-2</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>refactoring</category>
      <category>TDD</category>
      <category>picture</category>
      <category>writing</category>
    </item>
    <item>
      <title>Name that refactoring: 1</title>
      <description>&lt;p&gt;I&amp;#8217;m working on writing up a few handouts I can use in a &lt;span class="caps"&gt;TDD&lt;/span&gt; class (and a few other places). There are a few drawings I keep doing and I&amp;#8217;m trying to replicate them so I can refer to something.&lt;/p&gt;


Problem is, with many such drawings, the observation of the creation is as important as the end product. I&amp;#8217;d like your feedback/recommendations (or links to better pictures). I&amp;#8217;m curious about at least two things.
	&lt;ul&gt;
	&lt;li&gt;What does this picture suggest to you or what can you draw from it, if anything?&lt;/li&gt;
		&lt;li&gt;Do you think this would be better served as a series of pictures showing the build-up?&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;img src=http://schuchert.wikispaces.com/file/view/NameThatRefactoring_1.png/109280805/NameThatRefactoring_1.png"&gt;&lt;/p&gt;


	&lt;p&gt;Thanks for your feedback.&lt;/p&gt;</description>
      <pubDate>Sun, 13 Dec 2009 19:35:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:55886ea2-c35a-4ab2-a166-7e2dd425404b</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/12/13/name-that-refactoring-1</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>refactoring</category>
      <category>TDD</category>
      <category>picture</category>
      <category>writing</category>
    </item>
    <item>
      <title>Writing Maintainable Automated Acceptance Tests.</title>
      <description>&lt;p&gt;Dale Emery recently wrote a lovely &lt;a href="http://cwd.dhemery.com/2009/11/wmaat/"&gt;article&lt;/a&gt; that has the same name as this blog.  This article is really quite good.  It makes the point that writing acceptance tests &lt;em&gt;is&lt;/em&gt; writing software; and so the same principles of cohesion, coupling, &lt;span class="caps"&gt;DRY&lt;/span&gt;, etc. apply.&lt;/p&gt;


	&lt;p&gt;The only problem I had with Dale&amp;#8217;s article, is that he used the wrong tool to demonstrate his principles.  So I&amp;#8217;ve created a video to show you how to apply Dale&amp;#8217;s principles using FitNesse.  (See below)&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ve included three different sources for the video.  One of them ought to work for you.  The higest resolution video is the quicktime/screencast version; but some people can&amp;#8217;t use it.   So choose your poison.&lt;/p&gt;


&lt;h3&gt;Viddler&lt;/h3&gt;
&lt;a href="http://www.viddler.com/explore/unclebobmartin/videos/4/"&gt;link&lt;/a&gt;
&lt;object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="437" height="370" id="viddler_unclebobmartin_4"&gt;&lt;param name="movie" value="http://www.viddler.com/player/125a82bd/" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;embed src="http://www.viddler.com/player/125a82bd/"  wmode="transparent" width="437" height="370" type="application/x-shockwave-flash" allowScriptAccess="always" allowFullScreen="true" name="viddler_unclebobmartin_4" /&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;hr/&gt;
&lt;h3&gt;Vimeo&lt;/h3&gt; 
&lt;a href="http://vimeo.com/8041760"&gt;link&lt;/a&gt;
&lt;object width="400" height="300"&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=8041760&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=8041760&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" width="400" height="300"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;p&gt;&lt;a href="http://vimeo.com/8041760"&gt;Writing Maintainable Automated Acceptance Tests&lt;/a&gt; from &lt;a href="http://vimeo.com/user947916"&gt;unclebob&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;hr/&gt;
&lt;h3&gt;screencast.com&lt;/h3&gt; (QuickTime) &lt;a href="http://www.screencast.com/t/YTliZTkxNm"&gt;link&lt;/a&gt;
&lt;object name="Video" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" codebase="http://www.apple.com/quicktime/download/" standby="Loading Quicktime components..." width="819" height="630" &gt; &lt;param name="src" value="http://content.screencast.com/users/unclebobmartin/folders/Default/media/861c647d-d814-4ffc-abd3-e3e644ef0242/WMAAT.mov"&gt;&lt;/param&gt; &lt;param name="autoplay" value="false"&gt;&lt;/param&gt; &lt;param name="controller" value="true"&gt;&lt;/param&gt; &lt;param name="enablejavascript" value="true"&gt;&lt;/param&gt; &lt;param name="playCount" value="1"&gt;&lt;/param&gt; &lt;param name="starttime" value="0"&gt;&lt;/param&gt; &lt;embed name="Video" pluginspage="http://www.apple.com/quicktime/download/" type="video/quicktime" src="http://content.screencast.com/users/unclebobmartin/folders/Default/media/861c647d-d814-4ffc-abd3-e3e644ef0242/WMAAT.mov" autoplay="false" controller="true" enablejavascript="true" starttime="0" width="819" height="630"&gt;&lt;/embed&gt; &lt;/object&gt;
&lt;hr/&gt;</description>
      <pubDate>Mon, 07 Dec 2009 16:54:42 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:a01b1158-3e02-49d9-8413-d411fbc6180a</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/12/07/writing-maintainable-automated-acceptance-tests</link>
    </item>
    <item>
      <title>the Importance of Observers</title>
      <description>&lt;p&gt;This week I spent 2 days with my friend &lt;a href="http://www.enthiosys.com/"&gt;Luke Hohmann&lt;/a&gt; getting trained in the use of &lt;a href="http://www.amazon.com/Innovation-Games-Creating-Breakthrough-Collaborative/dp/0321437292/ref=sr_1_1?ie=UTF8&amp;#38;s=books&amp;#38;qid=1259949907&amp;#38;sr=8-1"&gt;Innovation Games&amp;#174;&lt;/a&gt;. &lt;a href="http://www.amazon.com/Innovation-Games-Creating-Breakthrough-Collaborative/dp/0321437292/ref=sr_1_1?ie=UTF8&amp;#38;s=books&amp;#38;qid=1259949907&amp;#38;sr=8-1"&gt;Innovation Games&amp;#174;&lt;/a&gt; are a class of so-called serious games that use metaphor and experiential learning situations with an end-result-goal of developing actionable information. (This is my current way of describing them anyway.)&lt;/p&gt;


	&lt;p&gt;During one of these games I played the role of a facilitator. There were 2 of us facilitating, three &amp;#8220;customers&amp;#8221; being interviewed and 4 observers.&lt;/p&gt;


	&lt;p&gt;In my typical consulting role, I am often playing the role of facilitator, but I also have set myself up as an observer at the same time. In the past, this has seemed to make sense given I was the only consultant in the room. This recent experience, however, has really changed how I think about those situations.&lt;/p&gt;


In the design of &lt;a href="http://www.amazon.com/Innovation-Games-Creating-Breakthrough-Collaborative/dp/0321437292/ref=sr_1_1?ie=UTF8&amp;#38;s=books&amp;#38;qid=1259949907&amp;#38;sr=8-1"&gt;Innovation Games&amp;#174;&lt;/a&gt;, the facilitator will typically have a number (1/2 &amp;#8211; 1/3) of the participants serve as observers. This has several advantages.
	&lt;ul&gt;
	&lt;li&gt;The facilitator can focus on one thing (think single responsibility principle).&lt;/li&gt;
		&lt;li&gt;Different observers, different filters (we all have filters all of the time), resulting in more perspectives captured, giving better overall information.&lt;/li&gt;
		&lt;li&gt;Given enough observers, you can have individual observers focus on specific things.&lt;/li&gt;
		&lt;li&gt;Since the observers are typically from the team (not the consulting company), it reinforces the notion of ownership. The facilitator does not own the results, nor does s/he produce the results.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Why so many observers? &lt;a href="http://www.amazon.com/Innovation-Games-Creating-Breakthrough-Collaborative/dp/0321437292/ref=sr_1_1?ie=UTF8&amp;#38;s=books&amp;#38;qid=1259949907&amp;#38;sr=8-1"&gt;Innovation Games&amp;#174;&lt;/a&gt; are designed to get access to the things you don&amp;#8217;t know you don&amp;#8217;t know.&lt;/p&gt;


Jerry Weinberg has a simple model of leadership. The &lt;span class="caps"&gt;MOIJ&lt;/span&gt; model.
	&lt;ul&gt;
	&lt;li&gt;M is for Motivation&lt;/li&gt;
		&lt;li&gt;O is for Organization&lt;/li&gt;
		&lt;li&gt;I is for Innovation&lt;/li&gt;
		&lt;li&gt;J is for Jiggle&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;In any situation, take a read. Do you have too much Motivation or too little? Too much? People are frantic and running around like kids just after getting back from a successful night of trick-or-treating. Too little? Everybody is exhausted from yet another all nighter getting ready for a demo because too much focus was placed on adding stuff rather than adding stuff well.&lt;/p&gt;


	&lt;p&gt;The same idea applies to Organization and Innovation. It is possible to have to much or too little organization and too many or too few ideas.&lt;/p&gt;


	&lt;p&gt;What happens when none of those first three seem to fit? That&amp;#8217;s the Jiggle. You introduce some random element to see if you can get access to something you don&amp;#8217;t know you don&amp;#8217;t know.&lt;/p&gt;


	&lt;p&gt;With many observers (e.g. 8-10 in a group of 20), you have the flexibility to have someone look at hand gestures, someone to look at eye contact, someone to listen to change in vocal pitch, etc. That is, you have &amp;#8220;typical&amp;#8221; observers listening for &amp;#8220;important&amp;#8221; information and &amp;#8220;jiggiling&amp;#8221; observers searching form something else. Since you don&amp;#8217;t know what you don&amp;#8217;t know, doing things with specific kinds of observations might jiggle out information that otherwise you would have missed. It may not, that&amp;#8217;s part of the problem of trying to work in the space of you don&amp;#8217;t know you don&amp;#8217;t know.&lt;/p&gt;


	&lt;p&gt;In any case, to me this is now one of those &amp;#8220;intuitive once you know it&amp;#8221; things. In the past, I have worked within my self-perceived constraints of being a single person with 2 roles needing to be filled. Maybe on an intellectual level I understood the value of having observers separate from the facilitator but I did not really grok it.&lt;/p&gt;


	&lt;p&gt;Now I think I do.&lt;/p&gt;


	&lt;p&gt;Will I always separate those roles? I don&amp;#8217;t believe in context-free best practices, so no. However, will I make this my default preference? I&amp;#8217;ll certainly work on it.&lt;/p&gt;


	&lt;p&gt;More specifically, how am I going to use this new knowledge?&lt;/p&gt;


	&lt;p&gt;In 2 weeks, Michael Feathers and I are co-teaching an Agile/XP Immersion in Seattle. I&amp;#8217;ve already planned to use a few of the &lt;a href="http://www.amazon.com/Innovation-Games-Creating-Breakthrough-Collaborative/dp/0321437292/ref=sr_1_1?ie=UTF8&amp;#38;s=books&amp;#38;qid=1259949907&amp;#38;sr=8-1"&gt;Innovation Games&amp;#174;&lt;/a&gt; during the class. The big difference, however, is that I&amp;#8217;m going to encourage a number of the students to play the role of an observer (listening, recording, saying nothing) to give the customer a chance to own what&amp;#8217;s going on rather than being the recipient of a technique.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m sure it will take me some time to embody this new approach as my default rather than falling back on the (up until now) current way I&amp;#8217;ve been doing things. I&amp;#8217;m sure I&amp;#8217;ll stumble along the way. But as long as I keep making new mistakes and not repeating the old ones over and over, I&amp;#8217;ll be moving in a good direction.&lt;/p&gt;</description>
      <pubDate>Fri, 04 Dec 2009 11:51:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:39dbbe5e-7638-422c-9828-d3146b3cb7c2</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/12/04/the-importance-of-observers</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>innovation</category>
      <category>games</category>
      <category>r</category>
      <category>observation</category>
    </item>
    <item>
      <title>Saying &amp;quot;NO&amp;quot;.</title>
      <description>&lt;p&gt;I saw &lt;a href="http://theoatmeal.com/comics/design_hell"&gt;this cartoon&lt;/a&gt; in a tweet today. It&amp;#8217;s the story of how a boss corrupts the work of a professional.  It&amp;#8217;s a funny cartoon, and a sad story that happens all too often in our profession.  But who, exactly, was at fault?...&lt;/p&gt;


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


	&lt;p&gt;But something else compensates for the effort.  Making this recording was &lt;em&gt;fun&lt;/em&gt;&amp;#8212;it was a &lt;em&gt;lot of fun&lt;/em&gt;.  And that&amp;#8217;s probably the real answer to the question posed in the title of this blog.&lt;/p&gt;</description>
      <pubDate>Sat, 21 Nov 2009 04:32:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:b1c40077-fac6-4dd9-bc7f-0f988f020569</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/11/21/whats-all-this-nonsense-about-katas</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
    </item>
    <item>
      <title>Oh you poor, poor customer</title>
      <description>&lt;p&gt;I just got back from my third time at the &lt;a href="http://www.ayeconference.com/"&gt;&lt;span class="caps"&gt;AYE&lt;/span&gt;&lt;/a&gt; conference and it was another great time. I had a real eye-opening experience on Wednesday and it had to do with how I interact with customers, QA and even developers. Pretty much anybody taking a class or starting a project where I am involved.&lt;/p&gt;


I participated in a simulation of a project, playing the role of customer.
	&lt;ul&gt;
	&lt;li&gt;There were two of us playing customers &amp;#8211; we did not understand the problem and we did not necessarily agree or understand where we had different interpretations&lt;/li&gt;
		&lt;li&gt;We were freshly assigned the role and did not quite understand the details of the problem, our actual responsibility or how to interact with the team (a deficit of tacit knowledge)&lt;/li&gt;
		&lt;li&gt;Time was (perceived to be) at a premium&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;The session/simulation was run with great expertise by &lt;a href="http://www.donaldegray.com/tiki-index.php"&gt;Don Gray&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;My first really strong observation was during the first meeting with the development group &amp;#8211; about 5 minutes in. My co-customer and I had spent a few minutes (literally) reading the requirements and coming to some partial understanding. We met with the &amp;#8220;simulated&amp;#8221; development team and all hell broke loose (at least in my head).&lt;/p&gt;


The development team did some things well.
	&lt;ul&gt;
	&lt;li&gt;They tried to think of something small they could do in a time-box.&lt;/li&gt;
		&lt;li&gt;They presented us (the customers) with concrete examples of things they could do as first examples.&lt;/li&gt;
		&lt;li&gt;They asked concrete questions about the requirements.&lt;/li&gt;
		&lt;li&gt;The presented some preliminary examples of possible interpretations.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;These are all good things; things I would and have recommend in the past &amp;#8211; and will contine to do in the future. And these things&lt;i&gt; &lt;b&gt;did not work for me&lt;/b&gt;&lt;/i&gt;.&lt;/p&gt;


&amp;#8220;Playing&amp;#8221; the role of customer, when I came to that initial meeting there were many things in flux.
	&lt;ul&gt;
	&lt;li&gt;I did not really have much of an idea of a time-box.&lt;/li&gt;
		&lt;li&gt;I had looked at the problem in a very different way than the development team, so many of their questions simply did not make any sense to me.&lt;/li&gt;
		&lt;li&gt;I felt bombarded by many voices, with many different kinds and levels of content.&lt;/li&gt;
	&lt;/ul&gt;


I took away quite a bit away from that experience that I&amp;#8217;d do well to incorporate in my future interactions.
	&lt;ul&gt;
	&lt;li&gt;I am a big-time &lt;a href="http://en.wikipedia.org/wiki/Extraversion_and_introversion"&gt;extravert&lt;/a&gt; (Jung&amp;#8217;s definition) and I&amp;#8217;ve been the source of this kind of bombardment.&lt;/li&gt;
		&lt;li&gt;I need to catch myself jumping right in on what I think is important and instead&lt;i&gt; &lt;b&gt;ask what is important&lt;/b&gt;&lt;/i&gt; to the customer (or BA or QA or developer for that matter).&lt;/li&gt;
		&lt;li&gt;I probably have overly high expectations of what can be accomplished before the team has started to form, much of that initial interaction lacks the tacit knowledge of actual roles and requirements, such that many things are in flux.&lt;/li&gt;
		&lt;li&gt;Or, given a team that has been together, I need to get a grasp on its structure before making change recommendations.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;At one point, someone mentioned (in essence) that the &amp;#8220;actual&amp;#8221; requirements were coming from Don, not me, and essentially wrote me off. That was quite a powerful experience as I felt completely devalued as the customer. I can imagine a business person or QA person feeling the same thing.&lt;/p&gt;


	&lt;p&gt;I think the biggest one-word summary of the experience for me is empathy.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;After&amp;#8221; the simulation (I still had not fully decompressed I think), one person expressed concern over how the customers (me) had not followed &amp;#8220;the process&amp;#8221;. Wow is all I can say to my experience during that simple, loaded phrase.&lt;/p&gt;


	&lt;p&gt;In my world of the simulation, there was no process &amp;#8211; explicit or implicit. If there was one used by the team, it was tacit and I certainly was not aware of it (in fact, I don&amp;#8217;t think there was one &amp;#8220;the process&amp;#8221; as far as I could tell because I was able to both participate and observe). But regardless of whether there was or was not an explicit or implicit process, it does not matter. Can you imagine someone who is not fully available (a customer), being treated as if they were &amp;#8220;not following the process?&amp;#8221;, which I inferred to mean &amp;#8220;I was being difficult.&amp;#8221;&lt;/p&gt;


When I&amp;#8217;ve thought that, consciously or even subconsciously, I&amp;#8217;m certain that belief clouded my interactions with other people and it probably has come across as aggressive/offensive/inconsiderate. Maybe a good mantra to repeat to myself is something like:
&lt;blockquote&gt;
&lt;b&gt;&lt;i&gt;No matter how it might look, people are trying to be helpful to the best of their ability.&lt;/b&gt;&lt;/i&gt;
&lt;/blockquote&gt;

I know for certain my intentions during that simulation were good. I was trying to give information to the best of my abilities. I just wasn&amp;#8217;t yet aware of the requirements and I did not know how the development team was working. To be treated as if I was sabotaging &amp;#8220;the process&amp;#8221; was in fact quite offensive to me. I am certain I&amp;#8217;ve done that over the years. &amp;#8220;The process&amp;#8221;, regardless of which process it is, is a&lt;i&gt; &lt;b&gt;model&lt;/b&gt;&lt;/i&gt; of how to do things. And something I overheard really speaks about this:
&lt;blockquote&gt;
&lt;b&gt;&lt;i&gt;All models are wrong; some are useful.&lt;/b&gt;&lt;/i&gt;
&lt;/blockquote&gt;

	&lt;p&gt;(Notice how that applies to things like &lt;span class="caps"&gt;TDD&lt;/span&gt;, BDD, Scrum, XP, ...?-)&lt;/p&gt;


	&lt;p&gt;If you have a chance to attend &lt;span class="caps"&gt;AYE&lt;/span&gt; next year (or &lt;span class="caps"&gt;PSL&lt;/span&gt; in May), I&amp;#8217;d encourage you to do so. But be prepared to be overwhelmed with personal observations.&lt;/p&gt;</description>
      <pubDate>Fri, 13 Nov 2009 13:12:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:1d89322b-a60b-4c2c-b420-ac6fb43338e4</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/11/13/oh-you-poor-poor-customer</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>Extroversion</category>
      <category>aye</category>
      <category>tacit</category>
      <category>process</category>
      <category>people</category>
    </item>
    <item>
      <title>Archeological Dig</title>
      <description>&lt;p&gt;I was going through some old files today, and I stumbled upon some acetate slides from 1995.  They were entitled: &amp;#8220;Managing OO Projects&amp;#8221;.  Wow!  What a difference fifteen years makes!   (Or does it?) ...&lt;/p&gt;


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


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


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


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


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

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


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


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


	&lt;p&gt;Comments please!&lt;/p&gt;</description>
      <pubDate>Wed, 11 Nov 2009 10:39:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:2719dd93-f02d-4cbb-9850-265f68fbfb65</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/11/11/archeological-dig</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Agile Methods</category>
      <category>Design Principles</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>Excuse me sir, What Planet is this?</title>
      <description>&lt;p&gt;Update 12 hours later.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m not very proud of this blog (or as one commenter correctly called it &amp;#8220;blart&amp;#8221;).  It is derisive, sneering, and petulant.  It is unprofessional.  I guess I was having a bad morning.  I slipped.  I didn&amp;#8217;t check with my green band.&lt;/p&gt;


	&lt;p&gt;So I apologize to the audience at large, and to Cashto.  You should expect better from me.&lt;/p&gt;


	&lt;p&gt;I thought about pulling the blog down; but I think I&amp;#8217;ll leave it up here as an example of how &lt;i&gt;not&lt;/i&gt; to write a blog.&lt;/p&gt;


	&lt;p&gt;Some folks on twitter have been asking me to respond to this &lt;a href="http://blogs.msdn.com/cashto/archive/2009/03/31/it-s-ok-not-to-write-unit-tests.aspx"&gt;blough&lt;/a&gt; (don&amp;#8217;t bother to read it right now, I&amp;#8217;ll give you the capsule summary below.  Read it later if you must).  It&amp;#8217;s a typical screed complete with all the usual complaints, pejoratives, and illogic.  Generally I don&amp;#8217;t respond to blarts like this because I don&amp;#8217;t imagine that any readers take them very seriously.  But it appears that this blelch has made the twitter rounds and that I&amp;#8217;m going to have to say &lt;em&gt;something&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Here are the writer&amp;#8217;s main points:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;He likens unit tests to training wheels and says you can&amp;#8217;t use them to win the &lt;em&gt;Tour de France&lt;/em&gt;. 
	&lt;ul&gt;
	&lt;li&gt;I think winning the &lt;em&gt;Tour de France&lt;/em&gt; has much more to do with self-discipline than he imagines it does.  I mean it&amp;#8217;s not really just as simple as: &amp;#8220;Get on a bike and ride like hell!&amp;#8221;&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;He says testing is popular amongst college students
	&lt;ul&gt;
	&lt;li&gt;I&amp;#8217;d like to see his data!&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;He goes on to say: (cue John Cleese): &amp;#8220;(ahem) unit tests lose their effectiveness around level four of the &lt;em&gt;Dreyfus model of skill acquisition&amp;#8221;.&lt;/em&gt;  
	&lt;ul&gt;
	&lt;li&gt;(blank stunned stare).  Is this a joke?  All false erudition aside, &lt;span class="caps"&gt;WTF&lt;/span&gt; is he talking about?&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;He says that unit tests &lt;em&gt;don&amp;#8217;t&lt;/em&gt; give us confidence in refactoring because they &lt;strong&gt;over-specify&lt;/strong&gt; behavior and are too &lt;strong&gt;fine-grained&lt;/strong&gt;.  
	&lt;ul&gt;
	&lt;li&gt;He apparently prefers hyphenations to green bars.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;He says they mostly follow the &amp;#8220;happy path&amp;#8221; and therefore don&amp;#8217;t find bugs.  
	&lt;ul&gt;
	&lt;li&gt;Maybe when &lt;em&gt;he&lt;/em&gt; writes them!  This is a &lt;em&gt;big&lt;/em&gt; clue that the author can&amp;#8217;t spell &lt;span class="caps"&gt;TDD&lt;/span&gt;.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;He complains about Jester 
	&lt;ul&gt;
	&lt;li&gt;without getting the joke!&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;He says unit tests &amp;#8220;encourage some pretty questionable practices.&amp;#8221;  He flings a few design principles around and says that unit testing doesn&amp;#8217;t help with them. 
	&lt;ul&gt;
	&lt;li&gt;as the author, editor, and/or advocate of many of those principles; I have a slightly different view.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;He says that &amp;#8220;many are starting to discover that functional programming teaches far better design principles than unit testing ever will&amp;#8221;  
	&lt;ul&gt;
	&lt;li&gt;Oh no!  Not the old &amp;#8220;My language teaches design.&amp;#8221; claim.  We&amp;#8217;ve heard it all before.  They said it about C++, Java, &lt;span class="caps"&gt;COM&lt;/span&gt; (?!), etc&amp;#8230;  The lesson of the &amp;#8216;90s?  &lt;em&gt;Languages don&amp;#8217;t teach design&lt;/em&gt;.  You can make a mess in &lt;em&gt;any&lt;/em&gt; language.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;He says: &amp;#8220;tests can have negative &lt;span class="caps"&gt;ROI&lt;/span&gt;. Not only do they cost a lot to write, they&amp;#8217;re fragile, they&amp;#8217;re always broken, they get in the way of your refactoring, they&amp;#8217;re always having you chase down bogus failures, and the only way to get anything done is to ignore them.&amp;#8221;  
	&lt;ul&gt;
	&lt;li&gt;In one of my favorite episodes of Dr. Who, Tom Baker exits the Tardis, walks up to someone on the street and says: &amp;#8220;Excuse me sir, what planet is this?&amp;#8221;&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;He says: &amp;#8220;What I&amp;#8217;m saying is that it&amp;#8217;s okay if you don&amp;#8217;t write unit tests for everything. You probably have already suspected this for a long time, but now you know. I don&amp;#8217;t want you to feel guilty about it any more.&amp;#8221; 
	&lt;ul&gt;
	&lt;li&gt;Translation: &amp;#8220;&lt;i&gt;I&lt;/i&gt; don&amp;#8217;t want to feel guilty about it anymore so I&amp;#8217;m going to try to convince you&amp;#8230;&amp;#8221;  I sincerely doubt this author has &lt;em&gt;your&lt;/em&gt; best interests at heart.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;He says: &amp;#8220;Debugging is easy, at least in comparison to writing all those tedious tests.&amp;#8221; 
	&lt;ul&gt;
	&lt;li&gt;Refer back to the Dr. Who quote.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;br&gt;
&lt;br&gt;
To quote Barack Obama: &amp;#8220;Enough!&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Has this guy ever done &lt;span class="caps"&gt;TDD&lt;/span&gt;?  I rather doubt it.  Or if he did, he was so inept at it that his tests were &amp;#8220;fragile&amp;#8221;, &amp;#8220;always broken&amp;#8221;, and &amp;#8220;in the way of refactoring&amp;#8221;.  I think he should give it another try and this time spend a bit more time on test design.&lt;/p&gt;


	&lt;p&gt;Perhaps he&amp;#8217;s one of those guys who thought that unit tests were best written &lt;em&gt;after&lt;/em&gt; the code.  Certainly his list of complains makes a lot of sense in that light.  Hint:  If you want to fail at unit testing, write them last.&lt;/p&gt;


	&lt;p&gt;The bottom line is that the guy probably had a bad experience writing unit tests.  He&amp;#8217;s tired of writing them and wants to write fewer of them.  He&amp;#8217;d rather debug.  He thinks he can refactor without tests (which is definitively false).  He thinks he can go faster by writing fewer tests.  Fine, that&amp;#8217;s his choice. And he&amp;#8217;s found a rationalization to support his desires.  Great.&lt;/p&gt;


	&lt;p&gt;I predict that his results will not compare well with those who adopt the discipline of &lt;span class="caps"&gt;TDD&lt;/span&gt;.  I predict that after a few years he&amp;#8217;ll either change his mind, or go into management.&lt;/p&gt;


	&lt;p&gt;Oh, and to the author:  Gesundheit!&lt;/p&gt;</description>
      <pubDate>Thu, 05 Nov 2009 10:35:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:2a532aa7-e2ff-49b1-bfdf-38f1aa9fead9</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/11/05/its-ok-not-to-write-unit-tests-not</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Agile Methods</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>Manual Mocking: Resisting the Invasion of Dots and Parentheses</title>
      <description>&lt;p&gt;The twittersphere has been all abuzz today because of something I tweeted early this morning (follow @unclebobmartin).  In my tweet I said that I hand-roll most of my own mock objects in Java, rather than using a mocking framework like &lt;a href="mockito.org"&gt;mockito&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The replies were numerous and vociferous.  Dave Astels poignantly stated that hand-rolling mocks is so 2001!&lt;/p&gt;


	&lt;p&gt;So why do I roll my own mocks?&lt;/p&gt;


Consider the following two tests:
&lt;pre&gt;
public class SelectorTest {
  private List&amp;lt;Object&amp;gt; list;

  @Before
  public void setup() {
    list = new ArrayList&amp;lt;Object&amp;gt;();
    list.add(new Object());
  }

  @Test
  public void falseMatcherShouldSelectNoElements_mockist() {
    Matcher&amp;lt;Object&amp;gt; falseMatcher = mock(Matcher.class);
    Selector&amp;lt;Object&amp;gt; selector = new Selector&amp;lt;Object&amp;gt;(falseMatcher);
    when(falseMatcher.match(anyObject())).thenReturn(false);
    List&amp;lt;Object&amp;gt; selection = selector.select(list);
    assertThat(selection.size(), equalTo(0));
  }

  @Test
  public void falseMatcherShouldSelectNoElements_classic() {
    Matcher&amp;lt;Object&amp;gt; falseMatcher = new FalseMatcher();
    Selector&amp;lt;Object&amp;gt; selector = new Selector&amp;lt;Object&amp;gt;(falseMatcher);
    List&amp;lt;Object&amp;gt; selection = selector.select(list);
    assertThat(selection.size(), equalTo(0));}

  private static class FalseMatcher implements Matcher&amp;lt;Object&amp;gt; {
    public boolean match(Object element) {
      return false;
    }
  }
}
&lt;/pre&gt;

	&lt;p&gt;The first test shows the really cool power of &lt;a href="mockito.org"&gt;mockito&lt;/a&gt; (which is my current favorite in the menagerie of java mocking frameworks).  Just in case you can&amp;#8217;t parse the syntax, let me describe it for you:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;falseMatcher is assigned the return value of the &amp;#8220;mock&amp;#8221; function.  This is a very cool function that takes the argument class and builds a new stubbed object that derives from it.  In mockito, the argument can be a class or an interface.  Cool!&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Now don&amp;#8217;t get all panicy about the strange parenthetic syntax of the &amp;#8216;when&amp;#8217; statement.  The &amp;#8216;when&amp;#8217; statement simply tells the mock what to do when a method is called on it.  In this case it instructs the falseMatcher to return false when the &amp;#8216;match&amp;#8217; function is called with any object at all.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;The second test needs no explanation.&lt;/p&gt;


	&lt;p&gt;...&lt;/p&gt;


	&lt;p&gt;And that&amp;#8217;s kind of the point.  Why would I include a bizzare, dot-ridden, parentheses-laden syntax into my tests, when I can just as easily hand-roll the stub in pure and simple java?  How hard was it to hand-roll that stub?  Frankly, it took a lot less time and effort to hand-roll it than it took to write the (when(myobj.mymethod(anyx())).)()).))); statement.&lt;/p&gt;


	&lt;p&gt;OK, I&amp;#8217;m poking a little fun here.  But it&amp;#8217;s true.  My &lt;span class="caps"&gt;IDE&lt;/span&gt; (InteliJ) generated the stub for me.  I simply started with:&lt;/p&gt;


&lt;pre&gt;
Matcher&amp;lt;Object&amp;gt; falseMatcher = new Matcher&amp;lt;Object&amp;gt;() {};
&lt;/pre&gt;

	&lt;p&gt;InteliJ complained that some methods weren&amp;#8217;t implemented and offered to implement them for me.  I told it to go ahead.  It wrote the &amp;#8216;match&amp;#8217; method exactly as you see it.  Then I chose &amp;#8220;Convert Anonymous to Inner&amp;#8230;&amp;#8221; from the refactoring menu and named the new class FalseMatcher.  Voila!  No muss, no fuss, no parenthetic maze of dots.&lt;/p&gt;


Now look, I&amp;#8217;m not saying you shouldn&amp;#8217;t use mockito, or any of these other mocking tools.  I use them myself when I must.  Here, for example, is a test I wrote in FitNesse.  I was forced to use a mocking framework because I did not have the source code of the classes I was mocking.
&lt;pre&gt;
  @Before
  public void setUp() {
    manager = mock(GSSManager.class);
    properties = new Properties();
  }

  @Test
  public void credentialsShouldBeNonNullIfServiceNamePresent() throws Exception {
    properties.setProperty("NegotiateAuthenticator.serviceName", "service");
    properties.setProperty("NegotiateAuthenticator.serviceNameType", "1.1");
    properties.setProperty("NegotiateAuthenticator.mechanism", "1.2");
    GSSName gssName = mock(GSSName.class);
    GSSCredential gssCredential = mock(GSSCredential.class);
    when(manager.createName(anyString(), (Oid) anyObject(), (Oid) anyObject())).thenReturn(gssName);
    when(manager.createCredential((GSSName) anyObject(), anyInt(), (Oid) anyObject(), anyInt())).thenReturn(gssCredential);
    NegotiateAuthenticator authenticator = new NegotiateAuthenticator(manager, properties);
    Oid serviceNameType = authenticator.getServiceNameType();
    Oid mechanism = authenticator.getMechanism();
    verify(manager).createName("service", serviceNameType, mechanism);
    assertEquals("1.1", serviceNameType.toString());
    assertEquals("1.2", mechanism.toString());
    verify(manager).createCredential(gssName, GSSCredential.INDEFINITE_LIFETIME, mechanism, GSSCredential.ACCEPT_ONLY);
    assertEquals(gssCredential, authenticator.getServerCredentials());
  }
&lt;/pre&gt;

	&lt;p&gt;If I&amp;#8217;d had the source code of the &lt;span class="caps"&gt;GSS&lt;/span&gt; classes, I could have created some very simple stubs and spies that would have allowed me to make these tests a &lt;em&gt;lot&lt;/em&gt; cleaner than they currently appear.  Indeed, I might have been able to test the true &lt;em&gt;behavior&lt;/em&gt; of the classes rather than simply testing that I was calling them appropriately&amp;#8230;&lt;/p&gt;


	&lt;h2&gt;&lt;em&gt;Mockism&lt;/em&gt;&lt;/h2&gt;


	&lt;p&gt;That last bit is pretty important.  Some time ago Martin Fowler wrote a &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html#SoShouldIBeAClassicistOrAMockist"&gt;blog&lt;/a&gt; about the &lt;em&gt;Mockist&lt;/em&gt; and &lt;em&gt;Classical&lt;/em&gt; style of &lt;span class="caps"&gt;TDD&lt;/span&gt;.  In short, &lt;em&gt;Mockists&lt;/em&gt; don&amp;#8217;t test the behavior of the system so much as they test that their classes &amp;#8220;dance&amp;#8221; well with other classes.  That is, they mock/stub out all the other classes that the class under test uses, and then make sure that all the right functions are called in all the right orders with all the right arguments. etc.  There is value to doing this in many cases.  However you can get pretty badly carried away with the approach.&lt;/p&gt;


	&lt;p&gt;The classical approach is to test for desired behavior, and trust that if the test passes, then the class being tested must be dancing well with its partners.&lt;/p&gt;


	&lt;p&gt;Personally, I don&amp;#8217;t belong to either camp.  I sometimes test the choreography, and I sometimes test the behavior.  I test the choreography when I am trying to isolate one part of the system from another.  I test for the behavior when such isolation is not important to me.&lt;/p&gt;


	&lt;p&gt;The point of all this is that I have observed that a heavy dependence on mocking frameworks tends to tempt you towards testing the dance when you &lt;em&gt;should&lt;/em&gt; be testing behavior.  Tools can drive the way we think.  So remember, &lt;em&gt;you&lt;/em&gt; dominate the tool; don&amp;#8217;t let the tool dominate you!&lt;/p&gt;


	&lt;h2&gt;But aren&amp;#8217;t hand-rolled mocks fragile?&lt;/h2&gt;


	&lt;p&gt;Yes, they can be.  If you are mocking a class or interface that it very volatile (i.e. you are adding new methods, or modifying method signatures a lot) then you&amp;#8217;ll have to go back and maintain all your hand-rolled mocks every time you make such a change.  On the other hand, if you use a mocking framework, the framework will take care of that for you unless one of the methods you are specifically testing is modified.&lt;/p&gt;


	&lt;p&gt;But here&amp;#8217;s the thing.  Interfaces should not usually be volatile.  They should not continue to grow and grow, and the methods should not change much.  OK, I realize that&amp;#8217;s wishful thinking.  But, &lt;em&gt;yes&lt;/em&gt;, I wish for the kind of a design in which interfaces are the &lt;em&gt;least&lt;/em&gt; volatile source files that you have.  That&amp;#8217;s kind of the point of interfaces after all&amp;#8230;  You create interfaces so that you can separate volatile implementations from non-volatile clients.  (Or at least that&amp;#8217;s one reason.)&lt;/p&gt;


	&lt;p&gt;So if you are tempted to use a mocking framework because you don&amp;#8217;t want to maintain your volatile interfaces, perhaps you should be asking yourself the more pertinent question about why your interfaces are so volatile.&lt;/p&gt;


	&lt;p&gt;Still, if you&amp;#8217;ve got volatile interfaces, and there&amp;#8217;s just no way around it, then a mocking framework may be the right choice for you.&lt;/p&gt;


	&lt;h2&gt;So here&amp;#8217;s the bottom line.&lt;/h2&gt;


	&lt;ul&gt;
	&lt;li&gt;It&amp;#8217;s easy to roll your own stubs and mocks. Your &lt;span class="caps"&gt;IDE&lt;/span&gt; will help you and they&amp;#8217;ll be easier and more natural to read than the dots and parentheses that the mocking frameworks impose upon you.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Mocking frameworks drive you towards testing choreography rather than behavior.  This can be useful, but it&amp;#8217;s not always appropriate.  And besides, even when you are testing choreography, the hand-rolled stubs and mocks are probably easier to write and read.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;There are special cases where mocking tools are &lt;em&gt;invaluable&lt;/em&gt;, specifically when you have to test choreography with objects that you have no source for or when your design has left you with a plethora of volatile interfaces.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Am I telling you to avoid using mocking frameworks?  No, not at all.  I&amp;#8217;m just telling you that &lt;em&gt;you&lt;/em&gt; should drive tools, tools should not drive you.&lt;/p&gt;


	&lt;p&gt;If you have a situation where a mocking tool is the right choice, by all means use it.   But don&amp;#8217;t use it because you think it&amp;#8217;s &amp;#8220;agile&amp;#8221;, or because you think it&amp;#8217;s &amp;#8220;right&amp;#8221; or because you somehow think you are supposed to.  And remember, hand-rolling often results in simpler tests without the litter of dots and parentheses!&lt;/p&gt;</description>
      <pubDate>Wed, 28 Oct 2009 18:12:16 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:55f13a22-2823-4ae4-bd47-d32a1759e267</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/10/28/manual-mocking-resisting-the-invasion-of-dots-and-parentheses</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Agile Methods</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>C++ Bowling Kata Result</title>
      <description>&lt;p&gt;I&amp;#8217;m teaching a &lt;span class="caps"&gt;TDD&lt;/span&gt; and Refactoring class this week using C&amp;#43;&amp;#43;. Since I had not recently wrote the bowling kata in C&amp;#43;&amp;#43;, I figured it was about time to do it again.&lt;/p&gt;


	&lt;p&gt;Unlike the previous Scala version, this one only addresses the happy-path. I do not consider throwing too many balls or scoring too many pins in any frame. However, having just written this in Scala, I&amp;#8217;m sure I could do something similar in C&amp;#43;&amp;#43;.&lt;/p&gt;


	&lt;p&gt;I just switched to &lt;a href="http://sourceforge.net/projects/cpputest/"&gt;CppUTest 2.0&lt;/a&gt; and something I noticed is that if you use &amp;lt;vector&amp;gt; or other std-based classes, you need to make sure to include those first before including &amp;lt;CppUTest/TestHarness.h&amp;gt;. This is because CppUTest overloads new and delete, which causes havoc with the std-based classes. No big deal, I just made sure to include that file as the last header (rather than the first, which is what I used to do).&lt;/p&gt;


Here are the various files:
&lt;p/&gt;&lt;b&gt;&lt;i&gt;RunAllTests.cpp&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;table class="typocode_linenumber"&gt;&lt;tr&gt;&lt;td class="lineno"&gt;
&lt;pre&gt;
1
2
3
4
5
&lt;/pre&gt;
&lt;/td&gt;&lt;td width="100%"&gt;&lt;pre&gt;&lt;code class="typocode_cpp "&gt;#include &amp;lt;CppUTest/CommandLineTestRunner.h&amp;gt;

int main(int argc, char** argv) {
  CommandLineTestRunner::RunAllTests(argc, argv);
}&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p/&gt;&lt;b&gt;&lt;i&gt;BowlingScoreCardTest.cpp&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;table class="typocode_linenumber"&gt;&lt;tr&gt;&lt;td class="lineno"&gt;
&lt;pre&gt;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
&lt;/pre&gt;
&lt;/td&gt;&lt;td width="100%"&gt;&lt;pre&gt;&lt;code class="typocode_cpp "&gt;#include &amp;quot;BowlingScoreCard.h&amp;quot;

#include &amp;lt;CppUTest/TestHarness.h&amp;gt;

TEST_GROUP(BowlingScoreCard) {
  BowlingScoreCard* card;

  TEST_SETUP() {
    card = new BowlingScoreCard;
  }

  TEST_TEARDOWN() {
    delete card;
  }

  void throwOne(int value) {
      card-&amp;gt;recordThrow(value);
  }

  void throwMany(int rolls, int value) {
    for(int i = 0; i &amp;lt; rolls; ++i)
      throwOne(value);
  }

  void confirmScoreIs(int expected) {
    LONGS_EQUAL(expected, card-&amp;gt;score());
  }
};

TEST(BowlingScoreCard, noRollsGame) {
  confirmScoreIs(0);
}

TEST(BowlingScoreCard, throwAll0s) {
  throwMany(20, 0);
  confirmScoreIs(0);
}

TEST(BowlingScoreCard, throwAll1s) {
  throwMany(20, 1);
  confirmScoreIs(20);
}

TEST(BowlingScoreCard, throwOneSpare) {
  throwOne(7);
  throwOne(3);
  throwOne(6);
  throwMany(17, 0);
  confirmScoreIs(22);
}

TEST(BowlingScoreCard, all5sthrown) {
  throwMany(21, 5);
  confirmScoreIs(150);
}

TEST(BowlingScoreCard, throwOneStrike) {
  throwOne(10);
  throwOne(4);
  throwOne(3);
  confirmScoreIs(24);
}

TEST(BowlingScoreCard, perfectGame) {
  throwMany(12, 10);
  confirmScoreIs(300);
}

TEST(BowlingScoreCard, dutch200StrikeSpare) {
  for(int i = 0; i &amp;lt; 10; ++i) {
    throwOne(10);
    throwMany(2, 5);
  }
  throwOne(10);
  confirmScoreIs(200);
}

TEST(BowlingScoreCard, dutch200SpareStrike) {
  for(int i = 0; i &amp;lt; 10; ++i) {
    throwMany(2, 5);
    throwOne(10);
  }
  throwMany(2, 5);
  confirmScoreIs(200);
}&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p/&gt;&lt;b&gt;&lt;i&gt;BowlingScoreCard.h&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;table class="typocode_linenumber"&gt;&lt;tr&gt;&lt;td class="lineno"&gt;
&lt;pre&gt;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
&lt;/pre&gt;
&lt;/td&gt;&lt;td width="100%"&gt;&lt;pre&gt;&lt;code class="typocode_cpp "&gt;#pragma once

#ifndef BOWLING_SCORE_CARD_H
#define BOWLING_SCORE_CARD_H

#include &amp;lt;vector&amp;gt;
using namespace std;

class BowlingScoreCard
{
public:
  enum { Frames = 10, Mark = 10 };

  BowlingScoreCard();
  virtual ~BowlingScoreCard();
  int score();
  void recordThrow(int roll);

private:
  typedef vector&amp;lt;int&amp;gt; v_int;
  typedef v_int::size_type size_type;

  int scoreFrameAt(size_type index);
  int nextTwoRollsSummed(size_type index);
  int scoreAt(size_type index);
  int frameSizeAt(size_type index);
  bool isStrikeAt(size_type index);
  bool isSpareAt(size_type index);
  int scoreStrikeAt(size_type index);
  int scoreSpareAt(size_type index);

  v_int rolls;
};

#endif&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p/&gt;&lt;b&gt;&lt;i&gt;BowlingScoreCard.cpp&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;table class="typocode_linenumber"&gt;&lt;tr&gt;&lt;td class="lineno"&gt;
&lt;pre&gt;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
&lt;/pre&gt;
&lt;/td&gt;&lt;td width="100%"&gt;&lt;pre&gt;&lt;code class="typocode_cpp "&gt;#include &amp;quot;BowlingScoreCard.h&amp;quot;

BowlingScoreCard::BowlingScoreCard() {
}

BowlingScoreCard::~BowlingScoreCard() {
}

int BowlingScoreCard::score() {
  int score = 0;

  for(int index = 0, frame = 0; frame &amp;lt; Frames; ++frame) {
    score += scoreFrameAt(index);
    index += frameSizeAt(index);
  }

  return score;
}

int BowlingScoreCard::scoreFrameAt(size_type index) {
  if(isStrikeAt(index))
    return scoreStrikeAt(index);
  else if(isSpareAt(index))
    return scoreSpareAt(index);

  return nextTwoRollsSummed(index);
}

bool BowlingScoreCard::isStrikeAt(size_type index) {
  return scoreAt(index) == Mark;
}

bool BowlingScoreCard::isSpareAt(size_type index) {
  return !isStrikeAt(index) &amp;amp;&amp;amp; nextTwoRollsSummed(index) == Mark;
}

int BowlingScoreCard::scoreStrikeAt(size_type index) {
  return Mark + nextTwoRollsSummed(index + 1);
}

int BowlingScoreCard::scoreSpareAt(size_type index) {
  return Mark + scoreAt(index + 2);
}

int BowlingScoreCard::frameSizeAt(size_type index) {
  if(scoreAt(index) == Mark)
    return 1;
  return 2;
}

int BowlingScoreCard::nextTwoRollsSummed(size_type index) {
  return scoreAt(index) + scoreAt(index + 1);
}

int BowlingScoreCard::scoreAt(size_type index) {
  return index &amp;lt; rolls.size() ? rolls[index] : 0;
}

void BowlingScoreCard::recordThrow(int roll) {
  rolls.push_back(roll);
}&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

	&lt;p&gt;I sure do miss refactoring tools!-)&lt;/p&gt;</description>
      <pubDate>Tue, 27 Oct 2009 15:37:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:21e94a12-259b-4c2d-968b-7b8cea58c877</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/10/27/c-bowling-kata-result</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>c</category>
      <category>kata</category>
      <category>bowling</category>
      <category>TDD</category>
    </item>
    <item>
      <title>We must ship now and deal with consequences</title>
      <description>&lt;p&gt;Martin Fowler has written a good &lt;a href="http://martinfowler.com/bliki/TechnicalDebtQuadrant.html"&gt;blog&lt;/a&gt; about technical debt.  He suggests that there are two axes of debt: &lt;em&gt;deliberate&lt;/em&gt; and &lt;em&gt;prudent&lt;/em&gt;.  This creates four quadrants: &lt;em&gt;deliberate-prudent&lt;/em&gt;, &lt;em&gt;deliberate-imprudent&lt;/em&gt;, &lt;em&gt;inadvertent-prudent&lt;/em&gt;, and &lt;em&gt;inadvertent-imprudent&lt;/em&gt;.  I agree with just about everything in his blog except for one particular caption&amp;#8230;&lt;/p&gt;


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


	&lt;p&gt;Remember: &lt;em&gt;Murphy shall send you strong delusion, that you should believe you are in DP; so that you will be damned in DI.&lt;/em&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 15 Oct 2009 06:17:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:169be751-1a4f-45b8-8429-9eb3820be4a3</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/10/15/we-must-ship-now-and-deal-with-consequences</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Agile Methods</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>TDD Triage</title>
      <description>&lt;p&gt;With all controversy that has been generated buy my last two blogs (&lt;a href="http://blog.objectmentor.com/articles/2009/10/06/echoes-from-the-stone-age"&gt;1&lt;/a&gt;, &lt;a href="http://blog.objectmentor.com/articles/2009/10/07/tdd-derangement-syndrome"&gt;2&lt;/a&gt;), I thought it would be wise to talk bout where &lt;span class="caps"&gt;TDD&lt;/span&gt; works and where it doesn&amp;#8217;t&lt;/p&gt;


	&lt;h2&gt;Is &lt;span class="caps"&gt;TDD&lt;/span&gt; a replacement for architecture?&lt;/h2&gt;


	&lt;p&gt;No, of course not.  The notion that you can generate a viable architecture by starting with a blank screen and then writing one test case after the other is sheer folderol.  There are decisions that you need to make that have nothing to do with tests.&lt;/p&gt;


	&lt;p&gt;Of course many of these decisions can, and should, be deferred for as long as possible.  For example, the database schema is something that can likely wait for quite a long time.  The decision to use Spring, &lt;span class="caps"&gt;JSF&lt;/span&gt;, Hibernate, &lt;span class="caps"&gt;JPA&lt;/span&gt;, etc. can also likely wait.  The beauty of business rules is that they can, and should, be implemented independently of database and &lt;span class="caps"&gt;GUI&lt;/span&gt; models.&lt;/p&gt;


	&lt;p&gt;In FitNesse, we deferred the database decision as long as possible.  In the end we deferred it &lt;em&gt;indefinitely&lt;/em&gt; and used flat files instead.  At the beginning we did not think flat files would be the solution, we thought we&amp;#8217;d be using mysql.  But we kept on postponing that decision, and making our test cases pass.  Finally, one of the stubs we&amp;#8217;d been using to save fitnesse pages into flat files proved to be good enough.&lt;/p&gt;


	&lt;p&gt;Interestingly enough, one year later a user of FitNesse needed it to use mysql (because of corporate bureaucracy).  It took him a day to make the changes.  The architecture of FitNesse was so flexible, because of all the tests and stubbing, that shimming mysql in at the very end was trivial.&lt;/p&gt;


	&lt;p&gt;On the other hand, some architectural decisions need to be made early.  For example you really do need to choose your programming language pretty early on.  You also probably need to know whether you will be working in a web (batch) environment, or using a more intimate user interface.  If you are in an enterprise environment, you&amp;#8217;ll need to understand the existing database and plan how you will isolate your application from it.&lt;/p&gt;


	&lt;p&gt;When we started FitNesse, we made a very early architectural decision that has had a profound impact on the structure of the system.  That decision was named &amp;#8220;Download and go.&amp;#8221;  Before the first line of code was written we decided that FitNesse should not be bound to any other independent system, that you should be able to download it, and then execute it with a single command.  In 2001 this meant we had to write our own web server&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s the bottom line.  You cannot derive a complete architecture with &lt;span class="caps"&gt;TDD&lt;/span&gt;.  &lt;span class="caps"&gt;TDD&lt;/span&gt; can inform &lt;em&gt;some&lt;/em&gt; of your architectural decisions, but you cannot begin a project without an architectural vision.  So some up front architecture is necessary.  One of the most important up front architectural activities is deciding which architectural elements can be deferred and which cannot.&lt;/p&gt;


	&lt;h2&gt;Is &lt;span class="caps"&gt;TDD&lt;/span&gt; a replacement for design?&lt;/h2&gt;


	&lt;p&gt;No.  You still need &lt;em&gt;all&lt;/em&gt; your design skills.  You still need to know design principles, and design patterns.  You should know &lt;span class="caps"&gt;UML&lt;/span&gt;.  And, yes, you should create lightweight models of your proposed software designs.&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;TDD&lt;/span&gt;&amp;#8217;s role is to &lt;em&gt;inform&lt;/em&gt; your design decisions, not to replace them.  The &lt;a href="http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata"&gt;Bowling Game Kata&lt;/a&gt; is an example of how &lt;span class="caps"&gt;TDD&lt;/span&gt; can &lt;em&gt;utterly invalidate&lt;/em&gt; early design decisions; but the Bowling Game is an extreme case.  Usually &lt;span class="caps"&gt;TDD&lt;/span&gt; works to &lt;em&gt;validate&lt;/em&gt;, and/or &lt;em&gt;augment&lt;/em&gt; your design decisions.&lt;/p&gt;


	&lt;p&gt;A team of developers needs to have a design vision that they have agreed upon.  This vision can often be gained with a relatively short design session at the beginning of each iteration.  &lt;span class="caps"&gt;UML&lt;/span&gt; models can be proposed and negotiated on a white board.  This gives everyone the context required to make progress without stepping all over each other.&lt;/p&gt;


	&lt;p&gt;However, the models should not be considered law.  They are nothing more than an initial rough draft of the design.  As the teams practice &lt;span class="caps"&gt;TDD&lt;/span&gt;, they will undoubtedly discover weaknesses in the designs, and uncover better solutions. These improvements should be quickly communicated to the rest of the team.&lt;/p&gt;


	&lt;p&gt;The bottom line is that &lt;span class="caps"&gt;TDD&lt;/span&gt; is &lt;em&gt;a_ design technique but should not be the _sole&lt;/em&gt; design technique.  All the old design rules and skills still apply; and &lt;span class="caps"&gt;TDD&lt;/span&gt; is a powerful way to inform and augment them.&lt;/p&gt;


	&lt;h2&gt;Should &lt;span class="caps"&gt;TDD&lt;/span&gt; be used for every line of code?&lt;/h2&gt;


	&lt;p&gt;No.  There is a set of problems for which &lt;span class="caps"&gt;TDD&lt;/span&gt; is not particularly helpful.  GUIs are an example.&lt;/p&gt;


	&lt;p&gt;In FitNesse, for example, we use Velocity templates to create our web pages.  There is a lot of coding that goes into a Velocity template.  But to use &lt;span class="caps"&gt;TDD&lt;/span&gt; for those templates would be absurd.  The problem is that I&amp;#8217;m not at all sure what I want a page to look like.  I need the freedom to &lt;em&gt;fiddle&lt;/em&gt; around with the formatting and the structure until everything is just the way I want it.  Trying to do that &lt;em&gt;fiddling&lt;/em&gt; with &lt;span class="caps"&gt;TDD&lt;/span&gt; is futile.  Once I have the page the way I like it, &lt;em&gt;then&lt;/em&gt; I&amp;#8217;ll write some tests that make sure the templates work as written.&lt;/p&gt;


	&lt;p&gt;Of course it&amp;#8217;s not just GUIs.  It is the notion of &lt;em&gt;fiddling&lt;/em&gt; that is the key.  If you must &lt;em&gt;massage&lt;/em&gt; the code into place.  If you must &lt;em&gt;fiddle&lt;/em&gt; with some aspect in order to please the customer.  If there is some &lt;em&gt;uncertainty&lt;/em&gt; that can only be resolved by a very rapid cycle of edit-and-run, then &lt;span class="caps"&gt;TDD&lt;/span&gt; is likely to be more of a hindrance than a help.&lt;/p&gt;


	&lt;p&gt;As another example, I once worked with a trading company that had to parse incoming streams of trading data.  These streams did not have a well defined format.  The teams had to fiddle with regular expressions and parsers in order to get the decoding just right.  TDDing this would not have been wise.  Writing the tests afterwards was imperative.&lt;/p&gt;


	&lt;p&gt;The trick to manage this is &lt;em&gt;intense&lt;/em&gt; decoupling.  You want to make sure you identify every bit of the code that does not need to be &lt;em&gt;fiddled&lt;/em&gt;, and separate that code into modules that you can write with &lt;span class="caps"&gt;TDD&lt;/span&gt;.  Make sure that the &lt;em&gt;fiddled&lt;/em&gt; code is isolated and kept to a bare minimum.&lt;/p&gt;


	&lt;p&gt;For example, the Velocity templates in FitNesse draw their data from data structures that are built by the business rule processes (we call them Responders).  I relentlessly use &lt;span class="caps"&gt;TDD&lt;/span&gt; to make sure those data structures are right.  So when I &lt;em&gt;fiddle&lt;/em&gt; with the templates, at least I&amp;#8217;m not &lt;em&gt;fiddling&lt;/em&gt; with the code that generates the data for those templates.&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;NOTE&lt;/span&gt;!  Just because GUIs need to be &lt;em&gt;fiddled&lt;/em&gt; with, does not mean that most of the code around the &lt;span class="caps"&gt;GUI&lt;/span&gt; should not be &lt;span class="caps"&gt;TDD&lt;/span&gt;&amp;#8217;d.  In fact, most of that code &lt;em&gt;should&lt;/em&gt; be &lt;span class="caps"&gt;TDD&lt;/span&gt;&amp;#8217;d.  It&amp;#8217;s just the tiny thin veneer of code that controls the format that needs to be &lt;em&gt;fiddled&lt;/em&gt;.  All code that can and should be &lt;span class="caps"&gt;TDD&lt;/span&gt;&amp;#8217;d should be decoupled from that veneer.  So, decouple, decouple, decouple, and then finally &lt;em&gt;fiddle&lt;/em&gt;.&lt;/p&gt;


	&lt;h2&gt;Well, if you are going to write &lt;em&gt;some&lt;/em&gt; tests afterwards, why not write &lt;em&gt;all&lt;/em&gt; tests afterwards?&lt;/h2&gt;


	&lt;p&gt;Well, first, there&amp;#8217;s the &lt;a href="http://www.google.com/url?sa=t&amp;#38;source=web&amp;#38;ct=res&amp;#38;cd=1&amp;#38;url=http%3A%2F%2Fcollaboration.csc.ncsu.edu%2Flaurie%2FPapers%2FTDDpaperv8.pdf&amp;#38;ei=WoTMSvSXMYSqtgfDnMjrAQ&amp;#38;usg=AFQjCNHk6TJnNC32UGD8cN65EWGjoQkTBA&amp;#38;sig2=pbzOxiSB7_HAOoBTyDqetQ"&gt;George-Williams&lt;/a&gt; study, which showed that teams who are instructed to write tests afterwards, don&amp;#8217;t write tests at all.  Of course this is human nature.  Once you have the code &amp;#8220;working&amp;#8221; why write tests?  Writing tests for code that you believe works feels like a waste of time.&lt;/p&gt;


	&lt;p&gt;But that can be countered with sheer discipline.  The real reason to follow &lt;a href="http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd"&gt;The Three Laws of &lt;span class="caps"&gt;TDD&lt;/span&gt;&lt;/a&gt; and write your tests first is that it greatly enhances the chances that every line and every decision is tested.&lt;/p&gt;


	&lt;p&gt;Code coverage is a sneaky metric.  It is quite possible to create extremely high levels of coverage without a single assert.  I don&amp;#8217;t need to tell you that coverage without asserts is less than meaningful.  When you write tests first, your assertion coverage is very high.  When you write tests after, you assertion coverage simply cannot be that high.  Even the most dedicated and determined developer will make some coding decisions that block later testability.  When you write the tests first, this simply cannot happen.  When you write the tests first every coding decision you make &lt;em&gt;must&lt;/em&gt; support testability.&lt;/p&gt;


	&lt;p&gt;Clearly writing the tests first forces an extremely high degree of compatibility between the tests and the code.  Writing the tests first also means that your first thoughts about the code are from the point of view of a user, not an author; and that also has benefits.&lt;/p&gt;


	&lt;p&gt;So, &lt;em&gt;all else being equal&lt;/em&gt;, test-first is clearly better than test-after.&lt;/p&gt;


	&lt;h2&gt;Given that we accept the need for tests, why the resistance to test-first?&lt;/h2&gt;


	&lt;p&gt;Honestly, I don&amp;#8217;t know.  Clearly it can&amp;#8217;t be a productivity issue since we are going to write the tests anyway.&lt;/p&gt;


	&lt;p&gt;Perhaps some people don&amp;#8217;t like the fact that writing tests first interrupts the flow.  It&amp;#8217;s true, when you write tests first, you cannot write a whole algorithm.  You have to assemble that algorithm bit by bit as you add one test case after another.  Maybe some people just don&amp;#8217;t feel comfortable working this way.  Personally, I find working this way to be highly beneficial.  It&amp;#8217;s a way for me to think &lt;em&gt;critically&lt;/em&gt; about the code I am writing.  But I accept that some folks may find it difficult.&lt;/p&gt;


	&lt;p&gt;I once worked with an assembly language programmer who simply could not understand pointers.  No matter how hard I tried to explain them, he simply could not grasp the concept.   This made it hard for him to write certain kinds of programs.  I fear that the folks who cannot train their brains to think in a test-first way are working at a similar kind of disadvantage, though not nearly so severe.&lt;/p&gt;


	&lt;h2&gt;Wouldn&amp;#8217;t it be faster without such high test coverage?&lt;/h2&gt;


	&lt;p&gt;I&amp;#8217;ll paraphrase Kent Beck once again.  &amp;#8220;If I don&amp;#8217;t need to make it work, I can go a &lt;em&gt;lot&lt;/em&gt; faster.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;I once consulted for a team that followed this rule.  For them, the definition of &amp;#8220;Done&amp;#8221; was &amp;#8220;checked in&amp;#8221;.  If the checked in code had bugs, then fixing those bugs went on a different schedule.  Eventually the team started checking in empty source files in order to be &amp;#8220;done&amp;#8221; on time.&lt;/p&gt;


	&lt;p&gt;But let&amp;#8217;s take the original question seriously.  Do we really need to have close to 100% automated test coverage?  Doesn&amp;#8217;t the insistence on such a high level of coverage slow the development team down?&lt;/p&gt;


	&lt;p&gt;In a legacy environment it certainly does.  Indeed, in a legacy environment I would not insist on high test coverage at first.  I&amp;#8217;d set the goal pretty low, and then gradually ramp it up over a period of months to years.&lt;/p&gt;


	&lt;p&gt;Legacy code (defined by Michael Feathers as: code without tests) is a big problem.  Getting that code under automated test is a difficult and long-term activity.  The pay-off is huge, but you can&amp;#8217;t get there quickly.&lt;/p&gt;


	&lt;p&gt;In a non-legacy environment, and for all new code &lt;em&gt;within&lt;/em&gt; a legacy environment the situation is different.  High coverage with automated tests speeds you up; and it speeds you up a lot.&lt;/p&gt;


	&lt;p&gt;The reason isn&amp;#8217;t difficult to understand.  Firstly, you don&amp;#8217;t do much debugging.  How could you if you have tested virtually every line of code?  My own experience with debug time is that it all but disappears.  In the last year of intense development effort on FitNesse &lt;em&gt;I have spent almost no time debugging.&lt;/em&gt;  If I had to quantify that time, I&amp;#8217;d put it at 5 hours or less.&lt;/p&gt;


	&lt;p&gt;Secondly, I simply cannot inadvertently break the code.  The test suite finds such breakage within seconds!  And this makes me &lt;em&gt;fearless&lt;/em&gt;.  When you are &lt;em&gt;fearless&lt;/em&gt;, you can go a &lt;em&gt;lot faster&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Thirdly, My tests are little examples of how to work the system.  Whenever I forget how some part of the system works, I read the tests.  They quickly get me back up to speed.&lt;/p&gt;


	&lt;p&gt;Fourthly, I&amp;#8217;m not fighting a continuous barrage of bugs from the field.  Even though I have thousands of users, my bug list is tiny.  The time I spend in support is less than an hour a week, and usually that&amp;#8217;s just pointing people at the right spot in the user guide.&lt;/p&gt;


	&lt;p&gt;So to counter Kent Beck&amp;#8217;s quote above:  &amp;#8220;When your code &lt;em&gt;works&lt;/em&gt; you can go a &lt;em&gt;lot&lt;/em&gt; faster.&amp;#8221;&lt;/p&gt;


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


	&lt;p&gt;I&amp;#8217;m quite sure this blog will not quell the controversy.  I expect that those folks who consistently berate &lt;span class="caps"&gt;TDD&lt;/span&gt; will continue to do so.  But perhaps those who have &lt;em&gt;honest&lt;/em&gt; doubts will find this blog useful, or even convincing.&lt;/p&gt;</description>
      <pubDate>Thu, 08 Oct 2009 09:52:41 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:c0b1024c-cddc-49df-b72a-41eda9bf571b</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/10/08/tdd-triage</link>
    </item>
    <item>
      <title>TDD Derangement Syndrome</title>
      <description>&lt;p&gt;My recent blog about &lt;span class="caps"&gt;TDD&lt;/span&gt;, Design Patterns, Concurrency, and Sudoku seemed to draw the ire of a few vocal &lt;span class="caps"&gt;TDD&lt;/span&gt; detractors.  Some of these people were rude, insulting, derisive, dismissive, and immature.  Well, Halloween is not too far away.&lt;/p&gt;


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


	&lt;p&gt;Are there others?  I&amp;#8217;m sure there are.  This was just a quick web search.  
Again, if you know of more, please add a comment.&lt;/p&gt;</description>
      <pubDate>Wed, 07 Oct 2009 08:32:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:31f3a32e-467c-4c54-9ec8-3b63fe961ff1</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/10/07/tdd-derangement-syndrome</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Agile Methods</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>Scala Bowling Kata - still in the middle I suppose</title>
      <description>I had a 3.5 hour flight today. I realized I was missing some of the validation from the Ruby version related to how many rolls a valid game should allow:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_scala "&gt;  &amp;quot;One more roll on a game with 20 rolls and an open 10th frame&amp;quot; should {
    20 times { roll(1) }
    roll(1) must throwA[IllegalArgumentException]
  }

  &amp;quot;Two more rolls a game with 10 spares&amp;quot; should {
    10 times { spare }
    roll(1)
    roll(1) must throwA[IllegalArgumentException]
  }

  &amp;quot;Two marks in the 10th frame should&amp;quot; should {
    18 times { roll(1) }
    strike
    spare
    roll(1) must throwA[IllegalArgumentException]
  }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;On my flight from &lt;span class="caps"&gt;DFW&lt;/span&gt; to &lt;span class="caps"&gt;SNA&lt;/span&gt;, I got these behaviors implemented. The code was pretty ugly!&lt;/p&gt;


	&lt;p&gt;However, ugly code in hand, passing examples, a slight understanding of some of the problems with my code and a desire to make the BowlingScorer immutable was all I needed to make progress.&lt;/p&gt;


I removed the index instance field by rewriting the score method and injecting a tuple into foldLeft (written here using the short-hand notation /:):
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_scala "&gt;  def scoreAt(frame:Int) = 
    ((0,0) /: (1 to frame)) { (t, _) =&amp;gt;  
      (t._1 + scoreAtIndex(t._2), t._2 + incrementAt(t._2))
    }._1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

I had a mini state machine to track whether the first ball had been thrown yet or not. I replaced that by walking the list of scores:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;  def onFirstThrow = {
    var index = 0
    while(index &amp;lt; rolls.length)
      if(isStrike(index)) index += 1 else index += 2
    index == rolls.length
  }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;While I am happy I was able to remove the index variable, which was really a parameter being passed around in a field (ugly), I am not happy with this method.&lt;/p&gt;


I changed the roll method to return a new instance of a BowlingScorer, making the bowling scorer immutable:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_scala "&gt;  def roll(roll:Int) = {
    validate(roll)
    new BowlingScorer(rolls ++ Array(roll))
  }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;So I think I&amp;#8217;m still somewhere in the middle of working through this code. Again, I&amp;#8217;m still learning Scala. I have a lot to learn. I really only barely understand functional programming and, frankly, the Eclipse &lt;span class="caps"&gt;IDE&lt;/span&gt;, while functional, is getting in the way quite a bit. So for a toy example it is OK. Given the choice of this environment or vi and the command line, I&amp;#8217;d not pick the former. (I might give the other &lt;span class="caps"&gt;IDE&lt;/span&gt;&amp;#8217;s a go, but that&amp;#8217;s not really what I&amp;#8217;m interested in learning right now.)&lt;/p&gt;


	&lt;p&gt;So here&amp;#8217;s the next version. I plan to work through all of the comments I&amp;#8217;ve yet to process from the previous blog posting over the next few days. If you can recommend a better implementation of onFirstThrow, I&amp;#8217;d appreciate it.&lt;/p&gt;


	&lt;p&gt;Other general comments also welcome.&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;BowlingScorerExampleGroup.scala&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_scala "&gt;package com.om.example

import org.specs._

object BowlingScorerExampleGroup extends SpecificationWithJUnit {
  var scorer = new BowlingScorer(Nil);

  def roll(value:Int) =
    scorer = scorer.roll(value) 

  def haveAScoreOf(expected:Int) =
    scorer.score must_== expected

  def strike =
    roll(10)

  def spare {
    roll(5)
    roll(5)
  }

  implicit def intToDo(count: Int) = {
    new {
      def times(f: =&amp;gt; Unit) = {
        1 to count foreach { _ =&amp;gt; f }
      }
    }
  }

  &amp;quot;A Newly Created Bowling Scorer&amp;quot; should {
    haveAScoreOf(0)
  }

  &amp;quot;A game with all 0's&amp;quot; should {
    20 times { roll(0) }
    haveAScoreOf(0)
  }

  &amp;quot;A game with all 1's&amp;quot; should {
    20 times { roll(1) }
    haveAScoreOf(20)
  }

  &amp;quot;A game with a single spare followed by a 5&amp;quot; should {
    spare
    roll(5)
    haveAScoreOf(20)
  }

  &amp;quot;A game with all 5's&amp;quot; should {
    10 times { spare }
    roll(5)
    haveAScoreOf(150)
  }

  &amp;quot;A game with a single strike followed by a 4&amp;quot; should {
    strike
    roll(4)
    haveAScoreOf(18)
  }

  &amp;quot;A game with a strike, spare then an open frame with two 3's&amp;quot; should {
    strike
    spare
    2 times { roll(3) }
    haveAScoreOf(39)
  }

  &amp;quot;A game with strike, spare then an open frame with two 3's&amp;quot; should {
    spare
    strike
    2 times { roll(3) }
    haveAScoreOf(42)
  }

  &amp;quot;A Dutch 200 game, Spare-Strike&amp;quot; should {
    5 times {
      spare 
      strike
    }
    spare
    haveAScoreOf(200)
  }

  &amp;quot;A Dutch 200 game, Strike-Spare&amp;quot; should {
    5 times {
      strike
      spare 
    }
    strike
    haveAScoreOf(200)
  } 

  &amp;quot;A Perfect game&amp;quot; should {
    12 times { strike }
    haveAScoreOf(300)
  }

  &amp;quot;The score for each frame of a Perfect game, each frame&amp;quot; should {
    12 times { strike }
    1 to 10 foreach { frame =&amp;gt; scorer.scoreAt(frame) must_== 30 * frame }
  }

  &amp;quot;An individaul roll of &amp;gt; 10&amp;quot; should {
    roll(11) must throwA[IllegalArgumentException]
  }

  &amp;quot;An iniviaul roll of &amp;lt; 0&amp;quot; should {
    roll(-1) must throwA[IllegalArgumentException]
  }

  &amp;quot;A frame trying to contain more than 10 pins&amp;quot; should {
    roll(8)
    roll(3) must throwA[IllegalArgumentException]
  }

  &amp;quot;One more roll on a game with 20 rolls and an open 10th frame&amp;quot; should {
    20 times { roll(1) }
    roll(1) must throwA[IllegalArgumentException]
  }

  &amp;quot;Two more rolls a game with 10 spares&amp;quot; should {
    10 times { spare }
    roll(1)
    roll(1) must throwA[IllegalArgumentException]
  }

  &amp;quot;Two marks in the 10th frame should&amp;quot; should {
    18 times { roll(1) }
    strike
    spare
    roll(1) must throwA[IllegalArgumentException]
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;


	&lt;p&gt;&lt;b&gt;&lt;i&gt;BowlingScorer.scala&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_scala "&gt;package com.om.example

class BowlingScorer(rollsSoFar:List[Int]){
   val rolls:List[Int] = rollsSoFar

  def roll(roll:Int) = {
    validate(roll)
    new BowlingScorer(rolls ++ Array(roll))
  }

  def validate(roll:Int) {
    if(invalidRoll(roll))
      throw new IllegalArgumentException(&amp;quot;Individaul rolls must be from 0 .. 10&amp;quot;)

    if(frameRollTooHigh(roll))
      throw new IllegalArgumentException(&amp;quot;Total of rolls for frame must not exceed 10&amp;quot;);

    if(willBeTooManyRolls)
      throw new IllegalArgumentException(&amp;quot;Game over, no more rolls allowed&amp;quot;)
  }

  def invalidRoll(roll:Int) = 
    (0 to 10 contains(roll)) == false  

  def frameRollTooHigh(roll:Int) =
    openScoreAt(indexToValidate) + roll &amp;gt; 10

  def willBeTooManyRolls = 
    tenthRolled(indexOf10thFrame) &amp;amp;&amp;amp; nextRollTooMany(indexOf10thFrame)

  def tenthRolled(tenthIndex:Int) = 
    tenthIndex &amp;lt; rolls.length

  def nextRollTooMany(tenthIndex: Int) = 
    allowedTenthFrameRolls(tenthIndex) &amp;lt; rollsInTenthFrame(tenthIndex) + 1

  def indexOf10thFrame = 
    (0 /: (1 until 10)) {(c, _) =&amp;gt; c + incrementAt(c)}

  def allowedTenthFrameRolls(index:Int) =
    if(isMark(index)) 3 else 2

  def rollsInTenthFrame(index: Int) =
    rolls.length - index

  def indexToValidate =
    if(onFirstThrow) rolls.length else rolls.length - 1

  def onFirstThrow = {
    var index = 0
    while(index &amp;lt; rolls.length)
      if(isStrike(index)) index += 1 else index += 2
    index == rolls.length
  }

  def scoreAt(frame:Int) = 
    ((0,0) /: (1 to frame)) { (t, _) =&amp;gt;  
      (t._1 + scoreAtIndex(t._2), t._2 + incrementAt(t._2))
    }._1

  def score = scoreAt(10)

  def scoreAtIndex(index:Int) =
    if(isMark(index)) markScoreAt(index) else openScoreAt(index)

  def incrementAt(index:Int) =
    if(isStrike(index)) 1 else 2

  def isMark(index:Int) =
    isStrike(index) || isSpare(index)

  def isStrike(index:Int) =
    valueAt(index) == 10

  def markScoreAt(index:Int) =
    sumNext(index, 3)

  def isSpare(index:Int) =
    openScoreAt(index) == 10 &amp;amp;&amp;amp; valueAt(index) != 10

  def openScoreAt(index:Int) =
    sumNext(index, 2)

  def sumNext(index:Int, count:Int) =
    (0 /: (index until index+count))(_ + valueAt(_))

  def valueAt(index:Int) = 
    if(rolls.length &amp;gt; index) rolls(index) else 0
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</description>
      <pubDate>Wed, 07 Oct 2009 00:51:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:92053ad6-01f8-4086-abbe-55dd0e6088d9</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/10/07/scala-bowling-kata-still-in-the-middle-i-suppose</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>Scala</category>
      <category>bdd</category>
      <category>specs</category>
      <category>bowling</category>
      <category>kata</category>
    </item>
    <item>
      <title>Echoes from the Stone Age</title>
      <description>&lt;p&gt;The echoes from Joel Spolsky&amp;#8217;s &lt;a href="http://www.joelonsoftware.com/items/2009/09/23.html"&gt;Duct Tape blog&lt;/a&gt; continue to bounce off the blogosphere and twitterverse.  &lt;a href="http://www.tbray.org/ongoing/When/200x/2009/09/25/On-Duct-Tape"&gt;Tim Bray&lt;/a&gt; and &lt;a href="http://gigamonkeys.com/blog/2009/10/05/coders-unit-testing.html"&gt;Peter Seibel&lt;/a&gt; have both written responses to Joel, me, and each other.&lt;/p&gt;


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


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


	&lt;p&gt;Actually I think &lt;span class="caps"&gt;TDD&lt;/span&gt; is a good way to find out if an algorithm will self-assemble or not.  It usually doesn&amp;#8217;t take a lot of time to figure out which it&amp;#8217;s going to be.&lt;/p&gt;</description>
      <pubDate>Tue, 06 Oct 2009 11:07:29 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:1624b718-36a6-4521-aa4e-14d5b9623dc0</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/10/06/echoes-from-the-stone-age</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>Scala Bowling Kata - somewhere in the middle...</title>
      <description>I need to do some work with Scala to update our Concurrency in Java class. We want to demonstrate some other approaches to concurrency, e.g., Scala Actors (among others). I began by shaving yaks:
	&lt;ul&gt;
	&lt;li&gt;Installed the &lt;a href="http://www.scala-lang.org/node/94"&gt;Eclipse Scala Plugin&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Installed Scala using Mac Ports&lt;/li&gt;
		&lt;li&gt;Figured out how to get those things playing nice (the plugin page pretty much did that, but in a nutshell, add a few jar files to the classpath)&lt;/li&gt;
	&lt;/ul&gt;


Next, I wanted to use some &lt;span class="caps"&gt;BDD&lt;/span&gt; tool. I&amp;#8217;m going to try and stop using the term &lt;span class="caps"&gt;TDD&lt;/span&gt; simply because the T, which stands for Test in &lt;span class="caps"&gt;TDD&lt;/span&gt;, really means &amp;#8220;desired behavior&amp;#8221;. I considered calling it Trait Driven Development, but:
	&lt;ul&gt;
	&lt;li&gt;We don&amp;#8217;t need &lt;span class="caps"&gt;YADT&lt;/span&gt; &amp;#8211; Yet another damn term&lt;/li&gt;
		&lt;li&gt;Trait is a heavily overloaded word&lt;/li&gt;
		&lt;li&gt;I like the term &lt;span class="caps"&gt;BDD&lt;/span&gt; better and it fits.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Anyway, one such choice was &lt;a href="http://code.google.com/p/specs/"&gt;Specs&lt;/a&gt;, which is what I decided to use.&lt;/p&gt;


So back to yak shaving:
	&lt;ul&gt;
	&lt;li&gt;I added another jar to my classpath in Eclipse&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://code.google.com/p/specs/wiki/RunningSpecs#Run_your_specification_with_JUnit4_in_Eclipse"&gt;Then read how to get it running in Eclipse&lt;/a&gt;. Not too bad, I suppose.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;So now I need to learn Scala. Sure, I&amp;#8217;ve used it, but far less than Ruby. So it took me several hours to get specs running along with writing some Scala code to score a game &amp;#8211; I&amp;#8217;m glad I know the domain at least.&lt;/p&gt;


	&lt;p&gt;I wanted to make similar behaviors to the ones I wrote for the &lt;a href="http://blog.objectmentor.com/articles/2009/10/01/bowling-game-kata-in-ruby"&gt;Ruby version&lt;/a&gt;, which I did.&lt;/p&gt;


However, unlike the Ruby version, I was curious what would happen if I:
	&lt;ul&gt;
	&lt;li&gt;Took an approach similar to Uncle Bob &amp;#8211; strikes take one slot in an array&lt;/li&gt;
		&lt;li&gt;Added input validation&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;On the one hand, there are some interesting things I managed to create. On the other hand, I&amp;#8217;ve got a bit of a mess. I have a stateful object to avoid passing parameters so that I can write some of the code cleanly. I know I need to add in an intermediate computational object, and I&amp;#8217;m going to get to that. However, I wanted to get feedback on what I&amp;#8217;ve put out there so far.&lt;/p&gt;


Specifically, 
	&lt;ul&gt;
	&lt;li&gt;What do you think of the (bdd-style) examples from specc?&lt;/li&gt;
		&lt;li&gt;What is the correct way to write the Times(20).Do( ...) thing I came up with, there&lt;i&gt; &lt;b&gt;has&lt;/b&gt;&lt;/i&gt; be a better way? &lt;/li&gt;
		&lt;li&gt;For the part of the bowling scoring code that is not stateful (read this as, does not violate the &lt;span class="caps"&gt;SRP&lt;/span&gt;), what do you think of it?&lt;/li&gt;
		&lt;li&gt;How would you remove most/all of the state (other than the individual rolls) out of the Bowling scorer class? (Or would you choose to have the roll() method return a new instance of BowlingScorer with the new score recorded?)&lt;/li&gt;
		&lt;li&gt;Notice that the class maintains a mini state machine in the form of tracking whether the first ball of he current frame (not tracked) has or has not been thrown. That&amp;#8217;s only there to be able to perform input validation. I considered:
	&lt;ul&gt;
	&lt;li&gt;Walking the array&lt;/li&gt;
		&lt;li&gt;Going to 2 slots for every frame (making it easy to find the frame)&lt;/li&gt;
		&lt;li&gt;Storing a frame object (ok, I didn&amp;#8217;t really consider it, but I did think about it)&lt;/li&gt;
		&lt;li&gt;The mini state machine&lt;/li&gt;
	&lt;/ul&gt;
	&lt;/li&gt;
		&lt;li&gt;nextFrameScore uses the index instance variable, and changes it. This both violates command-query separation and demonstrates a violation of the &lt;span class="caps"&gt;SRP&lt;/span&gt;, but it made the scoreAt method look nice.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;An interesting side effect is that scoring marks (strikes and spares) uses the same approach, sum up three rolls total.&lt;/p&gt;


	&lt;p&gt;I know this needs work. What I&amp;#8217;ve got works according to its current specification (its examples), so in a sense, that&amp;#8217;s a good thing because I&amp;#8217;ve already stared experimenting with trying out different solutions. However, I am painfully aware of how unaware I am of Scala at the moment, so your (hopefully gentle) feedback will tell me what I need to learn next.&lt;/p&gt;


	&lt;p&gt;Looking forward to the virtual beating &amp;#8230;&lt;/p&gt;


	&lt;p&gt;Brett&lt;/p&gt;


Here are the two files I&amp;#8217;ve created so far (and to be clear, all of the examples pass):
&lt;p&gt;&lt;/p&gt;
&lt;b&gt;&lt;i&gt;BowlingScorerExampleGroup.scala&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_scala "&gt;package com.om.example

import org.specs._

object BowlingScorerExampleGroup extends SpecificationWithJUnit {
  var scorer = new BowlingScorer();

  def roll(value:Int) {
    scorer.roll(value) 
  }

  def rollMany(rolls:Int, value:Int) {
    0.until(rolls).foreach { arg =&amp;gt; scorer.roll(value) }
  }

  def haveAScoreOf(expected:Int) {
    scorer.score must_== expected
  }

  def strike {
    roll(10)
  }

  def spare {
    rollMany(2, 5) 
  }

  abstract class IDo {
    def Do(block: =&amp;gt; Unit) 
  }

  def Times(count:Int): IDo = {
    return new IDo {
      def Do(block: =&amp;gt; Unit) {
        1.to(count).foreach( arg =&amp;gt; block )
      }
    }
  }

  &amp;quot;A Newly Created Bowling Scorer&amp;quot; should {
    haveAScoreOf(0)
  }

  &amp;quot;A game with all 0's&amp;quot; should {
    Times(20).Do( roll(0) )
    haveAScoreOf(0)
  }

  &amp;quot;A game with all 1's&amp;quot; should {
    Times(20).Do { roll(1) }
    haveAScoreOf(20)
  }

  &amp;quot;A game with a single spare followed by a 5&amp;quot; should {
    spare
    roll(5)
    haveAScoreOf(20)
  }

  &amp;quot;A game with all 5's&amp;quot; should {
    Times(10).Do( spare ) 
    roll(5)
    haveAScoreOf(150)
  }

  &amp;quot;A game with a single strike followed by a 4&amp;quot; should {
    strike
    roll(4)
    haveAScoreOf(18)
  }

  &amp;quot;A game with a strike, spare then an open frame with two 3's&amp;quot; should {
    strike
    spare
    Times(2).Do( roll(3) )
    haveAScoreOf(39)
  }

  &amp;quot;A game with strike, spare then an open frame with two 3's&amp;quot; should {
    spare
    strike
    Times(2).Do( roll(3) )
    haveAScoreOf(42)
  }

  &amp;quot;A Dutch 200 game, Spare-Strike&amp;quot; should {
    Times(5).Do { 
      spare 
      strike
    }
    spare
    haveAScoreOf(200)
  }

  &amp;quot;A Dutch 200 game, Strike-Spare&amp;quot; should {
    Times(5).Do { 
      strike
      spare 
    }
    strike
    haveAScoreOf(200)
  } 

  &amp;quot;A Perfect game&amp;quot; should {
    Times(12).Do( strike ) 
    haveAScoreOf(300)
  }

  &amp;quot;The score for each frame of a Perfect game, each frame&amp;quot; should {
    Times(12).Do( strike ) 
    1.to(10).foreach{ frame =&amp;gt; scorer.scoreAt(frame) must_== 30 * frame }
  }

  &amp;quot;An individaul roll of &amp;gt; 10&amp;quot; should {
    roll(11) must throwA[IllegalArgumentException]
  }

  &amp;quot;An iniviaul roll of &amp;lt; 0&amp;quot; should {
    roll(-1) must throwA[IllegalArgumentException]
  }

  &amp;quot;A frame trying to contain more than 10 pins&amp;quot; should {
    roll(8)
    roll(3) must throwA[IllegalArgumentException]
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;&lt;b&gt;&lt;i&gt;BowlingScorer.scala&lt;/b&gt;&lt;/i&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_scala "&gt;package com.om.example

class BowlingScorer {
  var rolls:Array[Int] = Array()
  var index:Int = 0
  var firstBallInFrameThrown: Boolean = false;

  def roll(roll:Int) = {
    validate(roll)
    record(roll)
  }

  def validate(roll:Int) {
    if((0).to(10).contains(roll) == false)
      throw new IllegalArgumentException(&amp;quot;Individaul rolls must be from 0 .. 10&amp;quot;)

    if(openScoreAt(indexToValidate) + roll &amp;gt; 10)
      throw new IllegalArgumentException(&amp;quot;Total of rolls for frame must not exceed 10&amp;quot;);
  }

  def record(roll: Int) {
    rolls = rolls ++ Array(roll)
    firstBallInFrameThrown = firstBallInFrameThrown == false &amp;amp;&amp;amp; roll != 10
  }

  def indexToValidate = {
    if(firstBallInFrameThrown) rolls.length - 1 else rolls.length
  }

  def scoreAt(frame:Int) = {
    1.to(frame).foldLeft(0) { (total, frame) =&amp;gt;  total + nextFrameScore  }
  }

  def score = {
    scoreAt(10)
  }

  def nextFrameScore = {
    var result = 0;
    if(isStrike(index)) {
      result += markScoreAt(index)
      index += 1
    } else if(isSpare(index)) {
      result += markScoreAt(index);
      index += 2
    } else {
      result += openScoreAt(index);
      index += 2
    }
    result
  }

  def isStrike(index:Int) = {
    valueAt(index) == 10
  }

  def markScoreAt(index:Int) = {
    sumNext(index, 3)
  }

  def isSpare(index:Int) = {
    openScoreAt(index) == 10
  }

  def openScoreAt(index:Int) = {
    sumNext(index, 2)
  }

  def sumNext(index:Int, count:Int) = {
    index.until(index+count).foldLeft(0)(_ + valueAt(_))
  }

  def valueAt(index:Int) = {
    if(rolls.length &amp;gt; index) rolls.apply(index) else 0
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 05 Oct 2009 23:33:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:23cd72fc-e4b5-4dbd-b219-e4bb2e4b92c7</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/10/05/scala-bowling-kata-somewhere-in-the-middle</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>Scala</category>
      <category>bdd</category>
      <category>specs</category>
      <category>bowling</category>
      <category>kata</category>
    </item>
    <item>
      <title>Bowling Game Kata in Ruby</title>
      <description>&lt;p&gt;I have not really used Ruby much. I&amp;#8217;ve written a few tutorials, messed around with RSpec and Test::Unit and even Rails a bit, but I really don&amp;#8217;t know Ruby that well. I get Ruby (the &lt;span class="caps"&gt;MOP&lt;/span&gt;, instances, blocks, open classes, ...) but there&amp;#8217;s a difference between understanding that stuff and using it day-to-day.&lt;/p&gt;


	&lt;p&gt;Last night we had a Dojo in Oklahoma City and I wanted to get refreshed with RSpec, so I decided to jump in and do the bowling game kata. I did not follow uncle bob&amp;#8217;s lead exactly. For one, I went ahead and stored two throws for each frame. While what he ends up with is a bit shorter, it bothers me a little bit. I&amp;#8217;ve also seen people surprised by how bob stores his scores, so in a sense it violates the law of least astonishment.&lt;/p&gt;


	&lt;p&gt;That&amp;#8217;s neither here nor there, I got it working just fine &amp;#8211; though handling strikes was a bit more difficult because I decided to store two rolls instead of one (so clearly, there&amp;#8217;s no best answer, just ones that suck for different reasons).&lt;/p&gt;


	&lt;p&gt;After my first go around, I had a single spec with examples all under a single describe (what&amp;#8217;s that term they&amp;#8217;d use for what the describe expression creates?). I added several examples for partial scores, to make sure I was handling incomplete games correctly. I restructured those a bit and tried to make the names a bit more clear, not sure if I was successful.&lt;/p&gt;


	&lt;p&gt;In my original version I started with a frame in the score method as a local variable, but it quickly got converted to an index, and the index was mostly passed around after that. The approach was very c-esque. I didn&amp;#8217;t like that index all over the place, so I tried to remove it by refactoring. It took several false starts before I bit the bullet and simply duplicated each of the methods, one at a time, using parallel development. The old version using an index, the new one use a 1-based frame number. After I got that working with frames, I removed most of the methods using an index, except for a few.&lt;/p&gt;


	&lt;p&gt;What follows is the spec file and the ruby class. If you read the names of some of the examples, you might think I used to bowl in league, I did. My average was a paltry 158, my best game ever a 248. Best split I ever picked up? 4, 6, 7, 10.&lt;/p&gt;


	&lt;p&gt;Comments welcome.&lt;/p&gt;


	&lt;p&gt;&lt;i&gt;&lt;b&gt;bowling_score_card_spec.rb&lt;/i&gt;&lt;/b&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;bowling_score_card&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="ident"&gt;describe&lt;/span&gt; &lt;span class="constant"&gt;BowlingScoreCard&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;before&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:each&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
        &lt;span class="attribute"&gt;@bowling_game_scorer&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;BowlingScoreCard&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;roll&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;
        &lt;span class="attribute"&gt;@bowling_game_scorer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;roll_many&lt;/span&gt; &lt;span class="ident"&gt;count&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;
        &lt;span class="ident"&gt;count&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;score_should_be&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;
        &lt;span class="attribute"&gt;@bowling_game_scorer&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;score&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score 0&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
        &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="ident"&gt;describe&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Scores for Complete Games&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score 0 for an all gutter game&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;20&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should show 20 for an all 1 game&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;20&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;20&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score game with single spare correctly&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;17&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;20&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score game with single strike correctly&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;17&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;24&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score a dutch-200, spare-strike, correclty&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
                &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
                &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
            &lt;span class="keyword"&gt;end&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;

            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;200&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score a dutch-200, strike-spare, correctly&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
                &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
                &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
            &lt;span class="keyword"&gt;end&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;200&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;should score all 5's game as 150&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;21&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;150&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score a perfect game correctly&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;12&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;300&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should not count a 0, 10 roll as a strike&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;18&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;29&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="ident"&gt;describe&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Scoring for open games&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score just an open frame&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;4&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;7&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score just a spare&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score partial game with spare and following frame only&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;20&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score an opening turkey correctly&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll_many&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;60&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="ident"&gt;describe&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Scoring open game starting with a srike&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
        &lt;span class="ident"&gt;before&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:each&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;
        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score partial game with only strike&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score partial game with strike and half-open frame&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;4&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;18&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score partial game with strike and open frame&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;6&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;28&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score partial game with strike and spare&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;7&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;30&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="ident"&gt;describe&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Open game starting with two Strikes&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
        &lt;span class="ident"&gt;before&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:each&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should have a score of 30&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;30&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score correctly with following non-mark&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;4&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;42&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;

        &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;should score correclty with third frame open&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;4&lt;/span&gt;
            &lt;span class="ident"&gt;roll&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;
            &lt;span class="ident"&gt;score_should_be&lt;/span&gt; &lt;span class="number"&gt;48&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;


	&lt;p&gt;&lt;i&gt;&lt;b&gt;bowling_score_card.rb&lt;/i&gt;&lt;/b&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;BowlingScoreCard&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;
        &lt;span class="attribute"&gt;@rolls&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;roll&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;
        &lt;span class="attribute"&gt;@rolls&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;
        &lt;span class="attribute"&gt;@rolls&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;first_throw_is_strike?&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;score&lt;/span&gt;
        &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;..&lt;/span&gt;&lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;inject&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;score&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;score&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;strike_score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;is_strike_at?&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;spare_score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;is_spare_at?&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;open_score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;first_throw_is_strike?&lt;/span&gt;
        &lt;span class="ident"&gt;is_first_throw_in_frame?&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="attribute"&gt;@rolls&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;last&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;is_first_throw_in_frame?&lt;/span&gt;
        &lt;span class="attribute"&gt;@rolls&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;odd?&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;open_score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;first_throw_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;second_throw_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;);&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;spare_score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;open_score_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;first_throw_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;next_frame&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;strike_score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;score&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;open_score_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="ident"&gt;open_score_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;next_frame&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;
        &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;is_strike_at?&lt;/span&gt; &lt;span class="ident"&gt;next_frame&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
            &lt;span class="ident"&gt;score&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;first_throw_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;next_frame&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;next_frame&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)))&lt;/span&gt;
        &lt;span class="keyword"&gt;end&lt;/span&gt;
        &lt;span class="ident"&gt;score&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;next_frame&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;frame&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;is_spare_at?&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;open_score_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="ident"&gt;is_strike_at?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;is_strike_at?&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;first_throw_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;first_throw_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;score_at_throw&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;index_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;second_throw_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="ident"&gt;score_at_throw&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;index_for&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;index_for&lt;/span&gt; &lt;span class="ident"&gt;frame&lt;/span&gt;
        &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;frame&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;score_at_throw&lt;/span&gt; &lt;span class="ident"&gt;index&lt;/span&gt;
        &lt;span class="attribute"&gt;@rolls&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;length&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;index&lt;/span&gt; &lt;span class="punct"&gt;?&lt;/span&gt; &lt;span class="attribute"&gt;@rolls&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;index&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;:&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 01 Oct 2009 13:37:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:5144dc80-1acc-4f58-9c87-60971b35354b</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/10/01/bowling-game-kata-in-ruby</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>Ruby</category>
      <category>bowling</category>
      <category>kata</category>
      <category>RSpec</category>
    </item>
    <item>
      <title>Notes from the OkC Dojo 2009-09-30</title>
      <description>&lt;p&gt;Tonight we had a small group of die-hard practitioners working with Ruby and RSpec. We intended to use the Randori style, but it was a small enough group that we were a bit more informal than that.&lt;/p&gt;


	&lt;p&gt;We tried the Shunting Yard Algorithm again and it worked out fairly well. The level of experience in Ruby was low to moderate (which is why we wanted to get people a chance to practice it) and the RSpec experience was generally low (again, great reason to give it a try).&lt;/p&gt;


We had several interesting (at least to me) side discussions on things such as:
	&lt;ul&gt;
	&lt;li&gt;Forth&lt;/li&gt;
		&lt;li&gt;Operator precedence&lt;/li&gt;
		&lt;li&gt;Operator associativity&lt;/li&gt;
		&lt;li&gt;L-Values and R-Values&lt;/li&gt;
		&lt;li&gt;Directed Acyclic Graphis&lt;/li&gt;
		&lt;li&gt;In-fix, pre-fix, post-fix binary tree traversal&lt;/li&gt;
		&lt;li&gt;Abstract Syntax Trees (AST)&lt;/li&gt;
		&lt;li&gt;The list goes on, I&amp;#8217;m a big-time extrovert, so I told Chad to occasionally tell me to shut the heck up&lt;/li&gt;
	&lt;/ul&gt;


The Shunting Yard Algorithm is a means of translating an in-fix expression into a post-fix expression (a.k.a. reverse polish notation &amp;#8211; used by the best calculators in the world, HP [I also prefer vi, fyi!-] ). For example:
	&lt;ul&gt;
	&lt;li&gt;1 + 3 becomes 1 3 +&lt;/li&gt;
		&lt;li&gt;a = b = 17 becomes a b 17 = =&lt;/li&gt;
		&lt;li&gt;2 + 3 * 5 becomes 2 3 5 * +&lt;/li&gt;
		&lt;li&gt;2 * 3 + 5 becomes 2 3 * 5 +&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;One typical approach to this problem is to develop an &lt;span class="caps"&gt;AST&lt;/span&gt; from the in-fix representation and then recursively traversing the &lt;span class="caps"&gt;AST&lt;/span&gt; using a recursive post-fix traversal.&lt;/p&gt;


	&lt;p&gt;What I like about he Shunting Yard Algorithm is it takes a traditionally recursive algorithm (DAG traversal, where a binary tree is a degenerate &lt;span class="caps"&gt;DAG&lt;/span&gt;) and writes it iteratively using it&amp;#8217;s own stack (local or instance variable) storage versus using the program stack to store activation records (OK stack frames). Essentially, the local stack is used for pending work.&lt;/p&gt;


	&lt;p&gt;This is one of those things I think is a useful skill to learn: writing traditionally recursive algorithms using a stack-based approach. This allows you to step through something (think iteration) versus having to do things whole-hog (recursively, with a block (lambda) passed in). In fact, I bought a used algorithm book 20 years ago because it had a second on this subject. And looking over my left shoulder, I just saw that book. Nice.&lt;/p&gt;


	&lt;p&gt;To illustrate, here&amp;#8217;s the &lt;span class="caps"&gt;AST&lt;/span&gt; for the first example:&lt;p/&gt;
&lt;img src="http://yuml.me/3e75c5ce" /&gt;&lt;/p&gt;


Since the group had not done a lot with recursive algorithms (at least not recently), we discussed a short hand way to remember the various traversal algorithms using three letters: L, R, P
	&lt;ul&gt;
	&lt;li&gt;L -&amp;gt; Go Left&lt;/li&gt;
		&lt;li&gt;R -&amp;gt; Go Right&lt;/li&gt;
		&lt;li&gt;P -&amp;gt; Print (or process)&lt;/li&gt;
	&lt;/ul&gt;


Each of the three traditional traversal algorithms (for a binary tree) use just these three letters. And the way to remember each is to put the &amp;#8216;p&amp;#8217; where the name suggests. For example:
	&lt;ul&gt;
	&lt;li&gt;in-fix, in -&amp;gt; in between -&amp;gt; L &lt;b&gt;P&lt;/b&gt; R&lt;/li&gt;
		&lt;li&gt;pre-fix, pre, before -&amp;gt; &lt;b&gt;P&lt;/b&gt; L R&lt;/li&gt;
		&lt;li&gt;post-fix, post, after -&amp;gt; &lt;span class="caps"&gt;L R&lt;/span&gt; &lt;b&gt;P&lt;/b&gt;&lt;/li&gt;
	&lt;/ul&gt;


Then, given the graph above, you can traverse it as follows:
	&lt;ul&gt;
	&lt;li&gt;in-fix: Go left, you hit the 1, it&amp;#8217;s a leaf note so print it, go up to the +, print it, go to the right, you end up with 1 + 3&lt;/li&gt;
		&lt;li&gt;post-fix: Go left you hit the 1, it&amp;#8217;s a leaf node, print it, go back to the +, since this is post-fix, don&amp;#8217;t print yet, go to the right, you get the 3, it&amp;#8217;s a leaf node, print it, then finally print the +, giving: 1 3 +&lt;/li&gt;
		&lt;li&gt;pre-fix: start at + and print it, then go left, it&amp;#8217;s a leaf note, print it, go right, it&amp;#8217;s a leaf node, print it, so you get: + 1 3 &amp;#8211; which looks like a function call (think operator+(1, 3))&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;It&amp;#8217;s not quite this simple &amp;#8211; we actually looked at larger examples &amp;#8211; but this gets the essence across. And to move from a tree to a &lt;span class="caps"&gt;DAG&lt;/span&gt;, simply iterate over all children, printing before or after the complete iteration; in-fix doesn&amp;#8217;t make as much sense in a general &lt;span class="caps"&gt;DAG&lt;/span&gt;. We also discussed tracking the visited nodes if you&amp;#8217;ve got a graph versus an acyclic graph.&lt;/p&gt;


	&lt;p&gt;After we got a multi-operator expression with same-precedence operators working, e.g., 1 + 3 &amp;#8211; 2, which results in: 1 3 + 2 -, we moved on to handling different operator precedence.&lt;/p&gt;


	&lt;p&gt;Around this time, there was some skepticism that post-fix could represent the same expression as in-fix. This is normal, if you have not seen these kinds of representations. And let&amp;#8217;s be frank, how often do most of us deal with these kinds of things? Not often.&lt;/p&gt;


	&lt;p&gt;Also, there was another question: &lt;span class="caps"&gt;WHY&lt;/span&gt;?&lt;/p&gt;


	&lt;p&gt;In a nutshell, with a post-fix notation, you do not need parentheses. As soon as an operator is encountered, you can immediately process it rather than waiting until the next token to complete the operator (no look-ahead required). This also led to HP developing a calculator in 1967 (or &amp;#8216;68) that was &amp;lt; 50 pounds and around &lt;span class="caps"&gt;USD&lt;/span&gt; $5,000 that could add, subtract, multiply and divide, which was&lt;i&gt; &lt;b&gt;huge&lt;/b&gt;&lt;/i&gt; at the time (with a stack size of 3 &amp;#8211; later models went to a stack size of 4, giving us the x, y, z and t registers).&lt;/p&gt;


	&lt;p&gt;During this rat-hole, we discussed associativity. For example, a = b = c is really (a = (b = c))&lt;/p&gt;


	&lt;p&gt;That&amp;#8217;s because the assignment operator is right-associative. This lead into r-values and l-values.&lt;/p&gt;


Anyway, we&amp;#8217;re going to meet again next week. Because we (read this as me) were not disciplined in following the Randori style, these side discussions lead to taking a long to fix a problem. We should have &amp;#8220;hit the reset button&amp;#8221; sooner, so next time around we&amp;#8217;re going to add a bit more structure to see what happens:
	&lt;ul&gt;
	&lt;li&gt;The driver finishes by writing a new failing test.&lt;/li&gt;
		&lt;li&gt;The driver commits the code with the newest failing test (we&amp;#8217;ll be using git)&lt;/li&gt;
		&lt;li&gt;Change drivers and give him/her some time-box (5 &amp;#8211; 10 minutes)&lt;/li&gt;
		&lt;li&gt;If, at the end of the current time-box, the current driver has all tests passing, go back to the first bullet in this list.&lt;/li&gt;
		&lt;li&gt;If at the end, the same test that was failing is still failing, (fist time only) give them a bit more time.&lt;/li&gt;
		&lt;li&gt;However, if any other tests are failing, then we revert back to the last check in and switch drivers.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Here&amp;#8217;s an approximation of these rules using &lt;a href="http://yuml.me"&gt;yuml.me&lt;/a&gt;:
&lt;img src="http://yuml.me/704421f3" /&gt;&lt;/p&gt;


And here&amp;#8217;s the syntax to create that diagram:
&lt;pre&gt;
(start)-&amp;gt;(Create New Failing Test)-&amp;gt;(Commit Work)-&amp;gt;(Change Drivers)
(Change Drivers)-&amp;gt;(Driver Working)
(Driver Working)-&amp;gt;&amp;lt;d1&amp;gt;[tick]-&amp;gt;(Driver Working)
&amp;lt;d1&amp;gt;[alarm]-&amp;gt;(Check Results)-&amp;gt;([All Tests Passing])-&amp;gt;(Create New Failing Test)
(Check Results)-&amp;gt;([Driver Broke Stuff])-&amp;gt;(git -reset hard)-&amp;gt;(Change Drivers)
(Check Results)-&amp;gt;([First Time Only and Still Only Newest Test Failing])-&amp;gt;(Give Driver A Touch More Time)-&amp;gt;(Check Results)
&lt;/pre&gt;

	&lt;p&gt;Note that this is not a strict activity diagram, the feature is still in beta, and creating this diagram as I did made the results a bit more readable. Even so, I like this tool so I wanted to throw another example in there (and try out this diagram type I have not used before &amp;#8211; at least not with this tool, I&amp;#8217;ve created too many activity diagrams). If you&amp;#8217;d like to see an accurate activity diagram, post a comment and I&amp;#8217;ll draw one in Visio and post it.&lt;/p&gt;


	&lt;p&gt;Anyway, we&amp;#8217;re going to try to move to a weekly informal practice session with either bi-weekly or monthly &amp;#8220;formal&amp;#8221; meetings. We&amp;#8217;ll keep switching out the language and the tools. I&amp;#8217;m even tempted to do design sessions &amp;#8211; &lt;span class="caps"&gt;NO CODING&lt;/span&gt;?! What?! Why not. Some people still work that way, so it&amp;#8217;s good to be able to work in different modes.&lt;/p&gt;


	&lt;p&gt;If you&amp;#8217;re in Oklahoma City, hope to see you. If not, and I&amp;#8217;m in your town, I&amp;#8217;d be interested in dropping into your dojos!&lt;/p&gt;</description>
      <pubDate>Wed, 30 Sep 2009 22:57:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:10b4fa5b-d8fa-4c4a-aabf-53130760201e</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/09/30/notes-from-the-okc-dojo-2009-09-30</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>dojo</category>
      <category>kata</category>
      <category>shunting</category>
      <category>yard</category>
      <category>algorithm</category>
      <category>computer</category>
      <category>science</category>
      <category>ast</category>
      <category>TDD</category>
      <category>bdd</category>
      <category>RSpec</category>
      <category>Ruby</category>
      <category>yuml.me</category>
    </item>
    <item>
      <title>Ruining your Test Automation Strategy.</title>
      <description>&lt;p&gt;&lt;img src="http://butunclebob.com/files/images/test_plan_toc.jpg" width="300" align="left" hspace="10"&gt;
Everybody wants a test automation strategy nowadays.  The reason is clear.  It take a &lt;em&gt;lot&lt;/em&gt; of effort to run a suite of manual tests; and that effort has be be repeated several times per year.&lt;/p&gt;


	&lt;p&gt;Consider the fate of this poor customer of mine.  The picture you see here is simply the &lt;em&gt;Table of Contents&lt;/em&gt; of his manual test plan.  That plan has tens of thousands of individual manual tests.  It costs them millions of dollars to execute, and they must execute it many times each year.&lt;/p&gt;


	&lt;p&gt;To make matters worse, in these difficult times, management has told the QA manager that he must cut 50% from his manual testing budget.  The question he asked me was: &amp;#8220;Which 40,000 of these 80,000 tests should I delete?&amp;#8221;&lt;/p&gt;


	&lt;p&gt;So, as you can probably imagine, this poor guy really wished his tests were automated.  Runnning automated tests does not cost six figures several times a year.  Running automated tests does not need to be cut in half when budgets get tight.  Running automated tests are the way to go.&lt;/p&gt;


	&lt;p&gt;One common strategy to get your tests automated is to outsource the problem.  You hire some team of test writers to transform your manual tests into automated tests using some automation tool.  These folks execute the manual test plan while setting up the automation tool to record their actions.  Then the tool can simply play the actions back for each new release of the system; and make sure the screens don&amp;#8217;t change.&lt;/p&gt;


	&lt;p&gt;Sounds great doesn&amp;#8217;t it?  Sounds like just the ticket!  Sounds like a simple way to convert manual tests into automated tests!&lt;/p&gt;


	&lt;p&gt;Yeah, and it&amp;#8217;s a sure fire way to make sure you utterly ruin your strategy for test automation!...&lt;/p&gt;


&lt;p/&gt;
&lt;p/&gt;
&lt;p/&gt;

	&lt;h2&gt;Why is this so runious?&lt;/h2&gt;


	&lt;p&gt;Automatically testing a system through the &lt;span class="caps"&gt;GUI&lt;/span&gt; &lt;em&gt;couples&lt;/em&gt; the tests to the &lt;span class="caps"&gt;GUI&lt;/span&gt;.  That&amp;#8217;s right, this is a &lt;em&gt;coupling&lt;/em&gt; problem!  A standard, every-day, good ol&amp;#8217; software design &lt;em&gt;coupling&lt;/em&gt; problem.  And the problem with coupling is that when two things are coupled, and you change one of them, the other one breaks.&lt;/p&gt;


	&lt;p&gt;In the case of automated tests, if you change the &lt;span class="caps"&gt;GUI&lt;/span&gt;, the automated tests break.  This was a big enough problem when the test were manual.  You always had to go back and edit the test plans to take &lt;span class="caps"&gt;GUI&lt;/span&gt; changes into account.  Fortunately, since the test were manual, you had &lt;em&gt;human beings&lt;/em&gt; in the loop, and you could expect them to use common sense about simple &lt;span class="caps"&gt;GUI&lt;/span&gt; changes.  The fact that what they saw on the screen differed from what they test plan said they should see would not confound them so long as they understood how the &lt;span class="caps"&gt;GUI&lt;/span&gt; had changed.&lt;/p&gt;


	&lt;p&gt;But an automated tool doesn&amp;#8217;t have that kind of reasoning power.  If the automated tool sees &lt;em&gt;anything&lt;/em&gt; different from what it expects, it simply fails.&lt;/p&gt;


	&lt;p&gt;Now, clearly, automated tools can be made to be clever enough to avoid simple cosmetic issues like the moving of a button, or a change in the spelling of a menu.  But you have to &lt;em&gt;work&lt;/em&gt; at making the tests tolerant of such changes.  Do you think that outsourced team of test writers care much about that?&lt;/p&gt;


	&lt;p&gt;In any case, no tool can deal with changes to the navigation structure, or gross changes to the structure of screens.  Thus, there will always be a class of &lt;span class="caps"&gt;GUI&lt;/span&gt; changes that will cause huge swaths of automated tests to fail.  Unfortunately these kinds of changes are all too common.  What&amp;#8217;s more the cost of re-recording the tests is high, and the re-recording process itself is error-prone.&lt;/p&gt;


	&lt;p&gt;The net result is that &lt;span class="caps"&gt;GUI&lt;/span&gt; driven automated tests are &lt;em&gt;fragile&lt;/em&gt;, and the process of maintaining them is expensive and unreliable.&lt;/p&gt;


	&lt;p&gt;To drive this point home, consider the fate of an old client of mine who had tens of thousands of automated tests driven through the &lt;span class="caps"&gt;GUI&lt;/span&gt;.  Every time anyone changed the &lt;span class="caps"&gt;GUI&lt;/span&gt; a thousand or so tests broke.  The burden of maintaining those tests was so great that this customer added one restrictive policy after another in an effort to prevent changes to the &lt;span class="caps"&gt;GUI&lt;/span&gt;.  In the end, &lt;span class="caps"&gt;GUI&lt;/span&gt; changes became officially prohibited. (This was a &lt;span class="caps"&gt;DOS GUI&lt;/span&gt; in the era of Windows!)&lt;/p&gt;


	&lt;p&gt;Or consider another client who spent a great deal of time and effort creating automated tests through the &lt;span class="caps"&gt;GUI&lt;/span&gt;.  This client could not constrain the &lt;span class="caps"&gt;GUI&lt;/span&gt; against change, so had to live with the burden of re-recording the tests.  But the burden was too great. Trade-offs were made.  Many of the tests de-prioritized, and therefore lost.  Bit by bit this customer lost his investment in automated tests.&lt;/p&gt;


	&lt;p&gt;The bottom line is that automated tests through the &lt;span class="caps"&gt;GUI&lt;/span&gt; are inherently unstable, and will drive you to one or the other of those two undesirable states.&lt;/p&gt;


	&lt;h2&gt;It is hopeless?&lt;/h2&gt;


	&lt;p&gt;Not at all.  First of all, you &lt;em&gt;need&lt;/em&gt; some acceptance tests that go through the &lt;span class="caps"&gt;GUI&lt;/span&gt;.  I think that number is on the order of 5%.  These are integration tests that make sure that the whole system is wired up correctly.&lt;/p&gt;


	&lt;p&gt;You &lt;em&gt;also&lt;/em&gt; need to test the &lt;span class="caps"&gt;GUI&lt;/span&gt; through the &lt;span class="caps"&gt;GUI&lt;/span&gt;, and this might be another 5-10% of the total body of tests.  What does it mean to test the &lt;span class="caps"&gt;GUI&lt;/span&gt;?  It means that you aren&amp;#8217;t testing any &lt;em&gt;business&lt;/em&gt; rules!  You test the &lt;span class="caps"&gt;GUI&lt;/span&gt; and &lt;em&gt;only&lt;/em&gt; the &lt;span class="caps"&gt;GUI&lt;/span&gt;.   My favorite scheme for doing this is to mock out all the business rule code entirely, replacing it with a dummy that simply provides canned answers to all the &lt;span class="caps"&gt;GUI&lt;/span&gt; interfaces.  Imagine, for example, replacing all the servlets in a web system with dummy servlets that pay no attention to their inputs, use no database at all, and simply return canned &lt;span class="caps"&gt;HTML&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;By the same token, the &lt;em&gt;business rule&lt;/em&gt; tests should &lt;em&gt;not&lt;/em&gt; use the &lt;span class="caps"&gt;GUI&lt;/span&gt;.  In fact, the &lt;span class="caps"&gt;GUI&lt;/span&gt; shouldn&amp;#8217;t even be turned on.  Rather, your tests should invoke the same business rule APIs that the &lt;span class="caps"&gt;GUI&lt;/span&gt; invokes.  Indeed, the tests become an alternative UI.&lt;/p&gt;


	&lt;p&gt;Preferably the Business Rule &lt;span class="caps"&gt;API&lt;/span&gt; is well below the &lt;span class="caps"&gt;GUI&lt;/span&gt; layer.  In a web system it should be below the servlet layer.  In the best designed systems, it can even be &lt;em&gt;outside&lt;/em&gt; the container.&lt;/p&gt;


	&lt;p&gt;Tools like &lt;a href="http://fitnesse.org"&gt;FitNesse&lt;/a&gt;, &lt;a href="http://cukes.info/"&gt;Cucumber&lt;/a&gt;, &lt;a href="http://code.google.com/p/robotframework/"&gt;RobotFX&lt;/a&gt;, and &lt;a href="http://www.greenpeppersoftware.com/confluence/display/GPW/Home/"&gt;GreenPepper&lt;/a&gt; are designed for just this kind of &lt;span class="caps"&gt;API&lt;/span&gt; testing.&lt;/p&gt;


	&lt;p&gt;Tests that drive the system through the &lt;span class="caps"&gt;API&lt;/span&gt; are entirely decoupled from the &lt;span class="caps"&gt;GUI&lt;/span&gt;.  When the &lt;span class="caps"&gt;GUI&lt;/span&gt; changes, these tests are completely unaffected.  There is no huge burden of test maintenance, and you are not at risk for losing your tests or constraining the &lt;span class="caps"&gt;GUI&lt;/span&gt;.&lt;/p&gt;


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


	&lt;p&gt;Automated testing through the &lt;span class="caps"&gt;GUI&lt;/span&gt; is intuitive, seductive, and almost always &lt;em&gt;wrong&lt;/em&gt;!  A dedicated program of automatically testing your system through the &lt;span class="caps"&gt;GUI&lt;/span&gt; is almost certain to fail.  If you want a robust test automation strategy, plan to use a healthy dose of &lt;span class="caps"&gt;API&lt;/span&gt; testing, and as little &lt;span class="caps"&gt;GUI&lt;/span&gt; testing as possible.&lt;/p&gt;</description>
      <pubDate>Tue, 29 Sep 2009 15:42:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:fc26eb14-7654-49ba-a79c-52a5b8f8bb0c</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/09/29/ruining-your-test-automation-strategy</link>
      <category>Design Principles</category>
    </item>
    <item>
      <title>The Duct Tape Programmer</title>
      <description>&lt;p&gt;In Joel Spolsky&amp;#8217;s recent &lt;a href="http://www.joelonsoftware.com/items/2009/09/23.html"&gt;blog&lt;/a&gt; he talks about &amp;#8220;Duct Tape Programmers&amp;#8221;.  These &amp;#8220;pretty boys&amp;#8221; don&amp;#8217;t use complex tools like C++, Templates, &lt;span class="caps"&gt;COM&lt;/span&gt;, Multiple Inheritance, etc.  They don&amp;#8217;t waste their time going to &amp;#8220;goddamn Design Patterns meetups&amp;#8221;.  They don&amp;#8217;t do all the fancy things that speakers at conferences talk about.  They just ship product.&lt;/p&gt;


	&lt;p&gt;Surprisingly I agreed with almost everything he wrote.  Almost&amp;#8230;&lt;/p&gt;


	&lt;p&gt;It&amp;#8217;s a good blog.  It&amp;#8217;s a &lt;em&gt;really&lt;/em&gt; good blog.  Oh I don&amp;#8217;t mean his silly complaining about C++ or Templates or &lt;span class="caps"&gt;COM&lt;/span&gt;.  (Although doing just about &lt;em&gt;anything&lt;/em&gt; that involves Visual Studio is something I don&amp;#8217;t want to think about.)  I think you can ignore the &lt;em&gt;specifics&lt;/em&gt; of what Joel said.  What&amp;#8217;s good about the blog is the &lt;em&gt;spririt&lt;/em&gt;.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;Quoting Peter Seibel quoting Jamie Zawinsky: &amp;#8217;&amp;ldquo;Yeah,&amp;rdquo; he says, &amp;ldquo;At the end of the day, ship the [f___ing] thing! It&amp;rsquo;s great to rewrite your code and make it cleaner and by the third time it&amp;rsquo;ll actually be pretty. But that&amp;rsquo;s not the point&amp;mdash;you&amp;rsquo;re not here to write code; you&amp;rsquo;re here to ship products.&amp;rdquo;&amp;#8217;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Now don&amp;#8217;t get me wrong.  I&amp;#8217;m the &amp;#8220;Clean Code&amp;#8221; guy.  I want your code &lt;em&gt;clean&lt;/em&gt;.  I &lt;em&gt;don&amp;#8217;t&lt;/em&gt; want you making a mess.  On the other hand, I want you to &lt;em&gt;ship&lt;/em&gt;.  I don&amp;#8217;t want you gilding the lilly.  I don&amp;#8217;t want you wrapped up in endless polishing.&lt;/p&gt;


	&lt;p&gt;I want you to ship, but I don&amp;#8217;t want you to ship shit.&lt;/p&gt;


	&lt;p&gt;If you think I&amp;#8217;m contradicting myself, you&amp;#8217;re wrong.  There is no contradiction in the notion that you must ship, and that you must be proud of what you ship.&lt;/p&gt;


	&lt;p&gt;The programmer who spends weeks building the &lt;em&gt;perfect structure&lt;/em&gt; does just as much harm to the project as the programmer who hacks a bunch of crap together. Neither have struck the balance that&amp;#8217;s required.&lt;/p&gt;


	&lt;p&gt;In short, it&amp;#8217;s bad to use too much duct tape.  But I&amp;#8217;d be suspicious if I didn&amp;#8217;t see &lt;em&gt;some&lt;/em&gt; duct tape!&lt;/p&gt;


	&lt;p&gt;As for Joel&amp;#8217;s consistent dismissal of unit testing, he&amp;#8217;s just &lt;em&gt;wrong&lt;/em&gt; about that.  Unit testing (done &lt;span class="caps"&gt;TDD&lt;/span&gt; style) does not slow you down, it speeds you up.  One day I hope Joel eventually realizes this.  Programmers who say they don&amp;#8217;t have time to write tests are living in the stone age.  They might as well be saying that man wasn&amp;#8217;t meant to fly.&lt;/p&gt;


	&lt;p&gt;As for Joel&amp;#8217;s consistent complaints about C++, Templates, Design Patterns, &lt;span class="caps"&gt;COM&lt;/span&gt;, etc, etc.  Any tool can be over used.  There&amp;#8217;s nothing wrong with any of these things, and they all have benefits to provide.  So long as you use them for their benefits, instead of for their &amp;#8220;cool-ness&amp;#8221; (COM?  Cool? Well, Joel&amp;#8217;s an old guy like me.) you&amp;#8217;ll be fine.&lt;/p&gt;


	&lt;p&gt;Again Joel&amp;#8217;s &lt;em&gt;specific&lt;/em&gt; complaints can be ignored.  The &lt;em&gt;spirit&lt;/em&gt; of simplicity, however, should be taken to heart.  If you don&amp;#8217;t need a &amp;#8220;cool&amp;#8221; technology, you are probably better off not using it.  Keep things simple.  Keep things uncomplicated.  Don&amp;#8217;t pack your system with every new idea you&amp;#8217;ve heard.&lt;/p&gt;


	&lt;p&gt;Not that you shouldn&amp;#8217;t learn new ideas, and new languages, and new APIs; you should!  But you don&amp;#8217;t have to use them in systems as soon as they are out of the box.  Let them cure a bit.&lt;/p&gt;


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


	&lt;p&gt;I won&amp;#8217;t make excuses for programmers.  Programers should be &lt;em&gt;smart&lt;/em&gt;.  Programmers should be &lt;em&gt;very&lt;/em&gt; &lt;em&gt;very&lt;/em&gt; smart.  Indeed, programmers should be smart enough to build beautiful and robust systems from a small set of very simple tools.&lt;/p&gt;


	&lt;p&gt;So.  Be smart.  Be clean.  Be simple.  Ship!  And keep a &lt;em&gt;small&lt;/em&gt; roll of duct tape at the ready, and don&amp;#8217;t be afraid to use it.&lt;/p&gt;</description>
      <pubDate>Thu, 24 Sep 2009 11:51:03 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:d7458171-7aae-4085-947f-7c4f8f28f79f</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/09/24/the-duct-tape-programmer</link>
    </item>
    <item>
      <title>A Mess is not a Technical Debt.</title>
      <description>&lt;p&gt;The term &lt;a href="http://martinfowler.com/bliki/TechnicalDebt.html"&gt;Technical Debt&lt;/a&gt; was created by Ward Cunningham to describe the engineering trade-off&amp;#8217;s that software developers and business stakeholders must often make in order to meet schedules and customer expectations.  In short, you may need to use suboptimal designs in the short term, because the schedule does not allow longer term designs to be used.  As a simple example, your initial website design may need to be frames based because you don&amp;#8217;t have time to build an Ajax framework.&lt;/p&gt;


	&lt;p&gt;Clearly this causes a debt.  If the customer is looking for a web 2.0 system, then frames just aren&amp;#8217;t going to cut it for long.  So time is going to have to be carved out of a future schedule to refit the system with an Ajax solution.&lt;/p&gt;


	&lt;p&gt;In short, the business has decided that it can afford to delay release 2 in order to accelerate release 1.  Is this wise?&lt;/p&gt;


	&lt;p&gt;Businesses make this kind of trade-off all the time; and there&amp;#8217;s nothing inherently unwise about it.  If the early release of 1.0 drives the business that pays for the development of 2.0 then the business has won.  So &lt;em&gt;this kind&lt;/em&gt; of reasoned technical debt may indeed be appropriate.&lt;/p&gt;


	&lt;p&gt;Unfortunately there is another situation that is sometimes called &amp;#8220;technical debt&amp;#8221; but that is neither reasoned nor wise.  A mess.&lt;/p&gt;


	&lt;p&gt;Technical debt may be necessary, but it had also better be &lt;em&gt;clean&lt;/em&gt;!  If you are going to implement a frames solution instead of an &lt;span class="caps"&gt;AJAX&lt;/span&gt; solution, then make sure that the workmanship of the frames solution is top-notch.  Make sure the design is well balanced, and the code is clean.  If you make a mess while implementing that frames solution, you&amp;#8217;ll never be able to replace it with an &lt;span class="caps"&gt;AJAX&lt;/span&gt; framework.  The mess will impede your progress forever.&lt;/p&gt;


	&lt;p&gt;A mess is not a technical debt.  A mess is just a mess.  Technical debt decisions are made based on real project constraints.  They are risky, but they can be beneficial.  The decision to make a mess is never rational, is always based on laziness and unprofessionalism, and has no chance of paying of in the future.  A mess is &lt;em&gt;always&lt;/em&gt; a loss.&lt;/p&gt;


	&lt;p&gt;When you buy a house and take on a big mortgage debt, you tighten up all your spending and accounting.  You clean up your books and your budgets.  You behave with &lt;em&gt;increased&lt;/em&gt; discipline.  The same is true of technical debt.  The more technical debt you take on, the tighter your disciplines need to be.  You should do &lt;em&gt;more&lt;/em&gt; testing, and &lt;em&gt;more&lt;/em&gt; pairing and &lt;em&gt;more&lt;/em&gt; refactoring.  Technical debt is not a license to make a mess.  Technical debt creates the need for even greater cleanliness.&lt;/p&gt;


	&lt;p&gt;When you decide to take on a technical debt, you had better make sure that your code stays squeaky clean.  Keeping the system clean is the only way you will pay down that debt.&lt;/p&gt;</description>
      <pubDate>Tue, 22 Sep 2009 08:15:19 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:0d502aec-a625-4ce1-9ad9-6e67aa589b44</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/09/22/a-mess-is-not-a-technical-debt</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>&amp;quot;Programming Scala&amp;quot; Is Now Available</title>
      <description>&lt;p&gt;&lt;a href="http://oreilly.com/catalog/9780596155957/"&gt;Programming Scala&lt;/a&gt; is finally available online at &lt;a href="http://www.amazon.com/Programming-Scala-Animal-Guide-Wampler/dp/0596155956/ref=sr_1_3?ie=UTF8&amp;#38;s=books&amp;#38;qid=1253575163&amp;#38;sr=8-3"&gt;Amazon&lt;/a&gt;, &lt;a href="http://oreilly.com/catalog/9780596155957/"&gt;O&amp;#8217;Reilly&lt;/a&gt;,  &lt;a href="http://my.safaribooksonline.com/9780596801908"&gt;Safari&lt;/a&gt;, and hopefully at other online and physical bookstores, too. If you have trouble finding it, just memorize the &lt;span class="caps"&gt;ISBN&lt;/span&gt;, 9780596155957, to aid your search. ;)&lt;/p&gt;


&lt;center&gt;&lt;a href="http://oreilly.com/catalog/9780596155957/"&gt;&lt;img src="http://blog.objectmentor.com/files/prog_scala_mech_cover_front_503x660.png" style="border: 1px solid #7E205F;" /&gt;&lt;/a&gt;&lt;/center&gt;

	&lt;p&gt;&lt;br/&gt;You can download the complete code examples &lt;a href="http://examples.oreilly.com/9780596155964/"&gt;here&lt;/a&gt;. If you want to &amp;#8220;try before you buy&amp;#8221;, see our &lt;a href="http://programming-scala.labs.oreilly.com/"&gt;labs&lt;/a&gt; site.&lt;/p&gt;


	&lt;p&gt;I pitched the book idea just over one year ago. &lt;a href="http://twitter.com/al3x"&gt;Alex Payne&lt;/a&gt;, my co-author, was also talking to O&amp;#8217;Reilly about a book, so we joined forces. It&amp;#8217;s been a fast ride.&lt;/p&gt;


	&lt;p&gt;This book is for you if you are an experienced developer who wants a comprehensive, but fast introduction to Scala. We try to convince you why we like Scala so much, but we also tell you about those dark corners and gotchas that you&amp;#8217;ll find in any language. We even preview the forthcoming 2.8 version of Scala. I hope you&amp;#8217;ll give &lt;a href="http://oreilly.com/catalog/9780596155957/"&gt;Programming Scala&lt;/a&gt; a look.&lt;/p&gt;</description>
      <pubDate>Mon, 21 Sep 2009 17:48:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:5d439b0f-ba3b-4e25-a0d5-b8023a94dbd4</guid>
      <author>Dean Wampler</author>
      <link>http://blog.objectmentor.com/articles/2009/09/21/programming-scala-is-now-available</link>
      <category>Dean's Deprecations</category>
      <category>Scala</category>
      <category>programmingscala</category>
      <category>books</category>
      <enclosure type="image/png" url="http://blog.objectmentor.com/files/prog_scala_mech_cover_front_503x6601.png" length="172253"/>
    </item>
    <item>
      <title>The CSM Integrity Deficit</title>
      <description>&lt;p&gt;Scott Ambler wrote a &lt;a href="https://www.ibm.com/developerworks/mydeveloperworks/blogs/ambler/entry/integrity_debt"&gt;blog&lt;/a&gt;, and an &lt;a href="http://www.ambysoft.com/certification/scam.html"&gt;editorial&lt;/a&gt; about the dirty dealings and desperate deception of the Scrum Alliance and their slimy certification scam.  He rightly points out that the &lt;em&gt;certification&lt;/em&gt; means little more than the applicant&amp;#8217;s check didn&amp;#8217;t bounce.&lt;/p&gt;


	&lt;p&gt;He goes on to imply that the entire agile community is guilty of keeping silent while this huge chicanery was foisted upon an innocent industry.  He calls this conspiratorial silence: &lt;em&gt;&amp;#8220;integrity debt&amp;#8221;&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Oh bollux!  What an incredible load of Dingoes Kidneys!&lt;/p&gt;


	&lt;p&gt;Look.  I&amp;#8217;m not a big fan of &lt;span class="caps"&gt;CSM&lt;/span&gt;.  I think it&amp;#8217;s a gimmick. I am not a &lt;span class="caps"&gt;CSM&lt;/span&gt; myself, and have no intention of joining their ranks.  When I meet someone who proclaims themselves to be a &lt;span class="caps"&gt;CSM&lt;/span&gt;, I&amp;#8217;m not particularly impressed.  I know what that certification means, and I take it with a grain of salt.  To me, the title of &lt;span class="caps"&gt;CSM&lt;/span&gt; is worth little more than a shrug.&lt;/p&gt;


	&lt;p&gt;We at Object Mentor do a lot of training in things like Test Driven Development, Agile Methods. Object Oriented Principles, Java, C#, etc. etc.  At the end of every course we often sign and pass out certificates to the students.  Those certificates proclaim that the student attended the course.  I see no difference between that certificate (which is a certification after all) and the &lt;span class="caps"&gt;CSM&lt;/span&gt; certificate.  I suppose the students who take our &lt;span class="caps"&gt;TDD&lt;/span&gt; course could claim to be &lt;em&gt;Object Mentor Certified TDDers&lt;/em&gt;; and they&amp;#8217;d be right.&lt;/p&gt;


	&lt;p&gt;Have we created an &amp;#8220;Integrity Debt&amp;#8221; by handing out those certificates?  Of course not.  Everybody knows exactly what they mean.  Nobody misrepresents their intent.  They are an honest statement of fact.  And the same is true of the &lt;span class="caps"&gt;CSM&lt;/span&gt; certificate.&lt;/p&gt;


	&lt;p&gt;Is it troubling that some HR people are starting to put &lt;span class="caps"&gt;CSM&lt;/span&gt; requirements on Job postings?  Not at all!  It is perfectly within the rights of any company to decide that they want to hire people who have been appropriately trained.  Are there some HR people who overestimate the value of &lt;span class="caps"&gt;CSM&lt;/span&gt;?  Probably, but that&amp;#8217;s their own fault.&lt;/p&gt;


	&lt;p&gt;In my humble opinion there is no significant integrity issue here.  Oh it wouldn&amp;#8217;t surprise me to learn that there might have been some back-door deals in the early days of &lt;span class="caps"&gt;CSM&lt;/span&gt;.  Perhaps some people were given &lt;span class="caps"&gt;CST&lt;/span&gt; status, or &lt;span class="caps"&gt;CSM&lt;/span&gt; status without careful controls.  If that happened, I chalk it up to birthing pains which the Scrum Alliance is striving to correct.  I don&amp;#8217;t think anybody was out to scam anybody else.  I don&amp;#8217;t think &lt;span class="caps"&gt;CSM&lt;/span&gt; is a far flung conspiracy to ruin the software industry, and I don&amp;#8217;t think the US government flew those jets into the twin towers.&lt;/p&gt;


	&lt;p&gt;Bottom line.  There is no &lt;em&gt;&amp;#8220;Integrity Debt&amp;#8221;&lt;/em&gt; here. What there &lt;em&gt;is&lt;/em&gt; is a group of honest and caring folks who are trying to figure out the best ways to get Agile concepts adopted in an industry that &lt;em&gt;sorely&lt;/em&gt; needs them.&lt;/p&gt;


	&lt;p&gt;In that regard I think that the agile movement has enjoyed a significant &lt;em&gt;boost&lt;/em&gt; because of the interest generated by the &lt;span class="caps"&gt;CSM&lt;/span&gt; program.  There are more companies doing Agile today because of &lt;span class="caps"&gt;CSM&lt;/span&gt;.  So if anybody owes a debt here, it may be the Agile community owing a debt to the &lt;span class="caps"&gt;CSM&lt;/span&gt; program.&lt;/p&gt;


	&lt;p&gt;Maybe, instead of accusing and castigating and pointing the finger of judgement and doom we ought give a salute to Ken Schwaber, and say: &amp;#8220;Thanks Ken.&amp;#8221;&lt;/p&gt;</description>
      <pubDate>Fri, 18 Sep 2009 08:44:43 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:2ae0ff36-9f77-4c49-b236-0d4853d9176c</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/09/18/the-csm-integrity-deficit</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Agile Methods</category>
    </item>
    <item>
      <title>QCon SF 2008: Radical Simplification through Polyglot and Poly-paradigm Programming </title>
      <description>&lt;p&gt;InfoQ has posted the video of my talk at last year&amp;#8217;s QCon San Francisco on &lt;a href="http://www.infoq.com/presentations/polyglot-polyparadigm-programming"&gt;Radical Simplification through Polyglot and Poly-paradigm Programming&lt;/a&gt;. I make the case that relying on just one programming language or one modularity paradigm (&lt;em&gt;i.e.&lt;/em&gt;, object-oriented programming, functional programming, &lt;em&gt;etc.&lt;/em&gt;) is insufficient for most applications that we&amp;#8217;re building today. That includes embedded systems, games, up to complex Internet and enterprise applications.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m giving an &lt;a href="http://thestrangeloop.com/sessions/polyglot-and-polyparadigm-programming-better-agility"&gt; updated version of this talk&lt;/a&gt; at the &lt;a href="http://thestrangeloop.com/"&gt;Strange Loop Conference&lt;/a&gt;, October 22-23, in St. Louis. I hope to see you there.&lt;/p&gt;</description>
      <pubDate>Tue, 15 Sep 2009 10:35:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:58621ae8-c1b7-4110-8376-1bc0cc248122</guid>
      <author>Dean Wampler</author>
      <link>http://blog.objectmentor.com/articles/2009/09/15/qcon-sf-2008-radical-simplification-through-polyglot-and-poly-paradigm-programming</link>
      <category>Dean's Deprecations</category>
      <category>Videos</category>
      <category>Public Speaking Engagements</category>
      <category>Dynamic Languages</category>
      <category>Agile Methods</category>
      <category>Design Principles</category>
      <category>polyglot</category>
      <category>poly</category>
      <category>paradigm</category>
      <category>QCon</category>
      <category>strange</category>
      <category>loop</category>
    </item>
    <item>
      <title>One Thing: Extract till you Drop.</title>
      <description>&lt;p&gt;For years authors and consultants (like me) have been telling us that functions should do &lt;em&gt;one thing&lt;/em&gt;.  They should do it well.  They should do it only.&lt;/p&gt;


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


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


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

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

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

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

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


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


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

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

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


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


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

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

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

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

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

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


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

      return stringToReplace;
    }

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

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


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


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


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


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

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

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


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


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


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

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

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

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

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

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

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

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

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

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

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


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


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


	&lt;p&gt;After all, with modern tools it takes &lt;em&gt;very&lt;/em&gt; little time.  It makes each function almost trivial.  The code reads very nicely.  It forces you to put little snippets of code into nicely named functions.  And, well gosh, extracting till you drop is kind of fun!&lt;/p&gt;</description>
      <pubDate>Fri, 11 Sep 2009 13:33:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:fa921995-cdc4-4867-8541-9bfa9a2834e4</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/09/11/one-thing-extract-till-you-drop</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Software Craftsmanship</category>
      <category>Design Principles</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>Improving Testability of GUI Code, an Eample</title>
      <description>&lt;p&gt;Just finished first draft. More to come, questions/comments appreciated.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://schuchert.wikispaces.com/tdd.Refactoring.UiExample"&gt;http://schuchert.wikispaces.com/tdd.Refactoring.UiExample&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 10 Sep 2009 23:08:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:02584823-cab7-4003-8a06-87e6767455fb</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/09/10/improving-testability-of-gui-code-an-eample</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>test</category>
      <category>gui</category>
      <category>SRP</category>
      <category>welc</category>
      <category>refactoring</category>
      <category>legacy</category>
    </item>
    <item>
      <title>Pair with one of us at Agile 2009</title>
      <description>&lt;p&gt;Dean, Uncle Bob, Michale Feathers and I will be spending time in our Agile 2009 booth working on problems and pairing with volunteers.&lt;/p&gt;


	&lt;p&gt;If you&amp;#8217;d like to join us for some pairing, please stop by.&lt;/p&gt;


	&lt;p&gt;We&amp;#8217;ll give you an autographed &amp;#8220;code monkey&amp;#8221; for your efforts.&lt;/p&gt;</description>
      <pubDate>Mon, 24 Aug 2009 16:43:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:92de7123-c005-47d4-b68c-ad32f62c0a4e</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2009/08/24/pair-with-one-of-us-at-agile-2009</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>agile2009</category>
      <category>pairing</category>
      <category>TDD</category>
    </item>
    <item>
      <title>The Sculptors</title>
      <description>&lt;p&gt;&amp;#8220;Welcome!&amp;#8221; said the &lt;a href="http://butunclebob.com/files/images/golden%20code%20bob.jpg"&gt;Master&lt;/a&gt; to the &lt;a href="http://2.bp.blogspot.com/_dYi-rTxxT2o/SXPhBn4-19I/AAAAAAAAB8g/cBCPoilslpE/S220-h/3187276048_580e77883b-1.jpg"&gt;Journeyman&lt;/a&gt;.  &amp;#8220;It has been long since last you were here, and there is much we can discuss.  I trust your &lt;a href="http://programmingtour.blogspot.com/"&gt;journeys&lt;/a&gt; have been interesing?&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Indeed they have, and I have much to show you.&amp;#8221; The Journeyman replied.  &amp;#8220;And I see you have a new Apprentice!&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Yes indeed, a fine lad who has been helping me with my projects.  He learns quickly, and his practice is true.&amp;#8221;  The &lt;a href="http://lupusdeiapprenticeship.blogspot.com/"&gt;Apprentice&lt;/a&gt; said nothing, but nodded to the Journeyman and sat quietly as his two elders conversed.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;What then have you to show me?&amp;#8221; Said the Master.&lt;/p&gt;


	&lt;p&gt;The Journeyman smiled and said: &amp;#8220;Have you seen the &lt;a href="http://www.parlezuml.com/softwarecraftsmanship/sessions/tdd_as_if_you_meant_it.htm"&gt;technique&lt;/a&gt; of &lt;a href="http://www.keithbraithwaite.demon.co.uk/professional/"&gt;Braithe&lt;/a&gt;?&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Ah, yes, I believe he calls it: Sculpt as though you really mean it.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Yes, that&amp;#8217;s the one.  Have you tried it?&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;No.&amp;#8221; The master replied &amp;#8220;I&amp;#8217;ve only heard about it.  Have you?&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Indeed, I have done this several times at the &lt;a href="http://coderetreat.ning.com/"&gt;Clay Retreats&lt;/a&gt;.  Would you like me to show you?&amp;#8221;&lt;/p&gt;


	&lt;p&gt;The Master smiled and nodded. &amp;#8220;I&amp;#8217;d very much like to see this technique.&amp;#8221;  And then to the Apprentice: &amp;#8220;Come over here and work with us boy, you&amp;#8217;ll learn something new.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;The Apprentice set down the work we was doing and moved over to sit down with the other two.  It was clear that he found this very exciting.&lt;/p&gt;


	&lt;p&gt;The Journeyman reached into his bag and pulled out a wad of &lt;a href="http://www.ruby-lang.org/en/"&gt;slick, pliable, Clay&lt;/a&gt;.  The Apprentice was pleasantly surprised.  Though he had worked with this kind of Clay before, it had been a while.  He and the Master had lately been working with a &lt;a href="http://java.sun.com/"&gt;brown Clay that was duller and stiffer&lt;/a&gt; than this.&lt;/p&gt;


	&lt;p&gt;The Master said: &amp;#8220;Let&amp;#8217;s use my &lt;a href="http://www.jetbrains.com/idea/"&gt;wheel&lt;/a&gt;.&amp;#8221;  The Master&amp;#8217;s wheel was delicate and ornate, sporting many knobs, levers, and other forms of calibration and adjustment.&lt;/p&gt;


	&lt;p&gt;The Journeyman paused ever so slightly.  &amp;#8220;Oh.  Well&amp;#8230; certainly.  That will be a good experience for me.  I usually just use a &lt;a href="http://www.vim.org/"&gt;little portable wheel&lt;/a&gt; that I keep in my pack.  Yes, by all means, let&amp;#8217;s use your wheel.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;It took some time to get the Clay situated just right on the Master&amp;#8217;s wheel.  Powerful though it was, getting the adjustments and balance just right was a painstaking process.  But soon, the wheel was spinning and the Clay was balanced and ready.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;I suggest we sculpt: &lt;a href="http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life"&gt;Horton&amp;#8217;s Mage of Feil&lt;/a&gt;.&amp;#8221; Said the master.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;An excellent choice.&amp;#8221; Replied the Journeyman.  We&amp;#8217;ll never finish it in this session, but that&amp;#8217;s not the point.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Indeed not!&amp;#8221; intoned the Master.  &amp;#8220;Shall I begin?&amp;#8221;&lt;/p&gt;


	&lt;p&gt;The master stopped the spinning of the wheel, and began to shape the rough outline of the Mage.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Why are you shaping the Mage?&amp;#8221; The Journeyman asked, grinning.&lt;/p&gt;


	&lt;p&gt;The Master stopped and smiled sheepishly.  &amp;#8220;Why indeed?  I&amp;#8217;ve gotten ahead of my self.  I am informing the Clay, rather than letting the Clay inform me.&amp;#8221;  He turned to the Apprentice and said: &amp;#8220;In the style of Braithe we do not tell the Clay what shape to take, we allow the Clay to tell us what shape it desires.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;But how can Clay tell us anything?&amp;#8221; The Apprentice blurted.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Don&amp;#8217;t be obtuse boy!&amp;#8221; Chided the Master.&lt;/p&gt;


	&lt;p&gt;The Journeyman put his hands on the Clay and said: &amp;#8220;If you will permit me?  I will begin with the Mage&amp;#8217;s Staff.&amp;#8221;  His fingers hovered over the Clay for a moment, and then he made the slightest groove in the Clay with the tip of his thumbnail.  &amp;#8220;There.&amp;#8221; He said.  &amp;#8220;That&amp;#8217;s the tip of the shaft.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Yes,&amp;#8221; said the Master staring intently at the Clay.  &amp;#8220;I can see how the shaft could develop from that beginning; but it&amp;#8217;s in the wrong place.  It should be more to the right and closer to the top.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Should it?&amp;#8221; The Journeyman&amp;#8217;s face bore that knowing grin again.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;I suppose Braithe would say that Clay is Clay, and will move to where it is needed.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Indeed, I believe he would.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;The Master put his hands on the Clay and extended the groove ever so slightly.  Then the Journeyman responded in kind.  Gradually, the shape of the staff began to appear.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;This is so strange.&amp;#8221; The Apprentice complained.  &amp;#8220;The angle is all wrong.  Horton holds his staff high, pointing to the north star, and yet you are forming it as though it were laying on the ground!&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Interesting, isn&amp;#8217;t it.&amp;#8221; The Journeyman replied.  &amp;#8220;It&amp;#8217;s hard to imagine how the Mage will appear from this beginning.  But the Clay will have it&amp;#8217;s way.  Just watch.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Hour after hour, the two craftsmen worked.  Even the Apprentice put his hand in occasionally.  They always focussed on one area.  First the staff, then the hand holding the staff, then the arm for that hand, the elbow, the upper arm, the shoulder, the chain-mail, the saddle, and horse.&lt;/p&gt;


	&lt;p&gt;Sometimes they&amp;#8217;d start a new shape in a part of the Clay that was far from where that shape would eventually end up.  Then they would gradually fold the Clay so that the shapes lined up.&lt;/p&gt;


	&lt;p&gt;And as they worked the angle of the piece gradually changed.  By the end of the day, the rear hooves of the horse stood on the wheel.  The Mage&amp;#8217;s legs strained at the stirups as his body leaned forward and his outstretched arm drove his staff into the sky towards the north star.&lt;/p&gt;


	&lt;p&gt;The Master noted the angle of the sun.  He turned to the Journeyman.  &amp;#8220;I believe it is time for you to return.  The &lt;a href="http://www.metrarail.com/Sched/cnw_n/great_lakes.shtml"&gt;coach&lt;/a&gt; leaves at sundown.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;But the Mage is not finished!&amp;#8221; Cried the Apprentice.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Nor shall this Mage ever be finished.&amp;#8221; Said the Master.  We shall keep it in this form on our shelves, so that we can study it later.&amp;#8221;  And the master gingerly removed the partially completed sculpture from the wheel and placed it on a &lt;a href="http://github.com/unclebob/Mage-of-Lief/tree/master"&gt;high shelf&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;Thank you for comming.&amp;#8221; Said the Master.  &amp;#8220;I have learned much.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&amp;#8220;As have I.&amp;#8221; Said the Journeyman.  &amp;#8220;Thank you for having me.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;The two men shook hands, eye-to-eye.  And then parted company.&lt;/p&gt;</description>
      <pubDate>Mon, 17 Aug 2009 10:27:39 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:c44e0fdd-9e43-4289-a716-4afbe88cb6a1</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/08/17/the-sculptors</link>
    </item>
    <item>
      <title>vih</title>
      <description>&lt;p&gt;Over the past few days, I&amp;#8217;ve been tinkering with a little project I&amp;#8217;ve called vih &amp;#8211; it&amp;#8217;s a vi clone written in Haskell.  Here&amp;#8217;s the &lt;a href=http://github.com/michaelfeathers/vih/tree/master&gt;git repo&lt;/a&gt;.  

&lt;p&gt;The way I&amp;#8217;ve started it is rather naive, and frankly I&amp;#8217;m surprised I that I had gotten as far as I did without curses and with the simple data structure I choose.  Rather than using a clever representation for a buffer, I decided to just use a &lt;code&gt;String&lt;/code&gt;.  What this means is that every time a character is inserted into a buffer, the whole thing is split and reconstituted.  I&amp;#8217;m not using &lt;code&gt;Data.ByteString&lt;/code&gt; or &lt;code&gt;Data.ByteString.Lazy&lt;/code&gt; either.  I suppose that I&amp;#8217;ll move toward a more sensible data structure in a while but right now typing is comfortable even with all of that work going on.

&lt;p&gt;My intention in doing this was to start to get a sense of how data structures evolve in Haskell by growing something large from a small seed. The primary data structure that I&amp;#8217;m using right now is called &lt;code&gt;EditBuffer&lt;/code&gt; and I notice that quite a few of my functions translate an &lt;code&gt;EditBuffer&lt;/code&gt; to another &lt;code&gt;EditBuffer&lt;/code&gt;.  This seems to work fine, however I find that I almost always have to label the buffer in the argument list and deconstruct it.  I haven&amp;#8217;t seen pervasive use of labels like that in Haskell code I&amp;#8217;ve looked at, so I&amp;#8217;m wondering if my mapping of functions to data structures is odd.

	&lt;p&gt;Right now, vih supports insert and command mode (toggled with &amp;#8216;i&amp;#8217; and &amp;#8216;ESC&amp;#8217;), the h, j, k, l cursor movements, line deletion with &amp;#8216;dd&amp;#8217;, home with &amp;#8216;gg&amp;#8217;, end of file with &amp;#8216;G&amp;#8217;, `in line&amp;#8217; positioning with &amp;#8216;0&amp;#8217; and &amp;#8217;$&amp;#8217;, insert new line after with &amp;#8216;o&amp;#8217;, and delete current char with &amp;#8216;x&amp;#8217;.  No file I/O yet.&lt;/p&gt;


	&lt;p&gt;Have a look, fork or contribute.&lt;/p&gt;</description>
      <pubDate>Fri, 14 Aug 2009 00:31:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:f3bac35e-0d49-47f6-b231-e95ad3293df1</guid>
      <author>Michael Feathers</author>
      <link>http://blog.objectmentor.com/articles/2009/08/14/vih</link>
      <category>Michaels Musings</category>
    </item>
    <item>
      <title>To Test The Untestable Bug.</title>
      <description>&lt;p&gt;I found a bug that couldn&amp;#8217;t be tested yesterday.&lt;/p&gt;


	&lt;p&gt;There is nothing quite so satisfying as isolating a bug, writing a test that fails because of that bug, and then making the test pass by fixing the bug.  The fact that the test is passing is proof that the bug is fixed.  The existence of that test in the test suite ensures that the bug will never come back again.&lt;/p&gt;


	&lt;p&gt;For ten years I have worked this way.  For ten years I have taught, and coached, and otherwise cajoled software developers to work this way too.  Sometimes those developers would ask me about bugs that couldn&amp;#8217;t be tested; and I would reject the whole concept.  &amp;#8220;If you can write a line of code, you can test that line of code.&amp;#8221; I would reply.&lt;/p&gt;


	&lt;p&gt;But yesterday I found a bug that I couldn&amp;#8217;t write a test for.&lt;/p&gt;


	&lt;p&gt;Actually, that&amp;#8217;s not quite fair.  I &lt;em&gt;was&lt;/em&gt; able to write a test for the bug.  The problem was that the test passed, and I couldn&amp;#8217;t make it fail.&lt;/p&gt;


	&lt;p&gt;But let me set the stage first&amp;#8230;&lt;/p&gt;


	&lt;p&gt;My son Justin is apprenticing with me this summer.  He&amp;#8217;s been helping me write new features for FitNesse.  We have had many pleasant weeks working together.&lt;/p&gt;


	&lt;p&gt;About a week ago I asked him to rework an area of the FitNesse code that includes SuiteSetUp and SuiteTearDown pages into test suites.  These pages are executed &lt;em&gt;once&lt;/em&gt; per suite run.  They are similar to @BeforeClass and @AfterClass functions in JUnit.&lt;/p&gt;


	&lt;p&gt;The old mechanism started with the suite page and found the nearest inherited SuiteSetUp and SuiteTearDown for that page.  Then it would include the SuiteSetUp, all the tests, and finally the SuiteTearDown.  The new mechanism needed to be smarter.  It would look at every test page and determine the most appropriate SuiteSetUp and SuiteTearDown for that page.  Then it would group the test pages by common SuiteSetUp and SuiteTearDown pairs and include them in the suite.&lt;/p&gt;


OK, I know this is a bit detailed, but I&amp;#8217;m almost done.  The point is that the old mechanism created a list of tests that looked like this: 
&lt;pre&gt;Utttt...ttttD&lt;/pre&gt;Whereas the new mechanism created a list of tests that looked like this: &lt;pre&gt;UtttDUttDUtttttDUtD...&lt;/pre&gt;  Where U and D are SuiteSetUp and SuiteTearDown pages, and the t&amp;#8217;s are test pages.

	&lt;p&gt;Justin got all his unit tests passing, cleaned up the code, and then showed it to me.  We spent a little more time cleaning it up, until we were both satisfied with it.&lt;/p&gt;


	&lt;p&gt;Then Justin said to me: &amp;#8220;We should write an acceptance test for this.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;We write a lot of acceptance tests for FitNesse; and, of course, we use FitNesse to write those tests.  There are over 200 FitNesse tests for FitNesse.  But until Justin said it, it didn&amp;#8217;t occur to me that this feature should have an acceptance test.  But after some thought, it was clear that it should.&lt;/p&gt;


	&lt;p&gt;So Justin and I set about to write the acceptance test for this feature.  It was actually pretty straight forward.  We simply used a shadow instance of FitNesse to create a test suite with several test pages and appropriate SuiteSetUp and SuiteTearDown pages.  Then we executed the suite in the shadow instance, and dissected the &lt;span class="caps"&gt;HTML&lt;/span&gt; to ensure that the setups and teardowns were included in the right order.  Easy.&lt;/p&gt;


We used a &lt;em&gt;Slim&lt;/em&gt; OrderedQuery table to ensure that the list of tests, setups, and teardowns was in the right order.  One of the Ordered Query tables looked like this:
&lt;pre&gt;
!|ordered query:pages run in suite|SuiteChildOne  |
|page name                                        |
|SuiteChildOne.SuiteSetUp                         |
|SuiteChildOne.TestOneOne                         |
|SuiteChildOne.TestOneTwo                         |
|SuiteChildOne.SuiteTearDown                      |                                     
|SuiteChildOne.SuiteSetUp                         |
|SuiteChildOne.TestOneThree                       |
|SuiteChildOne.SuiteTearDown                      |
&lt;/pre&gt;

	&lt;p&gt;The TestOneOne and TestOneTwo pages were Fit tests.  The TestOneThree page was a slim test.  These kinds of tests execute in different JVMs, therefore they needed to be run separately, with their own execution of SuiteSetUp and SuiteTearDown.&lt;/p&gt;


	&lt;p&gt;Oddly, this table failed, and the failure was &lt;em&gt;inexplicable&lt;/em&gt;.  It kept complaining that the rows were out of order, when they clearly were correct.&lt;/p&gt;


	&lt;p&gt;After a little inspection and fiddling, Justin said: &amp;#8220;I think the Ordered Query table doesn&amp;#8217;t like duplicates.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Having written the Ordered Query table about 6 months ago, I reviewed the code in my mind and realized he probably had a point.  The Ordered Query table was derived from Query table.  Query tables check that all specified rows exist in a query, but don&amp;#8217;t care about order.  Ordered Query tables ensure that order is correct too.  Having based the Ordered Query algorithm on the Query algorithm, I realized that there might indeed be a duplication issue.&lt;/p&gt;


	&lt;p&gt;So, we modified the test to eliminate the need for duplicates; and I wrote a &lt;a href="https://fitnesse.lighthouseapp.com/projects/23650-fitnesse/tickets/153-orderedquery-does-not-like-duplicate-rows#ticket-153-4"&gt;lighthouse task&lt;/a&gt; that described the bug.&lt;/p&gt;


Yesterday I went to lighthouse and saw that bug there.  I decided to fix it.  So I wrote an acceptance tests expecially for it.  It looked like this:
&lt;pre&gt;
!|Ordered Query:duplicate rows|A|
|x                              |
|SuiteChildOne.SuiteSetUp       |
|SuiteChildOne.TestOneOne       |
|SuiteChildOne.TestOneTwo       |
|SuiteChildOne.SuiteTearDown    |
|SuiteChildOne.SuiteSetUp       |
|SuiteChildOne.TestOneThree     |
|SuiteChildOne.SuiteTearDown    |
&lt;/pre&gt;
Note the similarity?

	&lt;p&gt;Oddly, the test passed.  I scratched my head about this, and tried several other different combinations.  They all worked just fine.  It was as though the bug had disappeared.&lt;/p&gt;


	&lt;p&gt;I began to doubt that the bug had ever existed.  I started rationalizing that perhaps Justin and I had been so focussed on ordering the suites that we didn&amp;#8217;t really diagnose the problem properly, and that we had made some silly cockpit error and mistaken it for a bug in OrderedQuery.&lt;/p&gt;


	&lt;p&gt;So I went to lighthouse and invalidated the bug.  Fortunately for me, I left the new acceptance test in place!...&lt;/p&gt;


	&lt;p&gt;I completed a few more lighthouse tasks, did a git commit, and prepared to push the changes to &lt;a href="http://github.com/unclebob/fitnesse/tree/master"&gt;github&lt;/a&gt;.  It is our rule that you never push to github without running an ant release.  This is the same script that our &lt;a href="http://internal.objectmentor.com:9090/job/fitnesse/"&gt;Hudson&lt;/a&gt; server runs whenever it detects a change in github.  So, in theory, the hudson build should never fail because nobody pushes to github without running the build.&lt;/p&gt;


	&lt;p&gt;The build takes about three minutes to run, and it executes every unit and acceptance test in the system.  Indeed, this same script is the sole criterion we use for deciding whether FitNesse is ready for release.  If the build succeeds, we ship!&lt;/p&gt;


	&lt;p&gt;Anyway, the ant release failed; and it was the new acceptance test that was the cause!&lt;/p&gt;


	&lt;p&gt;The new test history feature of fitnesse is really useful.  I was able to look at the test run that failed and see exactly what the problem was.  And the problem was precisely the same problem that Justin and I saw a week ago.  It looked like Ordered Query &lt;em&gt;really did&lt;/em&gt; have a problem with duplicates.  &lt;em&gt;Sometimes&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;So I quickly re-validated the lighthouse task and set about to diagnose the problem with a bit more care.  I started up FitNesse again and ran the failing test.  It passed!&lt;/p&gt;


	&lt;p&gt;Oh fratz!  How was I going to debug this thing if I couldn&amp;#8217;t get it to reliably fail?  I tried several different configurations of rows and queries, but they all passed just fine.  What&amp;#8217;s more, a subsequent run of ant release passed too!  I only saw it fail twice, and each time a simple recompile made the problem go away.&lt;/p&gt;


	&lt;p&gt;So I fell back on a very old skill that I haven&amp;#8217;t had to use in over ten years.  I started to &lt;em&gt;desk check&lt;/em&gt; the code!  OK, it&amp;#8217;s a bit of an exaggeration to say that I haven&amp;#8217;t desk checked in over ten years.  Actually I desk check all the time.  The point is I always have failing tests to support me.  This time was &lt;em&gt;different&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Actually the problem (well, I &lt;em&gt;think&lt;/em&gt; it was the problem) was not too hard to find.  Deep in the algorithm that matched query rows with table rows was a HashSet of the row numbers that had not yet been matched &amp;#8211; creatively called unmatchedRows.  Every time I matched a row, I removed the number of that row from this set.&lt;/p&gt;


	&lt;p&gt;This algorithm was written for Query tables and was inherited into Ordered Query.  However, in Ordered Query I copied that set into a List for one reason or another.&lt;/p&gt;


	&lt;p&gt;All this works fine until there is a duplicate.  As you might expect, in the Ordered Query the &lt;em&gt;order&lt;/em&gt; in which the duplicates are processed is important.  Unfortunately, the order of the rows in the list that was copied from the set is indeterminate.&lt;/p&gt;


	&lt;p&gt;Now, maybe you missed the importance of that last paragraph.  It described the bug.  So let me re-emphasize.  In the case of duplicate rows I was depending on the order of elements in a list; but I built the list from a HashSet.  HashSets don&amp;#8217;t order their elements.  So the order of the list was indeterminate.&lt;/p&gt;


	&lt;p&gt;The fix was simple.  I changed the HashSet into an ArrayList.  That fixed it.  I think&amp;#8230;&lt;/p&gt;


	&lt;p&gt;The problem is that I had no way to reliably create the symptom.  I could not write a test that failed because I was using a HashSet instead of an ArrayList.  I could not mock out the HashSet because the bug &lt;em&gt;was in the use of&lt;/em&gt; the HashSet.  I could not run the application 1000 times to statistically see the fault, because the behavior did not change from run to run.  The only thing that seemed able to &lt;em&gt;sometimes&lt;/em&gt; expose the fault was a recompile!  And I wasn&amp;#8217;t about to put my system into a &lt;em&gt;recompile-til-fail&lt;/em&gt; loop.&lt;/p&gt;


	&lt;p&gt;Why a recompile?  I suppose it has something to do with the values of internal addresses and their effect upon the hash values within the HashSet.&lt;/p&gt;


	&lt;p&gt;So, here, finally, after 10 years of being a die-hard TDDer, I have encountered a bug that I could not &lt;span class="caps"&gt;TDD&lt;/span&gt; my way out of.  To solve it, I had to &lt;em&gt;guess&lt;/em&gt;.  To solve it, I had to go open-loop.  To solve it, I had to &lt;em&gt;assume&lt;/em&gt; that I had found the cause, without being sure.  As a result, I am not certain that I have actually solved the problem.  It may be that a day or a year from now that acceptance test will fail again; and I&amp;#8217;ll be back scratching my head and debugging.&lt;/p&gt;


	&lt;p&gt;(sigh).&lt;/p&gt;</description>
      <pubDate>Thu, 13 Aug 2009 13:56:12 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:77d9e018-e6ae-4c00-9b91-223870f3b2b4</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/08/13/to-test-the-untestable-bug</link>
    </item>
    <item>
      <title>Over the next month..</title>
      <description>&lt;p&gt;I&amp;#8217;m off on a round of conferences, classes and talks soon, so I figured I&amp;#8217;d list them here.

&lt;p&gt;In about 2 weeks, I&amp;#8217;ll be at Agile2009.  While there, I&amp;#8217;ll be doing a workshop called &lt;a href=http://agile2009.agilealliance.org/node/1953&gt;Treating Errorhandling as a First Class Consideration in Design&lt;/a&gt;.  This might be as much tutorial as workshop.  I&amp;#8217;ve been collecting a lot of material on error handling over the past few years and it will be nice to present some of it.

&lt;p&gt;I&amp;#8217;ll also be doing a talk called &lt;a href=http://agile2009.agilealliance.org/node/864&gt;Test Driven Development: Ten Years Later&lt;/a&gt; with Steve Freeman on the main stage.  We gave this talk at QCon London last year. It&amp;#8217;s chock-full of history and reminiscences.  

&lt;p&gt;Some people in the Software Craftsmanship community pulled a sneaky and organized &lt;a href=http://scna.softwarecraftsmanship.org/&gt;Software Craftsmanship North America (SCNA)&lt;/a&gt;, a one-day conference during Agile2009 across the street.  I&amp;#8217;ll be speaking there as well.   

&lt;p&gt;Later in the week at Agile, I&amp;#8217;ll be doing a workshop with Naresh Jain called &lt;a href=http://agile2009.agilealliance.org/node/2257&gt;
Styles of &lt;span class="caps"&gt;TDD&lt;/span&gt;: First Test&lt;/a&gt;.  Naresh has had a long-standing interest in the different ways that different people approach &lt;span class="caps"&gt;TDD&lt;/span&gt;, and we hope to throw the spotlight on that aspect in the workshop. Brett Schuchert and I will also be doing something terrifying with legacy code in public early one morning during the conference.  Details as it finalizes.

&lt;p&gt;It should come as no surprise to readers of this blog that I&amp;#8217;m interested in functional programming.  I&amp;#8217;ve had a casual interest for a while, but recently, I&amp;#8217;ve decided to go full bore and dedicate whatever spare time I have to it &amp;#8211; to the exclusion of the other design and programming topics I spend time investigating/thinking about.  So, the week after Agile, I&amp;#8217;m going to &lt;a href=http://www.cs.nott.ac.uk/~gmh/icfp09.html&gt;&lt;span class="caps"&gt;ICFP&lt;/span&gt;&lt;/a&gt; and its companion practitioner conferences &lt;a href=http://www.defun2009.info/blog/tutorial-schedule/&gt;&lt;span class="caps"&gt;DEFUN2009&lt;/span&gt;&lt;/a&gt; and &lt;a href=http://cufp.galois.com/&gt;&lt;span class="caps"&gt;CUFP&lt;/span&gt;&lt;/a&gt;.  I&amp;#8217;m looking forward to meeting some of the people who&amp;#8217;ve been helping me on and off and chatting with me on irc and mailing lists.  

&lt;p&gt;A week or so after that, I&amp;#8217;ll be teaching a &lt;a href=http://www.crisp.se/tdd/feathers/20090915&gt;Three-day &lt;span class="caps"&gt;TDD&lt;/span&gt;/Refactoring course in Stockholm&lt;/a&gt;.  There are still sign ups available. I&amp;#8217;m looking forward to that trip as well.

&lt;p&gt;Looking out past September, I&amp;#8217;ll be speaking at &lt;a href=http://jaoo.dk/aarhus-2009/&gt;&lt;span class="caps"&gt;JAOO&lt;/span&gt;&lt;/a&gt; in Aarhus, and &lt;a href=http://agilevancouver.ca/&gt;Agile Vancouver&lt;/a&gt;. More about those later as the talk times and topics finalize.</description>
      <pubDate>Thu, 13 Aug 2009 09:50:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:4ef72785-1549-4b79-977b-d482ba9acd71</guid>
      <author>Michael Feathers</author>
      <link>http://blog.objectmentor.com/articles/2009/08/13/over-the-next-month</link>
      <category>Michaels Musings</category>
    </item>
    <item>
      <title>Jarvis March in Clojure</title>
      <description>&lt;p&gt;OK, all you Clojure gurus, I need your help.  I need to speed this algorithm up.&lt;/p&gt;


	&lt;p&gt;Just for fun I thought I&amp;#8217;d write the Jarvis March algorithm in Clojure.  This algorithm is for finding the convex hull of a collection of points.  The basic idea is really simple.  Imagine that all the points in the collection are represented by nails in a board.  Find the left-most nail and tie a string to it.  Then wind the string around the nails.  The string will only touch nails that are part of the convex hull.&lt;/p&gt;


	&lt;p&gt;The details are not really that much more difficult.  You start at the left-most point and calculate the angle from vertical required to touch every other point.  The point with the minimum angle is the next point.  You keep going around looking finding points with the minimum angle that is greater than the previous angle. When you get back to the starting point you are done.&lt;/p&gt;


	&lt;p&gt;Calculating angles can be time consuming, so I use a psuedo-angle algorithm.  It doesn&amp;#8217;t calculate the actual angle, rather it is a function that increases with the true angle, and goes from [0, 4).&lt;/p&gt;


The code is pretty simple.  
&lt;pre&gt;
(ns convexHull.convex-hull
  (:use clojure.contrib.math))

(defn quadrant-one-pseudo-angle [dx dy]
  (/ dx (+ dy dx)))

(defn pseudo-angle [[dx dy]]
  (cond
    (and (= dx 0) (= dy 0))
    0

    (and (&amp;gt;= dx 0) (&amp;gt; dy 0))
    (quadrant-one-pseudo-angle dx dy)

    (and (&amp;gt; dx 0) (&amp;lt;= dy 0))
    (+ 1 (quadrant-one-pseudo-angle (abs dy) dx))

    (and (&amp;lt;= dx 0) (&amp;lt; dy 0))
    (+ 2 (quadrant-one-pseudo-angle (abs dx) (abs dy)))

    (and (&amp;lt; dx 0) (&amp;gt;= dy 0))
    (+ 3 (quadrant-one-pseudo-angle dy (abs dx)))

    :else nil))

(defn point-min [[x1 y1 :as p1] [x2 y2 :as p2]]
  (cond
    (&amp;lt; x1 x2)
    p1

    (= x1 x2)
    (if (&amp;lt; y1 y2) p1 p2)

    :else
    p2))

(defn find-min-point [points]
  (reduce point-min points))

(defn delta-point [[x1 y1] [x2 y2]]
  [(- x1 x2) (- y1 y2)])

(defn angle-and-point [point base]
  [(pseudo-angle (delta-point point base)) point])

(defn min-angle-and-point [ap1 ap2]
  (if (&amp;lt; (first ap1) (first ap2)) ap1 ap2))

(defn find-point-with-least-angle-from [base angle points]
  (reduce min-angle-and-point
    (remove
      #(&amp;lt; (first %) angle)
      (map #(angle-and-point % base)
        (remove
          (fn [p] (= base p))
          points)))))

(defn hull [points]
  (println "Start")
  (let [starting-point (find-min-point points)]
    (println starting-point)
    (loop [hull-list [starting-point] angle 0 last-point starting-point]
      (let [[angle next-point] (find-point-with-least-angle-from last-point angle points)]
        (if (= next-point (first hull-list))
          hull-list
          (recur (conj hull-list next-point) angle next-point))))))
&lt;/pre&gt;

I execute it with this:
&lt;pre&gt;
(ns convexHull.time-hull
  (:use convexHull.convex-hull))

(def r (java.util.Random.))
(defn rands [] (repeatedly #(.nextGaussian r)))
(defn points [] (take 400000 (partition 2 (rands))))
(let [hull-points (time (hull (points)))]
  (printf "Points: %d\n" (count hull-points))
  (doseq [x hull-points] (println x)))
&lt;/pre&gt;

	&lt;p&gt;This takes &lt;em&gt;way&lt;/em&gt; too long to run.  The equivalent java program will do a million points in half a second.  This one is taking 25 seconds to do a half-million points.  It won&amp;#8217;t even &lt;em&gt;do&lt;/em&gt; a million points.  It slows way way down and then runs out of memory.  (There must be some kind of disk caching going on or something.)&lt;/p&gt;


	&lt;p&gt;Anyway, I&amp;#8217;d be interested in seeing how a real Clojure programmer would speed this program up.&lt;/p&gt;</description>
      <pubDate>Tue, 11 Aug 2009 21:10:21 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:fd5cfe9d-1538-4efa-9664-44c3c855f848</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/08/11/jarvis-march-in-clojure</link>
      <category>Uncle Bob's Blatherings</category>
    </item>
    <item>
      <title>Naming and Body Language in Functional Code</title>
      <description>&lt;p&gt;I wrote a blog the other day about functional refactoring and I had what I thought was a good example:

&lt;code&gt;&lt;pre&gt;
absPosition :: Buffer -&amp;gt; Int
absPosition (Buffer (x, y) contents) = x + lenPreviousLines contents
  where lenPreviousLines = 
    foldr ((+).length) 0 . take y . terminatedLines
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Almost immediately, I saw replies on a couple of forums (including this one) which pointed out that I could&amp;#8217;ve written the code this way:

&lt;code&gt;&lt;pre&gt;
absPosition (Buffer (x, y) contents) = x + lenPreviousLines contents
  where lenPreviousLines = 
    sum . map length . take y . terminatedLines
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;It&amp;#8217;s funny, I thought of using &lt;code&gt;sum&lt;/code&gt; instead of &lt;code&gt;foldr&lt;/code&gt; back when I was using Haskell&amp;#8217;s line function.  The code I had looked like this:

&lt;code&gt;&lt;pre&gt;
absPosition (Buffer (x, y) contents) = x + lenPreviousLines contents
  where lenPreviousLines = 
    foldr ((+).((+1).length)) 0 . take y . lines
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;But, I realized that the code wasn&amp;#8217;t in great shape for &lt;code&gt;sum&lt;/code&gt;, so I created &lt;code&gt;terminatedLines&lt;/code&gt;, used it and promptly forgot to do the refactoring I set out to do.

&lt;code&gt;&lt;pre&gt;
terminatedLines :: String -&amp;gt; [String]
terminatedLines = map (++ "\n") . lines
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;From an imperative point of view, &lt;code&gt;terminatedLines&lt;/code&gt; looks a bit silly: &lt;i&gt;What?? You&amp;#8217;re going to append a newline to each line in a list of lines you just created just so that you can count it??&lt;/i&gt; But, I suspect 
that it isn&amp;#8217;t that bad.  The evaluator pulls values from each line and as it reaches the end of one it should just put a newline at the end of it.  If I&amp;#8217;m wrong about this, please let me know.

&lt;p&gt;In any case, I agree that the code looks better with &lt;code&gt;sum&lt;/code&gt; that it does with &lt;code&gt;foldr (+) 0&lt;/code&gt;.  The big question is &amp;#8211; should we refactor any more?

&lt;p&gt; Someone with the handle &lt;i&gt;sterl&lt;/i&gt; suggested a very cool trick.  I could drop the where clause like this:

&lt;code&gt;&lt;pre&gt;
absPosition (Buffer (x, y) contents) = 
  x + (sum . map length . take y . terminatedLines) contents
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;And then move on to this:

&lt;code&gt;&lt;pre&gt;
absPosition (Buffer (x, y) contents) = 
  sum . (x:) . map length . take y . terminatedLines $ contents
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;What&amp;#8217;s going on here?  Well as &lt;i&gt;sterl&lt;/i&gt; put it, we&amp;#8217;re summing anyway so why not prepend the &lt;code&gt;x&lt;/code&gt; onto the list that we are already summing? 

&lt;p&gt;Part of me likes this and part of me doesn&amp;#8217;t.  One the one hand, it&amp;#8217;s brief, but on the other hand, the code isn&amp;#8217;t telling us why it is doing what it is doing anymore. In the original code, there is an algorithm:
&lt;blockquote&gt;To get the absolute position, add the x position of the location to the sum of the lengths of all of the previous lines.&lt;/blockquote&gt;

&lt;p&gt;In the new code, the algorithm is:
&lt;blockquote&gt;To get the absolute position, sum the current x position with the lengths of all of the previous lines.&lt;/blockquote&gt;

&lt;p&gt;Wait, that&amp;#8217;s sort of the same, isn&amp;#8217;t it?

&lt;p&gt;This example points to a fundamental dilemma that I have with naming in Haskell.  I&amp;#8217;m used to introducing names in lower-level languages to bridge the gap between intention and mechanism, but what happens when your mechanism is so high-level that it can speak for itself?  Maybe we don&amp;#8217;t need names as much?

&lt;p&gt;Now, I know as I write this that someone is going to look at this as an extreme statement.  It isn&amp;#8217;t. Names are useful, and indispensable, but really they are only one of several ways of communicating meaning.  In each case, we have to pick the right tool for the job.  With Haskell, I think that programmers communicate with structure as much as they communicate with names.  It&amp;#8217;s the body-language of their code.</description>
      <pubDate>Tue, 11 Aug 2009 12:25:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:571c0f66-0389-492d-93c5-2992eedf53af</guid>
      <author>Michael Feathers</author>
      <link>http://blog.objectmentor.com/articles/2009/08/11/naming-and-body-language-in-functional-code</link>
      <category>Michaels Musings</category>
    </item>
    <item>
      <title>TDD and FP</title>
      <description>&lt;p&gt;No, this isn&amp;#8217;t a blog about how to do &lt;span class="caps"&gt;TDD&lt;/span&gt; in a functional language.  Rather, it&amp;#8217;s a blog about the similarities between the two disciplines.&lt;/p&gt;


	&lt;p&gt;First, a quick definition.  Functional Programming is programming with functions.  In particular, functions that have no side effects.  A function that has no side effects is a function that returns the same value given the same inputs irrespective of the state of any other part of the system.&lt;/p&gt;


	&lt;p&gt;Does this mean that functions in a functional program are truly free of all side-effects?  Clearly not, since they are usually running on machines where the machine instructions are all about side effects.  It&amp;#8217;s just that all the side effects have been cancelled out by the time the a true function returns.  The function leaves no residual state behind.&lt;/p&gt;


	&lt;p&gt;A unit test, properly written in &lt;span class="caps"&gt;TDD&lt;/span&gt; style, has no side effects.  Every time you run it, it will give you the same (hopefully green) result.  You can run as many tests as you like, in any order you like, but they&amp;#8217;ll always give you the same result.  Why?  Because they leave no state behind.  They have no side-effects.&lt;/p&gt;


	&lt;p&gt;It&amp;#8217;s not that the operations executed by the unit tests don&amp;#8217;t have side effects.  Most of the time they do, since most of the time we are writing them in languages (like Java) that are rife with side effects.  But that&amp;#8217;s not relevant since all those side effects get cancelled out by the time the unit test completes.&lt;/p&gt;


	&lt;p&gt;Does the function you are testing create files?  That&amp;#8217;s ok, your test will delete them before it completes.  Does the function you are testing create rows in a database?  That&amp;#8217;s OK, your tests will remove them before it finishes.  Does the function you are testing change any state at all?  If so, the unit test will put that state back where it was before the test was run.  Unit tests are atomic operations that leave the state of the system unchanged!&lt;/p&gt;


	&lt;p&gt;In short, code written with &lt;span class="caps"&gt;TDD&lt;/span&gt; is code that has been assembled into pairs that have no side effects.  One side of the pair is a unit test, and the other side of the pair is production code.  Together they are functional, even if separate they are not.&lt;/p&gt;


	&lt;p&gt;Thus, &lt;span class="caps"&gt;TDD&lt;/span&gt; is Functional Programming (of a kind).  If your unit tests are very granular, you are more likely to write your production code in a functional style; or at least in a style in which side-effects are so localized that they can be managed within the scope of a single test.&lt;/p&gt;


	&lt;p&gt;Certainly &lt;span class="caps"&gt;TDD&lt;/span&gt; is not a replacement for learning a functional language.  I think there&amp;#8217;s much to be gained by learning Haskell, or Scala, or Clojure.  However, &lt;span class="caps"&gt;TDD&lt;/span&gt; &lt;em&gt;is&lt;/em&gt; a style of programming that encourages programmers to severely limit side-effects and keep them manageable within very small scopes.&lt;/p&gt;</description>
      <pubDate>Sat, 08 Aug 2009 16:31:10 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:68440555-c52f-4a75-bdb3-6e5da4a9f419</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/08/08/tdd-and-fp</link>
    </item>
    <item>
      <title>Using Clojure for Scripting</title>
      <description>&lt;p&gt;Clojure makes a nice language for writing scripts that explore things on the filesystem.  For example, here is a cute little program that explores the FitNesse source tree counting the lines of production java code and comparing it to the lines of unit test code.&lt;/p&gt;


&lt;pre&gt;

(use 'clojure.contrib.duck-streams)

(def file-counts
  (map
    #(list (.toString %) (count (read-lines %)))
    (remove #(.isDirectory %)
      (file-seq (file-str "~/projects/FitNesseGit/src/fitnesse")))))

(defn count-lines-that-end-with [file-counts suffix]
  (reduce +
    (map second
      (filter #(.endsWith (first %) suffix) file-counts))))

(def java-count (count-lines-that-end-with file-counts ".java"))
(def test-count (count-lines-that-end-with file-counts "Test.java"))

(printf "Java lines: %d\n" java-count)
(printf "Test lines: %d\n" test-count)
(printf "Test pct: %.1f\n" (double (* 100 (/ test-count java-count))))
&lt;/pre&gt;</description>
      <pubDate>Sat, 08 Aug 2009 14:14:07 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:ada5a2eb-c1fa-4853-905f-7cdcd02d8d60</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/08/08/using-clojure-for-scripting</link>
      <category>Uncle Bob's Blatherings</category>
    </item>
    <item>
      <title>Imposing the Edges Later</title>
      <description>&lt;p&gt;Here&amp;#8217;s what wikipedia has to say about lazy evaluation: 

&lt;blockquote&gt;The benefits of lazy evaluation include: performance increases due to avoiding unnecessary calculations, avoiding error conditions in the evaluation of compound expressions, the ability to construct infinite data structures, and the ability to define control structures as regular functions rather than built-in primitives.&lt;/blockquote&gt;

&lt;p&gt;It&amp;#8217;s all true, but I think it misses a point.  One of the nicest things about lazy evaluation is that it enables a different form of abstraction.  Take a look at &lt;a href=http://www.physics.emory.edu/~weeks/software/mandel.c&gt;this code&lt;/a&gt;.  It computes the &lt;a href=http://en.wikipedia.org/wiki/Mandelbrot_set&gt;Mandelbrot Set.&lt;/a&gt;  There are many ways to code up this algorithm, but the code I just linked to is very typical &amp;#8211; it&amp;#8217;s a doubly nested loop which iterates over a specific rectangle in the complex plane.  It&amp;#8217;s hard to see anything that&amp;#8217;s awkward about its iteration strategy in a procedural language &amp;#8211; the algorithm does require starting and ending points in the plane.

&lt;p&gt;Let&amp;#8217;s look at a different way of approaching this.  Here&amp;#8217;s part of a Mandelbrot Set generator in Haskell:

&lt;code&gt;&lt;pre&gt;
mandelbrot :: Double -&amp;gt; [[Int]]
mandelbrot incrementSize =
  [[ escapeIterations $ translate offset . translate (x,y) . mandel
    | x &amp;lt;- increments]
    | y &amp;lt;- increments] 
   where increments = [0.0, incrementSize .. ]

window :: (Int, Int) -&amp;gt; (Int, Int) -&amp;gt; [[a]] -&amp;gt; [[a]]
window (x0, x1) (y0, y1) = range y0 y1 . map (range x0 x1)
  where range m n = take (n-m) . drop m

&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;The interesting bit is the &lt;code&gt;mandelbrot&lt;/code&gt; function.  It contains a doubly-nested list comprehension which, essentially, mimics the behavior of a doubly-nested loop in the procedural algorithm.  However, there is one interesting difference.  This list comprehension actually represents the mandelbrot computation across a full quarter of the infinite plane &amp;#8211; it goes from zero to infinity in x and y.  All we have to do is pass it an increment size and it is configured to create that grid. If we want to zoom in to a particular place in the Mandelbrot Set, we can use the &lt;code&gt;window&lt;/code&gt; function like this:

&lt;code&gt;&lt;pre&gt;
-- compute the mandelbrot from (10,10) inclusive to
-- (20,20) exclusive with an increment of 0.05 

window (10, 20) (10, 20) $ mandelbrot 0.05
&lt;/pre&gt;&lt;/code&gt;   

&lt;p&gt;The trick to this code is in &lt;code&gt;window&lt;/code&gt;&amp;#8217;s &lt;code&gt;range&lt;/code&gt; computation.  It takes a starting position, an ending position, and a list and it drops all of the elements of the list before the starting position, without evaluating them, and then it takes, from the front of the new list, &lt;code&gt;end - start&lt;/code&gt; elements, giving us a sub-range from the original list.  When that elements of that sub-list are evaluated, the computation for each point in the window occurs.    

&lt;p&gt;This code yields the computation that we want and the neat thing is, we are really only computing the piece we specified with &lt;code&gt;window&lt;/code&gt;.  We&amp;#8217;ve essentially formed a general computation and imposed the edges later.

&lt;p&gt;Looking back now at the imperative mandelbrot code, it&amp;#8217;s easy to see that it was, in a way, mixing two concerns.  The code which determined the range was mixed with the code which generated the set.  Laziness allows us to separate the two concerns.  

	&lt;p&gt;&lt;i&gt;Note: There are much more direct ways of computing the Mandelbrot Set in Haskell.  Here&amp;#8217;s one which is &lt;a href=http://warp.povusers.org/MandScripts/haskell.html&gt;particularly brief.&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Sat, 08 Aug 2009 11:12:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:04c166b9-ce54-4fda-8121-7e8898845702</guid>
      <author>Michael Feathers</author>
      <link>http://blog.objectmentor.com/articles/2009/08/08/imposing-the-edges-later</link>
      <category>Michaels Musings</category>
    </item>
    <item>
      <title>Java calling Clojure.</title>
      <description>&lt;p&gt;While I think Clojure is an interesting language, in order for it to be of real practical use, I must be able to use it in conjunction with other systems I am working on.  Specifically, I&amp;#8217;d like to write some FitNesse tools in Clojure;  but for that to work, I&amp;#8217;ll need to call into my Clojure code from Java.&lt;/p&gt;


	&lt;p&gt;Today, my son Justin and I managed to do just that by following the instruction in Stuart Halloway&amp;#8217;s &lt;a href="http://www.pragprog.com/titles/shcloj/programming-clojure"&gt;book&lt;/a&gt;, the Clojure api &lt;a href="http://clojure.org/api#toc388"&gt;website&lt;/a&gt;, and Mark Volkmann&amp;#8217;s very useful &lt;a href="http://java.ociweb.com/mark/clojure/article.html"&gt;site&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Be advised, that it takes a bit of fiddling to get this to work.  You will have to jockey around with your classpaths and output directories.  But it&amp;#8217;s not actually that hard to do, and the results can be very rewarding.&lt;/p&gt;


	&lt;p&gt;We implemented the Bowling game (again), but this time we wrote the unit tests in Java, and had them call into Clojure.  From the point of view of the Java tests, it looked just like we were calling into java code.  The tests had no idea that this was Clojure.&lt;/p&gt;


Here are the tests:
&lt;pre&gt;
package bowling;

import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;

public class BowlingTest {
  private Game g;

  @Before
  public void setup() {
    g = new Game();
  }

  @Test
  public void roll() throws Exception {
    g.roll(0);
  }

  @Test
  public void gutterGame() throws Exception {
    rollMany(20, 0);
    assertEquals(0, g.score());
  }

  private void rollMany(int n, int pins) {
    for (int i=0; i&amp;lt; n; i++) {
      g.roll(pins);
    }
  }

  @Test
  public void allOnes() throws Exception {
    rollMany(20, 1);
    assertEquals(20, g.score());    
  }

  @Test
  public void oneSpare() throws Exception {
    g.roll(5);
    g.roll(5);
    g.roll(3);
    rollMany(17, 0);
    assertEquals(16, g.score());
  }

  @Test
  public void oneStrike() throws Exception {
    g.roll(10);
    g.roll(5);
    rollMany(17,0);
    assertEquals(20, g.score());
  }

  @Test
  public void perfectGame() throws Exception {
    rollMany(12, 10);
    assertEquals(300, g.score());
  }

  @Test
  public void allSpares() throws Exception {
    rollMany(21, 5);
    assertEquals(150, g.score());
  }
}
&lt;/pre&gt;

The clojure code to make them pass looks like this:
&lt;pre&gt;
(ns bowling.Game
  (:gen-class
    :state state
    :init init
    :methods [
    [roll [int] void]
    [score [] int]
    ]))

(defn -init [] [[] (atom [])])

(defn -roll [this pins]
  (reset! (.state this) (conj @(.state this) pins)))

(declare score-frames)

(defn -score [this]
  (reduce + (take 10 (score-frames [] (conj @(.state this) 0)))))

(defn score-frames [scores [first second third :as rolls]]
  (cond
    (or (empty? rolls) (nil? second) (nil? third)) scores
    (= 10 first) (recur (conj scores (+ 10 second third)) (next rolls))
    (= 10 (+ first second)) (recur (conj scores (+ 10 third)) (nnext rolls))
    :else
    (recur (conj scores (+ first second)) (nnext rolls))))
&lt;/pre&gt;

	&lt;p&gt;The magic is all up in that (ns bowling.game&amp;#8230; block.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;The name of the java class is Game in the bowling package, or just bowling.Game.&lt;/li&gt;
		&lt;li&gt;Clojure will create a special member function named &lt;em&gt;state&lt;/em&gt; that you can use to squirrel away the state variables of the class.&lt;/li&gt;
		&lt;li&gt;A function named &lt;em&gt;-init&lt;/em&gt; will be called when your class is constructed.  You must write this function to return a vector containing 1) a vector of all the arguments to pass to the base class constructor (in my case none), and the initial state of the newly created instance, (in my case an empty vector stuffed into an atom)  &lt;/li&gt;
		&lt;li&gt;The class will have two new methods, &lt;em&gt;roll&lt;/em&gt;, which takes an int and returns void, and &lt;em&gt;score&lt;/em&gt; which takes nothing and returns an int.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;When a method is called on the instance, Clojure automatically invokes a function of the same name, but prefixed by a -, so -roll and -score are the implementations of the &lt;em&gt;roll&lt;/em&gt; and &lt;em&gt;score&lt;/em&gt; methods.  Note that each of these functions take a &lt;em&gt;this&lt;/em&gt; argument.  You can get the state out of &lt;em&gt;this&lt;/em&gt; by saying (.state this).&lt;/p&gt;


	&lt;p&gt;From a source code point of view, that&amp;#8217;s about all there is to it.  But how do you compile this into a java .class file?&lt;/p&gt;


Here&amp;#8217;s what we did.  We created a new file named compile.clj that looks like this:
&lt;pre&gt;
(set! *compile-path* "../../classes")
(compile 'bowling.Game)
&lt;/pre&gt;
We can run this file from our &lt;span class="caps"&gt;IDE&lt;/span&gt; (IntelliJ using the LAClojure plugin) and it will compile quite nicely.  But there are a few things you have to make sure you do.

	&lt;ul&gt;
	&lt;li&gt;Find out where your &lt;span class="caps"&gt;IDE&lt;/span&gt; puts the .class files, and set the &lt;em&gt;&lt;strong&gt;compile-path&lt;/strong&gt;&lt;/em&gt; variable to that directory.&lt;/li&gt;
		&lt;li&gt;Also make sure that directory is in your classpath.&lt;/li&gt;
		&lt;li&gt;Make sure that directory exists!&lt;/li&gt;
		&lt;li&gt;Also make sure that your source file directory (the directory that contains the packages) is in your classpath. (I know&amp;#8230; but that&amp;#8217;s apparently what it takes.)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;You will get errors.  And the errors aren&amp;#8217;t particularly informative.  The key to understanding them is to look at the backtrace of the exceptions they throw.  Notice, for example, if the function &amp;#8220;WriteClassFile&amp;#8221; (or something like that) is buried in the backtrace.  If so, you are probably having trouble writing your class file.&lt;/p&gt;


	&lt;p&gt;In the end, we wrote up an ant script that compiled our clojure and our java together.  (You have to compile them in the right order!  If java calls Clojure, those .class files have to exist before the java will compile!)&lt;/p&gt;


	&lt;p&gt;The ant script we used was created for us by IntelliJ, and then we modified it to get it to work.  I include it here with the caveat that we made it work, but we didn&amp;#8217;t make it &amp;#8220;right&amp;#8221;.   You can ignore most of the stuff at the beginning.  The interesting part is the &lt;em&gt;Clojure&lt;/em&gt; target, and the &lt;em&gt;clean&lt;/em&gt; target.&lt;/p&gt;


&lt;pre&gt;
&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;project name="bowlingforjunit" default="all"&amp;gt;

  &amp;lt;property file="bowlingforjunit.properties"/&amp;gt;
  &amp;lt;!-- Uncomment the following property if no tests compilation is needed --&amp;gt;
  &amp;lt;!-- 
  &amp;lt;property name="skip.tests" value="true"/&amp;gt;
   --&amp;gt;

  &amp;lt;!-- Compiler options --&amp;gt;

  &amp;lt;property name="compiler.debug" value="on"/&amp;gt;
  &amp;lt;property name="compiler.generate.no.warnings" value="off"/&amp;gt;
  &amp;lt;property name="compiler.args" value=""/&amp;gt;
  &amp;lt;property name="compiler.max.memory" value="128m"/&amp;gt;
  &amp;lt;patternset id="ignored.files"&amp;gt;
    &amp;lt;exclude name="**/CVS/**"/&amp;gt;
    &amp;lt;exclude name="**/SCCS/**"/&amp;gt;
    &amp;lt;exclude name="**/RCS/**"/&amp;gt;
    &amp;lt;exclude name="**/rcs/**"/&amp;gt;
    &amp;lt;exclude name="**/.DS_Store/**"/&amp;gt;
    &amp;lt;exclude name="**/.svn/**"/&amp;gt;
    &amp;lt;exclude name="**/.pyc/**"/&amp;gt;
    &amp;lt;exclude name="**/.pyo/**"/&amp;gt;
    &amp;lt;exclude name="**/*.pyc/**"/&amp;gt;
    &amp;lt;exclude name="**/*.pyo/**"/&amp;gt;
    &amp;lt;exclude name="**/.git/**"/&amp;gt;
    &amp;lt;exclude name="**/.sbas/**"/&amp;gt;
    &amp;lt;exclude name="**/.IJI.*/**"/&amp;gt;
    &amp;lt;exclude name="**/vssver.scc/**"/&amp;gt;
    &amp;lt;exclude name="**/vssver2.scc/**"/&amp;gt;
  &amp;lt;/patternset&amp;gt;
  &amp;lt;patternset id="library.patterns"&amp;gt;
    &amp;lt;include name="*.zip"/&amp;gt;
    &amp;lt;include name="*.war"/&amp;gt;
    &amp;lt;include name="*.egg"/&amp;gt;
    &amp;lt;include name="*.ear"/&amp;gt;
    &amp;lt;include name="*.swc"/&amp;gt;
    &amp;lt;include name="*.jar"/&amp;gt;
  &amp;lt;/patternset&amp;gt;
  &amp;lt;patternset id="compiler.resources"&amp;gt;
    &amp;lt;include name="**/?*.properties"/&amp;gt;
    &amp;lt;include name="**/?*.xml"/&amp;gt;
    &amp;lt;include name="**/?*.gif"/&amp;gt;
    &amp;lt;include name="**/?*.png"/&amp;gt;
    &amp;lt;include name="**/?*.jpeg"/&amp;gt;
    &amp;lt;include name="**/?*.jpg"/&amp;gt;
    &amp;lt;include name="**/?*.html"/&amp;gt;
    &amp;lt;include name="**/?*.dtd"/&amp;gt;
    &amp;lt;include name="**/?*.tld"/&amp;gt;
    &amp;lt;include name="**/?*.ftl"/&amp;gt;
  &amp;lt;/patternset&amp;gt;

  &amp;lt;!-- JDK definitions --&amp;gt;

  &amp;lt;property name="jdk.bin.1.6" value="${jdk.home.1.6}/bin"/&amp;gt;
  &amp;lt;path id="jdk.classpath.1.6"&amp;gt;
    &amp;lt;fileset dir="${jdk.home.1.6}"&amp;gt;
      &amp;lt;include name="lib/deploy.jar"/&amp;gt;
      &amp;lt;include name="lib/dt.jar"/&amp;gt;
      &amp;lt;include name="lib/javaws.jar"/&amp;gt;
      &amp;lt;include name="lib/jce.jar"/&amp;gt;
      &amp;lt;include name="lib/management-agent.jar"/&amp;gt;
      &amp;lt;include name="lib/plugin.jar"/&amp;gt;
      &amp;lt;include name="lib/sa-jdi.jar"/&amp;gt;
      &amp;lt;include name="../Classes/charsets.jar"/&amp;gt;
      &amp;lt;include name="../Classes/classes.jar"/&amp;gt;
      &amp;lt;include name="../Classes/dt.jar"/&amp;gt;
      &amp;lt;include name="../Classes/jce.jar"/&amp;gt;
      &amp;lt;include name="../Classes/jconsole.jar"/&amp;gt;
      &amp;lt;include name="../Classes/jsse.jar"/&amp;gt;
      &amp;lt;include name="../Classes/laf.jar"/&amp;gt;
      &amp;lt;include name="../Classes/management-agent.jar"/&amp;gt;
      &amp;lt;include name="../Classes/ui.jar"/&amp;gt;
      &amp;lt;include name="lib/ext/apple_provider.jar"/&amp;gt;
      &amp;lt;include name="lib/ext/dnsns.jar"/&amp;gt;
      &amp;lt;include name="lib/ext/localedata.jar"/&amp;gt;
      &amp;lt;include name="lib/ext/sunjce_provider.jar"/&amp;gt;
      &amp;lt;include name="lib/ext/sunpkcs11.jar"/&amp;gt;
    &amp;lt;/fileset&amp;gt;
  &amp;lt;/path&amp;gt;

  &amp;lt;property name="project.jdk.home" value="${jdk.home.1.6}"/&amp;gt;
  &amp;lt;property name="project.jdk.bin" value="${jdk.bin.1.6}"/&amp;gt;
  &amp;lt;property name="project.jdk.classpath" value="jdk.classpath.1.6"/&amp;gt;

  &amp;lt;!-- Project Libraries --&amp;gt;

  &amp;lt;!-- Global Libraries --&amp;gt;

  &amp;lt;path id="library.clojure.classpath"&amp;gt;
    &amp;lt;pathelement location="/Users/unclebob/projects/clojure-build/lib/ant-launcher.jar"/&amp;gt;
    &amp;lt;pathelement location="/Users/unclebob/projects/clojure-build/lib/ant.jar"/&amp;gt;
    &amp;lt;pathelement location="/Users/unclebob/projects/clojure-build/lib/clojure-contrib.jar"/&amp;gt;
    &amp;lt;pathelement location="/Users/unclebob/projects/clojure-build/lib/clojure.jar"/&amp;gt;
    &amp;lt;pathelement location="/Users/unclebob/projects/clojure-build/lib/commons-codec-1.3.jar"/&amp;gt;
    &amp;lt;pathelement location="/Users/unclebob/projects/clojure-build/lib/commons-fileupload-1.2.1.jar"/&amp;gt;
    &amp;lt;pathelement location="/Users/unclebob/projects/clojure-build/lib/commons-io-1.4.jar"/&amp;gt;
    &amp;lt;pathelement location="/Users/unclebob/projects/clojure-build/lib/compojure.jar"/&amp;gt;
    &amp;lt;pathelement location="/Users/unclebob/projects/clojure-build/lib/hsqldb.jar"/&amp;gt;
    &amp;lt;pathelement location="/Users/unclebob/projects/clojure-build/lib/jetty-6.1.14.jar"/&amp;gt;
    &amp;lt;pathelement location="/Users/unclebob/projects/clojure-build/lib/jetty-util-6.1.14.jar"/&amp;gt;
    &amp;lt;pathelement location="/Users/unclebob/projects/clojure-build/lib/jline-0.9.94.jar"/&amp;gt;
    &amp;lt;pathelement location="/Users/unclebob/projects/clojure-build/lib/servlet-api-2.5-6.1.14.jar"/&amp;gt;
  &amp;lt;/path&amp;gt;

  &amp;lt;!-- Modules --&amp;gt;

  &amp;lt;!-- Module BowlingForJunit --&amp;gt;

  &amp;lt;dirname property="module.bowlingforjunit.basedir" file="${ant.file}"/&amp;gt;

  &amp;lt;property name="module.jdk.home.bowlingforjunit" value="${project.jdk.home}"/&amp;gt;
  &amp;lt;property name="module.jdk.bin.bowlingforjunit" value="${project.jdk.bin}"/&amp;gt;
  &amp;lt;property name="module.jdk.classpath.bowlingforjunit" value="${project.jdk.classpath}"/&amp;gt;

  &amp;lt;property name="compiler.args.bowlingforjunit" value="${compiler.args}"/&amp;gt;

  &amp;lt;property name="bowlingforjunit.output.dir" value="${module.bowlingforjunit.basedir}/classes"/&amp;gt;
  &amp;lt;property name="bowlingforjunit.testoutput.dir" value="${module.bowlingforjunit.basedir}/classes"/&amp;gt;

  &amp;lt;path id="bowlingforjunit.module.bootclasspath"&amp;gt;
    &amp;lt;!-- Paths to be included in compilation bootclasspath --&amp;gt;
  &amp;lt;/path&amp;gt;

  &amp;lt;path id="bowlingforjunit.module.classpath"&amp;gt;
    &amp;lt;path refid="${module.jdk.classpath.bowlingforjunit}"/&amp;gt;
    &amp;lt;pathelement location="/Library/junit4.6/junit-4.6.jar"/&amp;gt;
    &amp;lt;path refid="library.clojure.classpath"/&amp;gt;
    &amp;lt;pathelement location="${basedir}/classes"/&amp;gt;
  &amp;lt;/path&amp;gt;

  &amp;lt;path id="bowlingforjunit.runtime.module.classpath"&amp;gt;
    &amp;lt;pathelement location="${bowlingforjunit.output.dir}"/&amp;gt;
    &amp;lt;pathelement location="/Library/junit4.6/junit-4.6.jar"/&amp;gt;
    &amp;lt;path refid="library.clojure.classpath"/&amp;gt;
    &amp;lt;pathelement location="${basedir}/classes"/&amp;gt;
  &amp;lt;/path&amp;gt;

  &amp;lt;patternset id="excluded.from.module.bowlingforjunit"&amp;gt;
    &amp;lt;patternset refid="ignored.files"/&amp;gt;
  &amp;lt;/patternset&amp;gt;

  &amp;lt;patternset id="excluded.from.compilation.bowlingforjunit"&amp;gt;
    &amp;lt;patternset refid="excluded.from.module.bowlingforjunit"/&amp;gt;
  &amp;lt;/patternset&amp;gt;

  &amp;lt;path id="bowlingforjunit.module.sourcepath"&amp;gt;
    &amp;lt;dirset dir="${module.bowlingforjunit.basedir}"&amp;gt;
      &amp;lt;include name="src"/&amp;gt;
    &amp;lt;/dirset&amp;gt;
  &amp;lt;/path&amp;gt;

  &amp;lt;target name="compile" depends="clojure, compile.java" description="Compile module BowlingForJunit"/&amp;gt;

  &amp;lt;target name="compile.java" description="Compile module BowlingForJunit; production classes"&amp;gt;
    &amp;lt;mkdir dir="${bowlingforjunit.output.dir}"/&amp;gt;
    &amp;lt;javac destdir="${bowlingforjunit.output.dir}" debug="${compiler.debug}" nowarn="${compiler.generate.no.warnings}" 
           memorymaximumsize="${compiler.max.memory}" fork="true" executable="${module.jdk.bin.bowlingforjunit}/javac"&amp;gt;
      &amp;lt;compilerarg line="${compiler.args.bowlingforjunit}"/&amp;gt;
      &amp;lt;bootclasspath refid="bowlingforjunit.module.bootclasspath"/&amp;gt;
      &amp;lt;classpath refid="bowlingforjunit.module.classpath"/&amp;gt;
      &amp;lt;src refid="bowlingforjunit.module.sourcepath"/&amp;gt;
      &amp;lt;patternset refid="excluded.from.compilation.bowlingforjunit"/&amp;gt;
    &amp;lt;/javac&amp;gt;

    &amp;lt;copy todir="${bowlingforjunit.output.dir}"&amp;gt;
      &amp;lt;fileset dir="${module.bowlingforjunit.basedir}/src"&amp;gt;
        &amp;lt;patternset refid="compiler.resources"/&amp;gt;
        &amp;lt;type type="file"/&amp;gt;
      &amp;lt;/fileset&amp;gt;
    &amp;lt;/copy&amp;gt;
  &amp;lt;/target&amp;gt;

  &amp;lt;target name="clojure"&amp;gt;
    &amp;lt;java classname="clojure.lang.Compile"&amp;gt;
      &amp;lt;classpath&amp;gt;
        &amp;lt;path location="/Users/unclebob/projects/clojure/BowlingForJunit/classes"/&amp;gt;
        &amp;lt;path location="/Users/unclebob/projects/clojure/BowlingForJunit/src"/&amp;gt;        
        &amp;lt;path location="/Users/unclebob/projects/clojure/BowlingForJunit/src/bowling"/&amp;gt;
        &amp;lt;path location="/Users/unclebob/projects/clojure-build/lib/clojure.jar"/&amp;gt;
        &amp;lt;path location="/Users/unclebob/projects/clojure-build/lib/clojure-contrib.jar"/&amp;gt;  
      &amp;lt;/classpath&amp;gt;
      &amp;lt;sysproperty key="clojure.compile.path" value="/Users/unclebob/projects/clojure/BowlingForJunit/classes"/&amp;gt;
      &amp;lt;sysproperty key="java.awt.headless" value="true"/&amp;gt;
      &amp;lt;arg value="bowling.Game"/&amp;gt;
    &amp;lt;/java&amp;gt;
  &amp;lt;/target&amp;gt;

  &amp;lt;target name="clean" description="cleanup module"&amp;gt;
    &amp;lt;delete dir="${bowlingforjunit.output.dir}"/&amp;gt;
    &amp;lt;delete dir="${bowlingforjunit.testoutput.dir}"/&amp;gt;
    &amp;lt;mkdir  dir="${bowlingforjunit.output.dir}"/&amp;gt;
  &amp;lt;/target&amp;gt;

  &amp;lt;target name="all" depends="clean, compile" description="build all"/&amp;gt;
&amp;lt;/project&amp;gt;
&lt;/pre&gt;</description>
      <pubDate>Fri, 07 Aug 2009 17:00:43 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:6d45354f-02f4-4519-aebc-dad2102743cf</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/08/07/java-calling-clojure</link>
      <category>Uncle Bob's Blatherings</category>
    </item>
    <item>
      <title>As the tests get more specific, the code gets more generic.</title>
      <description>&lt;p&gt;I tweeted this not too long ago.  The basic idea is that as you add tests, the tests get more and more specific.  This makes sense since tests are, after all, specifications.  The more specifications you have, the more specific the whole body of specifications becomes.&lt;/p&gt;


	&lt;p&gt;As a general rule, good design dictates that the more specific your requirements become, the more general your code needs to be.  This is saying roughly the same thing as Greenspun&amp;#8217;s Tenth Rule of Programming: &amp;#8220;Any sufficiently complicated [...] program contains an ad hoc informally-specified bug-ridden slow implementation of half of Common Lisp.&amp;#8221;  Or rather, as more and more constraints pile upon a program, the designers look for ways to push those constraints out of the program itself and into the data.&lt;/p&gt;


	&lt;p&gt;In return for my tweet people asked for examples.&lt;/p&gt;


	&lt;p&gt;One of the better examples (though perhaps a bit trivial) is the &lt;a href="http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata"&gt;Prime Factors Kata&lt;/a&gt;.   This lovely little experiment grows and grows as you add test cases, and then suddenly collapses into an elegant three line algorithm.&lt;/p&gt;


	&lt;p&gt;The tests continue to become ever more specific.  The production code starts out &lt;em&gt;just as&lt;/em&gt; specific as the tests.  But with the second or third test the programmer must make a decision.  He can write the production code to mirror the tests (i.e. writing it as an if/else statement that detects which test is running and supplying the expected answer) or he can come up with some kind of more general algorithm that satisfies the tests without looking anything like them.&lt;/p&gt;


	&lt;p&gt;The algorithm grows and warps and twists; and then, just when it looks like it&amp;#8217;s destined to become a wretched mess; it simply evaporates into a lovely little three line nested loop.&lt;/p&gt;


	&lt;p&gt;We see the principle at work in other ways as well.  Often the programmers have a whole list of tests that they know must pass.  As they write them one by one, they write the production code that satisfies them.  Then, as in the &lt;a href="http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata"&gt;Bowling Game Kata&lt;/a&gt; the tests start to pass unexpectedly.  You were done with the code, and you weren&amp;#8217;t aware of it.  You continue writing tests, expecting one to fail, but they all pass.  The test code grows, but the production code remains the same.&lt;/p&gt;


	&lt;p&gt;Sometimes this happens in a less surprising way.  Sometimes you &lt;em&gt;know&lt;/em&gt; that you have implemented an algorithm that will pass all remaining tests, but you write those tests anyway because they are part of the specification&lt;/p&gt;


	&lt;p&gt;The point is that test code and production code do not grow at the same rate.  Indeed, as the application increases in complexity, the test code grows at a rate that is faster than the production code.  Sometimes the production code actually shrinks as the test code grows because the programmers moved a load of functionality out of the code and into the data.&lt;/p&gt;


	&lt;p&gt;Consider FitNesse.  A year ago there were 45,000 lines of code, of which 15,000 were tests, so 33% of the total were tests.&lt;/p&gt;


	&lt;p&gt;Now Fitnesse is 58,000 lines of code of which 26,000 are tests.  We added 13,000 lines of code overall, but 8,000 (61%), are tests! The tests have grown to over 44% of the total.&lt;/p&gt;</description>
      <pubDate>Thu, 06 Aug 2009 14:23:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:69954d56-0bc3-481c-86db-474de0f760e4</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/08/06/as-the-tests-get-more-specific-the-code-gets-more-generic</link>
      <category>Uncle Bob's Blatherings</category>
      <category>Clean Code</category>
    </item>
    <item>
      <title>Don't be lazy about lazy sequences.</title>
      <description>&lt;p&gt;Coding with infinite sequences is very powerful, but also very bizarre.  If you aren&amp;#8217;t careful you can get algorithms that work fine, but are O(N&lt;sup&gt;2) instead of O(N).&lt;/p&gt;


	&lt;p&gt;Consider the (partial-sums) function that I used in my previous &lt;a href="http://blog.objectmentor.com/articles/2009/08/05/generating-pi-in-clojure"&gt;blog&lt;/a&gt; on generating pi.&lt;/p&gt;


&lt;pre&gt;
(defn partial-sums [s]
  (lazy-seq
    (cons (first s) (add-streams (next s) (partial-sums s)))))
&lt;/pre&gt;  

	&lt;p&gt;This function takes in a list of (a b c&amp;#8230;) and returns a list of partial sums (a a+b a+b+c&amp;#8230;).  Trying to figure out how this function works is a bit mind-bending; at least for me; but here&amp;#8217;s how I visualize it.&lt;/p&gt;


It adds (next s) to (partial-sums s).  
&lt;pre&gt;
                   (next s)
                      |
                      V
              s: (a   b    c     d ...)
(partial-sum s):     (a   a+b  a+b+c ...)
&lt;/pre&gt;

	&lt;p&gt;Notice how the vertical columns are the sums that we want.  Notice also that each result is the sum of the previous result and the next element of s.  So verbally and visually this all makes sense.  But &lt;em&gt;algorithmically&lt;/em&gt; it can still be challenging to understand.  I mean, how do those values get calculated really?&lt;/p&gt;


	&lt;p&gt;Oh&amp;#8230;  And I should note&amp;#8230;  The function above doesn&amp;#8217;t work this way at all.  It&amp;#8217;s actually horrifically inefficient.  But I&amp;#8217;ll get to that, and to the solution.  First things first.&lt;/p&gt;


	&lt;p&gt;What allows this function to run is &lt;em&gt;lazy-evaluation&lt;/em&gt;.  All that really means is that an element of a list does not really exist until you ask for it.  At that point the program calculates what the element of the list should be and then returns it to you as if it was there all along.&lt;/p&gt;


	&lt;p&gt;In Clojure, when you build a sequence inside the (lazy-seq) form, it simply defers the execution of the procedures that generate the values of the sequence until those values are requested.  Look again at the function above.  When you call it, it simply returns immediately without doing anything.  The (lazy-seq) form simply short-circuits the execution of the function, deferring it for later.&lt;/p&gt;


	&lt;p&gt;So when (partial-sums) returns it gives you a sequence, but there&amp;#8217;s nothing in it!  However, as soon as you ask for the first element, the body of the (partial-sums) function will execute &lt;em&gt;just enough&lt;/em&gt; to give you the value of the first element.  No other elements are calculated.  When you ask for the next value, (partial-sums) will execute again, just enough to give you &lt;em&gt;that&lt;/em&gt; value.  And so on.&lt;/p&gt;


	&lt;p&gt;Knowing that, let&amp;#8217;s trace the execution.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;We call (partial-sums s) which returns a list (let&amp;#8217;s call it ps)&lt;/li&gt;
		&lt;li&gt;To get the first element of ps, (partial-sums) is lazily-invoked and simply returns &lt;span style="font-family:Courier New"&gt;(first s)&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;For the second element it returns the first element of the sequence produced by &lt;span style="font-family:Courier New"&gt;(add-streams (next s) (partial-sums s))&lt;/span&gt; &lt;br/&gt;which will be: &lt;span style="font-family:Courier New"&gt;(+ (first (next s)) (first s))&lt;/span&gt;&lt;/li&gt;
		&lt;li&gt;For the third element it returns the second element of the added streams, but the element is composed of yet another stream addition invoked by the recursive (partial-sums)  So it looks like this: &lt;br/&gt;&lt;span style="font-family:Courier New"&gt;(+ (first (next (next s)) (+ (first (next s)) (first s))&lt;/span&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&amp;#8220;Uh&amp;#8230;  Wait.&amp;#8221; I hear you say.   &amp;#8220;You mean that in order to calculate the third element, you have to add three elements?  Didn&amp;#8217;t we say that we could add the next element of s to the previous element of the partial sums?  Why do we have to do three additions?  Why does it seem to be doing this:&amp;#8221;&lt;/p&gt;


&lt;pre&gt;
(a b c)
  (a b c)
    (a b c)
&lt;/pre&gt;
Notice that the vertical columns &lt;em&gt;are&lt;/em&gt; the sums we are looking for; but calculating them requires a lot more work than just adding the next value to the previous sum!. 

	&lt;p&gt;&amp;#8220;But wait,&amp;#8221; you say again. &amp;#8220;I know something about Clojure.  Clojure &lt;em&gt;memoizes&lt;/em&gt; the list values.  Once you ask for a list element the first time, it never has to recalculate it again!  So when we get the third element of the result it &lt;em&gt;shouldn&amp;#8217;t&lt;/em&gt; have to recalculate the second.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;Partly right.  Once you lazily evaluate a list element, that element never has to be evaluated again.  It&amp;#8217;s in the list, and will simply be returned from the list.  But let me ask you this:  In the function above, where is the list that being asked &lt;em&gt;again&lt;/em&gt;?  Look closely.  There is no partial-sums result that is being asked for a value more than once.  Indeed, every time we need a value we create a new (partial-sums) list.  So we aren&amp;#8217;t taking advantage of the previous values because we&amp;#8217;re always creating a new list.&lt;/p&gt;


If you&amp;#8217;d like to prove this to yourself, you can run this fun little program.  
&lt;pre&gt;
(defn p [a b] (println a '+ b) (+ a b))

(defn add_streams [a b] (map p a b))

(defn partial-sums [s]
    (lazy-seq
      (cons (first s)
        (add_streams (next s) (partial-sums s)))))

(def w (iterate inc 1))
(println (take 5 (partial-sums w)))
&lt;/pre&gt;

Notice how I print every addition in the (p) function.  If you run this you&amp;#8217;ll get the following result:
&lt;pre&gt;
(2 + 1
1 2 + 1
3 + 3
3 2 + 1
3 + 3
4 + 6
6 2 + 1
3 + 3
4 + 6
5 + 10
10 15)
&lt;/pre&gt;

	&lt;p&gt;The jumble of numbers is evidence that the lazy evaluation is working.  As the println marches through the 5 partial sums, it causes each to be evaluated, causing each sum to be printed.  Notice how many sums are taken!  Ten additions for 5 partial sums.  It&amp;#8217;ll be 15 for 6, and 21 for 7.  Indeed, the number of additions required to calculate ps[n] is equal to ps[n-1].  A little thought will convince you that this is O(n&lt;/sup&gt;2).&lt;/p&gt;


	&lt;p&gt;To reduce this back to O(n), we need to stop creating a new list of partial-sums at each recursion, and use a single copy of the partial-sums result.  We can do this by saving the partial sums result in a var, and then using that in the add-streams call.&lt;/p&gt;


&lt;pre&gt;
(defn partial-sums [s]
    (def result (lazy-seq
      (cons (first s)
        (add_streams (next s) result)))) result)
&lt;/pre&gt;

	&lt;p&gt;This may bend your brain just a little bit more.  We are using the result &lt;em&gt;before&lt;/em&gt; we are done calculating it!  But that&amp;#8217;s ok, since we never use more than has &lt;em&gt;already been&lt;/em&gt; calculated&amp;#8230;&lt;/p&gt;


	&lt;p&gt;Running the program with this change yields the following output.&lt;/p&gt;


&lt;pre&gt;
(2 + 1
1 3 + 3
3 4 + 6
6 5 + 10
10 15)
&lt;/pre&gt;

	&lt;p&gt;&lt;em&gt;That&amp;#8217;s&lt;/em&gt; the O(n) behavior we wanted!  Each sum is calculated by adding the next element to the previous sum!  Hooray!&lt;/p&gt;


	&lt;p&gt;There&amp;#8217;s a lesson here.  You don&amp;#8217;t get the benefit of lazy sequences unless you &lt;em&gt;use&lt;/em&gt; the lazy sequences.  Creating a brand new one each time may generate the right answer, but it&amp;#8217;s lazy, and can burn a lot of execution cycles.&lt;/p&gt;


	&lt;p&gt;One problem I have with this solution is the creation of the global var &amp;#8216;result&amp;#8217;.  I&amp;#8217;m sure there&amp;#8217;s a way to create a local result; but I haven&amp;#8217;t found it yet.  (I tried using various let forms, but I haven&amp;#8217;t stumbled upon one that works yet.)&lt;/p&gt;</description>
      <pubDate>Thu, 06 Aug 2009 11:54:41 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:9010a7e4-16d5-4f2f-b4dc-743fe6da8ef3</guid>
      <author>Uncle Bob</author>
      <link>http://blog.objectmentor.com/articles/2009/08/06/dont-be-lazy-about-lazy-sequences</link>
      <category>Uncle Bob's Blatherings</category>
    </item>
  </channel>
</rss>
