<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>The Art of Software Development</title>
	<atom:link href="http://sinnema313.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://sinnema313.wordpress.com</link>
	<description>Musings on the Art and Craft of Creating Software</description>
	<lastBuildDate>Thu, 19 Jan 2012 18:53:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='sinnema313.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>The Art of Software Development</title>
		<link>http://sinnema313.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://sinnema313.wordpress.com/osd.xml" title="The Art of Software Development" />
	<atom:link rel='hub' href='http://sinnema313.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Practicing TDD using the Roman Numerals kata</title>
		<link>http://sinnema313.wordpress.com/2011/12/05/practicing-tdd-using-the-roman-numerals-kata/</link>
		<comments>http://sinnema313.wordpress.com/2011/12/05/practicing-tdd-using-the-roman-numerals-kata/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 16:52:28 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[kata]]></category>
		<category><![CDATA[Roman Numerals]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=1703</guid>
		<description><![CDATA[Test-Driven Development (TDD) is a scientific approach to software development that supports incremental design. I&#8217;ve found that, although very powerful, this approach takes some getting used to. Although the rules of TDD are simple, they&#8217;re not always easy: Write a &#8230; <a href="http://sinnema313.wordpress.com/2011/12/05/practicing-tdd-using-the-roman-numerals-kata/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1703&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Test-driven_development">Test-Driven Development</a> (TDD) is a scientific approach to software development that supports <a href="http://jamesshore.com/Agile-Book/incremental_design.html">incremental design</a>. I&#8217;ve found that, although very powerful, this approach takes some getting used to. Although the rules of TDD are <em>simple</em>, they&#8217;re not always <em>easy</em>:</p>
<ol>
<li>Write a failing test</li>
<li>Write the simplest bit of code that makes it pass</li>
<li><a href="http://martinfowler.com/refactoring/">Refactor</a> the code to follow the rules of simple design</li>
</ol>
<p>This is also called the Red-Green-Refactor cycle of TDD.</p>
<p>Writing a failing test isn&#8217;t always easy. Lots of TDD beginners write tests that are to big; TDD is all about taking baby steps. Likewise, writing the simplest bit of code to make the test pass is sometimes difficult. Many developers are trained to write generic code that can handle more than just the case at hand; they must unlearn these habits and truly focus on doing <a href="http://c2.com/cgi/wiki?DoTheSimplestThingThatCouldPossiblyWork">The Simplest Thing That Could Possibly Work.</a></p>
<p>The hardest part of TDD, however, is the final step. Some TDD novices skip it altogether, others have trouble evolving their design. Code that follows the rules of simple design</p>
<ol>
<li>Passes all the tests</li>
<li>Contains no duplication</li>
<li>Clearly expresses the programmer&#8217;s intent</li>
<li>Minimizes code</li>
</ol>
<p>The first is easy, since your xUnit framework will either give you Red or Green. But then the fun begins. Let&#8217;s walk through an example to see TDD in action.</p>
<p>We&#8217;ll use the <a href="http://codingdojo.org/cgi-bin/wiki.pl?KataRomanNumerals">Roman Numerals kata</a> for this example. A <a href="http://en.wikipedia.org/wiki/Kata">kata</a> is a term inherited from the martial arts. <a href="http://projects.ict.usc.edu/itw/gel/EricssonDeliberatePracticePR93.pdf">To get really good at something, you have to practice</a>. The martial arts understood this long before the <a href="http://manifesto.softwarecraftsmanship.org/">Software Crafsmanship</a> movement was born.<br />
They use katas to practice their basic moves over and over again. <a href="http://www.docondev.com/2011/01/sharpening-saw.html">Software katas</a> are similar. They focus on fundamental skills like TDD and incremental design.</p>
<p>In the Roman Numerals kata, we convert Arabic numbers (the one we use daily: 1, 2, 3, 4, 5, &#8230;) into their Roman equivalent: I, II, III, IV, V, &#8230; It&#8217;s a good kata, because it allows one to practice skills in a very concentrated area, as we&#8217;ll see.</p>
<p>So let&#8217;s get started. The first step is to write a failing test:<br />
<pre class="brush: java;">
public class RomanNumeralsTest {

  @Test
  public void one() {
    Assert.assertEquals(&quot;1&quot;, &quot;I&quot;, RomanNumerals.arabicToRoman(1));
  }

}
</pre></p>
<p>Note that this step really is <strong>not</strong> (only) about tests. It really is about designing your API from the client&#8217;s perspective. Think of something that you as a user of the API would like to see to solve your bigger problem. In this kata, the API is just a single method, so there is not much  to design.</p>
<p>OK, we&#8217;re at Red, so let&#8217;s get to Green:<br />
<pre class="brush: java;">
public class RomanNumerals {

  public static String arabicToRoman(int arabic) {
    return &quot;I&quot;;
  }

}
</pre></p>
<p><em>But that&#8217;s cheating! That&#8217;s not an algorithm to convert Arabic numerals into Roman!</em> True, it&#8217;s not, but it isn&#8217;t cheating either. The rules of TDD state that we should write the simplest code that passes the test. It&#8217;s only cheating if you play by the old rules. <a href="http://www.youtube.com/watch?v=FDezrybpuO8">You must unlearn what you have learned</a>.</p>
<p>Now for the Refactor step. The test passes, there is no duplication, we express our intent (that currently is limited to convert 1 into I) clearly, and we have the absolute minimum number of classes and methods (both 1), so we&#8217;re done. Easy, right?</p>
<p>Now we move to the next TDD cycle. First Red:<br />
<pre class="brush: java;">
public class RomanNumeralsTest {

  @Test
  public void oneTwo() {
    Assert.assertEquals(&quot;1&quot;, &quot;I&quot;, RomanNumerals.arabicToRoman(1));
    Assert.assertEquals(&quot;2&quot;, &quot;II&quot;, RomanNumerals.arabicToRoman(2));
  }

}
</pre></p>
<p>No need to change our API. In fact we won&#8217;t have to change it again for the whole kata. So let&#8217;s move to Green:<br />
<pre class="brush: java;">
public static String arabicToRoman(int arabic) {
  if (arabic == 2) {
    return &quot;II&quot;;
  }
  return &quot;I&quot;;
}
</pre></p>
<p>OK, we&#8217;re Green. Now let&#8217;s look at this code. It&#8217;s pretty obvious that if we continue down this path, we&#8217;ll end up with very, very bad code. There is no design at all, just a bunch of hacks. That&#8217;s why the Refactor step is essential.</p>
<p>We pass the tests, but how about duplication? There is duplication in the Arabic number passed in and the number of I&#8217;s the method returns. This may not be obvious to everyone because of the <code>return</code> in the middle of the method. Let&#8217;s get rid of it to better expose the duplication&#8230;<br />
<pre class="brush: java;">
public static String arabicToRoman(int arabic) {
  StringBuilder result = new StringBuilder();
  if (arabic == 2) {
    result.append(&quot;I&quot;);
  }
  result.append(&quot;I&quot;);
  return result.toString();
}
</pre></p>
<p>&#8230;so that we can remove it:<br />
<pre class="brush: java;">
public static String arabicToRoman(int arabic) {
  StringBuilder result = new StringBuilder();
  for (int i = 0; i &lt; arabic; i++) {
    result.append(&quot;I&quot;);
  }
  return result.toString();
}
</pre></p>
<p>What we did here was generalize an <code>if</code> statement into a <code>for</code> (or <code>while</code>). This is one of a bunch of <a href="http://cleancoder.posterous.com/the-transformation-priority-premise">transformations one often uses in TDD</a>. The net effect of a generalization like this is that we have discovered a rule based on similarities. This means that our code can now handle more cases than the ones we supplied as tests. In this specific case, we can now also convert 3 to III:<br />
<pre class="brush: java;">
@Test
public void oneTwoThreeRepeatIs() {
  Assert.assertEquals(&quot;1&quot;, &quot;I&quot;, RomanNumerals.arabicToRoman(1));
  Assert.assertEquals(&quot;2&quot;, &quot;II&quot;, RomanNumerals.arabicToRoman(2));
  Assert.assertEquals(&quot;3&quot;, &quot;III&quot;, RomanNumerals.arabicToRoman(3));
}
</pre></p>
<p>Now that we have removed duplication, let&#8217;s look at expressiveness and compactness. Looks OK to me, so let&#8217;s move on to the new case. We got 3 covered, so 4 is next:<br />
<pre class="brush: java;">
@Test
public void four() {
  Assert.assertEquals(&quot;4&quot;, &quot;IV&quot;, RomanNumerals.arabicToRoman(4));
}
</pre></p>
<p>This fails as expected, because we generalized to far. We need an exception to our discovered rule:<br />
<pre class="brush: java;">
  public static String arabicToRoman(int arabic) {
    StringBuilder result = new StringBuilder();
    if (arabic == 4) {
      return &quot;IV&quot;;
    }
    for (int i = 0; i &lt; arabic; i++) {
      result.append(&quot;I&quot;);
    }
    return result.toString();
  }
</pre></p>
<p>This uses <code>return</code> in the middle of a method again, which we discovered may hide duplication. So let&#8217;s not ever use that again. One alternative is to use an <code>else</code> statement. The other is to decrease the <code>arabic</code> parameter, so that the <code>for</code> loop never executes. We have no information right now on which to base our choice, so either will do:<br />
<pre class="brush: java;">
public static String arabicToRoman(int arabic) {
  StringBuilder result = new StringBuilder();
  if (arabic == 4) {
    result.append(&quot;IV&quot;);
  } else {
    for (int i = 0; i &lt; arabic; i++) {
      result.append(&quot;I&quot;);
    }
  }
  return result.toString();
}
</pre></p>
<p>It&#8217;s hard to see duplication in here, and I think the code expresses our current intent and is small, so let&#8217;s move on to the next test:<br />
<pre class="brush: java;">
@Test
public void five() {
  Assert.assertEquals(&quot;5&quot;, &quot;V&quot;, RomanNumerals.arabicToRoman(5));
}
</pre></p>
<p>Which we make pass with:<br />
<pre class="brush: java;">
public static String arabicToRoman(int arabic) {
  StringBuilder result = new StringBuilder();
  if (arabic == 5) {
    result.append(&quot;V&quot;);
  } else if (arabic == 4) {
    result.append(&quot;IV&quot;);
  } else {
    for (int i = 0; i &lt; arabic; i++) {
      result.append(&quot;I&quot;);
    }
  }
  return result.toString();
}
</pre></p>
<p>This is turning into a mess. But there is no duplication apparent yet, and the code does sort of say what we mean. So let&#8217;s push our uneasy feelings aside for a little while and move on to the next test:<br />
<pre class="brush: java;">
@Test
public void six() {
  Assert.assertEquals(&quot;6&quot;, &quot;VI&quot;, RomanNumerals.arabicToRoman(6));
}
</pre></p>
<p>Which passes with:<br />
<pre class="brush: java;">
public static String arabicToRoman(int arabic) {
  StringBuilder result = new StringBuilder();
  if (arabic == 6) {
    result.append(&quot;VI&quot;);
  } else if (arabic == 5) {
      result.append(&quot;V&quot;);
  } else if (arabic == 4) {
    result.append(&quot;IV&quot;);
  } else {
    for (int i = 0; i &lt; arabic; i++) {
      result.append(&quot;I&quot;);
    }
  }
  return result.toString();
}
</pre></p>
<p>Hmm, uglier still, but at least some duplication is now becoming visible: VI is V followed by I, and we already have code to append those. So we could first add the V and then rely on the <code>for</code> loop to add the I:<br />
<pre class="brush: java;">
public static String arabicToRoman(int arabic) {
  StringBuilder result = new StringBuilder();
  int remaining = arabic;
  if (remaining &gt;= 5) {
    result.append(&quot;V&quot;);
    remaining -= 5;
  }
  if (remaining == 4) {
    result.append(&quot;IV&quot;);
    remaining -= 4;
  }
  for (int i = 0; i &lt; remaining; i++) {
    result.append(&quot;I&quot;);
  }
  return result.toString();
}
</pre></p>
<p>Still not very clean, but better than before. And we can now also handle 7 and 8. So let&#8217;s move on to 9:<br />
<pre class="brush: java;">
@Test
public void nineIsXPrefixedByI() {
  Assert.assertEquals(&quot;9&quot;, &quot;IX&quot;, RomanNumerals.arabicToRoman(9));
}
</pre><br />
<pre class="brush: java;">
public static String arabicToRoman(int arabic) {
  StringBuilder result = new StringBuilder();
  int remaining = arabic;
  if (remaining == 9) {
    result.append(&quot;IX&quot;);
    remaining -= 9;
  }
  if (remaining &gt;= 5) {
    result.append(&quot;V&quot;);
    remaining -= 5;
  }
  if (remaining == 4) {
    result.append(&quot;IV&quot;);
    remaining -= 4;
  }
  for (int i = 0; i &lt; remaining; i++) {
    result.append(&quot;I&quot;);
  }
  return result.toString();
}
</pre></p>
<p>There&#8217;s definitely a pattern emerging. Two <code>if</code>s use <code>==</code>, and one uses <code>&gt;=</code>, but the rest of the statements is the same. We can make them all completely identical by a slight generalization:<br />
<pre class="brush: java;">
public static String arabicToRoman(int arabic) {
  StringBuilder result = new StringBuilder();
  int remaining = arabic;
  if (remaining &gt;= 9) {
    result.append(&quot;IX&quot;);
    remaining -= 9;
  }
  if (remaining &gt;= 5) {
    result.append(&quot;V&quot;);
    remaining -= 5;
  }
  if (remaining &gt;= 4) {
    result.append(&quot;IV&quot;);
    remaining -= 4;
  }
  for (int i = 0; i &lt; remaining; i++) {
    result.append(&quot;I&quot;);
  }
  return result.toString();
}
</pre></p>
<p>Now we can extract the duplication:<br />
<pre class="brush: java;">
public static String arabicToRoman(int arabic) {
  StringBuilder result = new StringBuilder();
  int remaining = arabic;
  remaining = appendRomanNumerals(remaining, 9, &quot;IX&quot;, result);
  remaining = appendRomanNumerals(remaining, 5, &quot;V&quot;, result);
  remaining = appendRomanNumerals(remaining, 4, &quot;IV&quot;, result);
  for (int i = 0; i &lt; remaining; i++) {
    result.append(&quot;I&quot;);
  }
  return result.toString();
}

private static int appendRomanNumerals(int arabic, int value, String romanDigits, StringBuilder builder) {
  int result = arabic;
  if (result &gt;= value) {
    builder.append(romanDigits);
    result -= value;
  }
  return result;
}
</pre></p>
<p>There is still duplication is the enumeration of calls to <code>appendRomanNumerals</code>. We can turn that into a loop:<br />
<pre class="brush: java;">
private static final int[]    VALUES  = { 9,    5,   4 };
private static final String[] SYMBOLS = { &quot;IX&quot;, &quot;V&quot;, &quot;IV&quot; };

public static String arabicToRoman(int arabic) {
  StringBuilder result = new StringBuilder();
  int remaining = arabic;
  for (int i = 0; i &lt; VALUES.length; i++) {
    remaining = appendRomanNumerals(remaining, VALUES[i], SYMBOLS[i], result);
  }
  for (int i = 0; i &lt; remaining; i++) {
    result.append(&quot;I&quot;);
  }
  return result.toString();
}
</pre></p>
<p>Now that we look at the code this way, it seems that the <code>for</code> loop does something similar to what <code>appendRomanNumerals</code> does. The only difference is that the loop does it multiple times, while the method does it only once. We can generalize the method and rewrite the loop to make this duplication more visible:<br />
<pre class="brush: java;">
public static String arabicToRoman(int arabic) {
  StringBuilder result = new StringBuilder();
  int remaining = arabic;
  for (int i = 0; i &lt; VALUES.length; i++) {
    remaining = appendRomanNumerals(remaining, VALUES[i], SYMBOLS[i], result);
  }
  while (remaining &gt;= 1) {
    result.append(&quot;I&quot;);
    remaining -= 1;
  }
  return result.toString();
}

private static int appendRomanNumerals(int arabic, int value, String romanDigits, StringBuilder builder) {
  int result = arabic;
  while (result &gt;= value) {
    builder.append(romanDigits);
    result -= value;
  }
  return result;
}
</pre></p>
<p>This makes it trivial to eliminate it:<br />
<pre class="brush: java;">
private static final int[]    VALUES  = { 9,    5,   4,    1   };
private static final String[] SYMBOLS = { &quot;IX&quot;, &quot;V&quot;, &quot;IV&quot;, &quot;I&quot; };

public static String arabicToRoman(int arabic) {
  StringBuilder result = new StringBuilder();
  int remaining = arabic;
  for (int i = 0; i &lt; VALUES.length; i++) {
    remaining = appendRomanNumerals(remaining, VALUES[i], SYMBOLS[i], result);
  }
  return result.toString();
}
</pre></p>
<p>Now we have discovered our algorithm and new cases can be handled by just adding to the arrays:<br />
<pre class="brush: java;">
  private static final int[]    VALUES  = { 1000, 900,  500, 400,  100, 90,   50,  40,   10,  9,    5,   4,    1   };
  private static final String[] SYMBOLS = { &quot;M&quot;,  &quot;CM&quot;, &quot;D&quot;, &quot;CD&quot;, &quot;C&quot;, &quot;XC&quot;, &quot;L&quot;, &quot;XL&quot;, &quot;X&quot;, &quot;IX&quot;, &quot;V&quot;, &quot;IV&quot;, &quot;I&quot; };
</pre></p>
<p>There is still some duplication in the arrays, but one can wonder whether eliminating it would actually improve the code, so we&#8217;re just going to leave it as it is. And then there is some duplication in the fact that we have two arrays with corresponding elements. Moving to one array would necessitate the introduction of a new class to hold the value/symbol combination and I don&#8217;t think that that&#8217;s worth it.</p>
<p>So that concludes our tour of TDD using the Roman Numerals kata. What I really like about this kata is that it is very focused. There is hardly any API design, so coming up with tests is really easy. And the solution isn&#8217;t all that complicated either; you only need <code>if</code> and <code>while</code>. This kata really helps you hone your skills of detecting and eliminating duplication, which is a fundamental skill to have when evolving your designs.</p>
<p><em>Have fun practicing!</em></p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/code/'>Code</a>, <a href='http://sinnema313.wordpress.com/category/test/'>test</a> Tagged: <a href='http://sinnema313.wordpress.com/tag/kata/'>kata</a>, <a href='http://sinnema313.wordpress.com/tag/roman-numerals/'>Roman Numerals</a>, <a href='http://sinnema313.wordpress.com/tag/tdd/'>TDD</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/1703/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/1703/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/1703/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/1703/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/1703/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/1703/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/1703/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/1703/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/1703/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/1703/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/1703/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/1703/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/1703/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/1703/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1703&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2011/12/05/practicing-tdd-using-the-roman-numerals-kata/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>
	</item>
		<item>
		<title>A REST API for XACML</title>
		<link>http://sinnema313.wordpress.com/2011/11/27/a-rest-api-for-xacml/</link>
		<comments>http://sinnema313.wordpress.com/2011/11/27/a-rest-api-for-xacml/#comments</comments>
		<pubDate>Sun, 27 Nov 2011 21:16:25 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[XACML]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[xacml]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=1610</guid>
		<description><![CDATA[The wonderful book RESTful Web Services describes a procedure for developing RESTful web services. In this post, we will apply this procedure to XACML. The eXtensible Access Control Markup Language (XACML) describes an architecture for authorization. The components of the &#8230; <a href="http://sinnema313.wordpress.com/2011/11/27/a-rest-api-for-xacml/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1610&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The wonderful book <a href="http://www.amazon.com/RESTful-Web-Services-ebook/dp/B0043D2ED6/ref=sr_1_1?s=digital-text&amp;ie=UTF8&amp;qid=1321601463&amp;sr=1-1">RESTful Web Services</a> describes a procedure for developing RESTful web services. In this post, we will apply this procedure to XACML.</p>
<p>The <a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=xacml" title="The XACML specification page at OASIS">eXtensible Access Control Markup Language</a> (XACML) describes an <a href="https://community.emc.com/docs/DOC-7314">architecture</a> for authorization. The components of the architecture that are of interest to us here are the <em>Policy Decision Point</em> (PDP) and <em>Policy Administration Point</em> (PAP). The PDP is the component that decides on an authorization request. The PAP is the component that maintains the authorization policies that the PDP uses to reach its decision. There are more components in the architecture, but from a web services standpoint, the PAP and PDP give a client everything it needs to write and evaluate authorization policies.</p>
<p><strong>Resources</strong><br />
Key to the <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm" title="The chapter on REST in Roy Fielding's Disseration">REST architectural style</a> is to identify resources and name them with <a href="http://tools.ietf.org/html/rfc2396">URIs</a>. The book states that <em>&#8220;A resource is anything interesting enough to be the target of a hypertext link.&#8221;</em> There are three different types of resources:</p>
<ul>
<li>Predefined one-off resources for especially important aspects of the application</li>
<li>Resources for every object in the data set the service exposes</li>
<li>Resources representing the results of algorithms applied to the data set</li>
</ul>
<p>An example of a predefined one-off resource is the list of XACML policies. We name that resource with the URI <code>/policies</code>. Note that this is a relative URI, the actual URI will be something like <code>http://www.example.com/application/policies</code>. In this post we will show relative URIs only.</p>
<p>An application can have many policies, which means the response could become very large. We solve that problem using <a href="http://en.wikipedia.org/wiki/Pagination#Pagination_in_Web_content_.28HTML.2C_ASP.2C_PHP.2C_and_others.29">pagination</a>: we will return a small number of results only. If a client wants more results, it can use <a href="http://en.wikipedia.org/wiki/Query_string">query parameters</a> to do so: <code>/policies?offset=100&amp;count=20</code>.</p>
<p>Resources from the data set that our service exposes are the individual XACML policies. We name policies with the URI <code>/policies/{policyId}</code>, where the part between <code>{}</code> is variable. We could even go a step further and include finer-grained resources like rules, attributes, and conditions. Their URIs would be <code>/policies/{policyId}/{ruleId}</code>, etc.</p>
<p>An example of a resource that is the result of an algorithm is the PDP&#8217;s access decision, which we arrive at by matching the policies with the request attributes. This resource is a bit trickier to name, since we need to supply input to it, which is usually accomplished using query parameters. So we could name this resource with the URI <code>/decision?attribute1=value1&amp;attribute2=value2&amp;...</code> A XACML attribute is identified by multiple pieces of information: category, id, and data type. We could encode these in a query parameter name using the scheme <code>{category}/{id};{dataType}</code>. Here we follow the convention that <code>/</code> implies hierarchy, while <code>;</code> implies unordered combination.</p>
<p>However, with categories like <code>urn:oasis:names:tc:xacml:1.0:subject-category:access-subject</code>, ids like <code>urn:oasis:names:tc:xacml:1.0:subject:subject-id</code>, and data types like <code>urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name</code>, the URI will grow very big very quickly. There is no theoretical limit to URI length, but many applications will enforce limits in practice. (There is even an <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.15">HTTP status code</a> for this situation.) So we will need a way to shorten the URI considerably.</p>
<p>One way to do that, is to define shortcuts for standard attributes. For instance, instead of writing <code>urn:oasis:names:tc:xacml:1.0:subject-category:access-subject/urn:oasis:names:tc:xacml:1.0:subject:subject-id,urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name</code>, we could just use <code>subject</code>. To avoid conflicts, these shortcuts would have to be standardized along with the REST API.</p>
<p>The other potential problem with this approach is that <code>/</code> and <code>;</code> are valid parts of URIs, and therefore could be used in categories, ids, and data types. The chances of this happening are not very high, though. The XACML specification uses <code>:</code> to separate components, and extensions would be wise to follow that example. Otherwise, they could use <a href="http://tools.ietf.org/html/rfc3986#page-12" title="Percent encoding in the URI specification">percent encoding</a>.</p>
<p><strong>Uniform Interface</strong><br />
The next step is to determine what operations are allowed on what resources. In a RESTful architecture, operations use the <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html">HTTP verbs</a> only. This is called the <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_5">uniform interface</a>. We must identify the HTTP verbs supported for each URI, and also determine what <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">HTTP status codes</a> they return.</p>
<p>The list of policies, <code>/policies</code>, only supports <code>GET</code>, to retrieve the policies. There is no need to support <a href="http://jcalcote.wordpress.com/2008/10/16/put-or-post-the-rest-of-the-story/" title="PUT vs POST"><code>POST</code> to create policies</a>: policies are named by ID, and the ID is part of the content, so it must be known to the client. This method will always return <code>200 OK</code> if the server is operating fine. Otherwise, a <code>500 Internal Server Error</code> will be returned. This last status is returned for all methods on all resources when there is a problem with the server, so we will not mention it any further.</p>
<p><code>PUT</code> on <code>/policies/{policyId}</code> creates a new policy, or overwrites an existing policy. <code>GET</code> retrieves a policy and <code>DELETE</code> removes it. <code>GET</code> will return either <code>200 OK</code> or <code>404 Not Found</code>. <code>PUT</code> and <code>DELETE</code> will normally return <code>204 No Content</code>. <code>PUT</code> can additionally return <code>415 Unsupported Media Type</code> when the representation in the request (see below) is not understood.</p>
<p>The <code>/decision</code> resource, being algorithmic, only supports <code>GET</code>. Possible return codes are <code>200 OK</code>, or <code>400 Bad Request</code> when a parameter is invalid. This could happen when an unknown category, id, or data type is specified, or when the value supplied doesn&#8217;t match the data type. It can also happen when an unknown shortcut is used to identify a variable.</p>
<p>Like all web services, a XACML PAP needs to be secured. Whatever means used for that is out of scope for this discussion, but there are some additional status codes that the web service may return, irrespective of the security means. <code>401 Unauthorized</code> means that the user making the request didn&#8217;t provide sufficient credentials, while <code>403 Forbidden</code> means that the user doesn&#8217;t have the privileges required to honor the request.</p>
<p><strong>Representations</strong><br />
The next step is to design the <em>representations</em> of the resources. There are two such representations: those presented to the server by the client, and those returned to the client by the server.</p>
<p>Clients don&#8217;t always have to provide content to the web services. Only <code>PUT</code> on <code>/policies/{policyId}/</code> requires input, namely the policy. The representation of a policy should simply follow the XML format that the XACML standard prescribes. There is no media type registered for XACML at <a href="http://www.iana.org/assignments/media-types/index.html">IANA</a>, so we&#8217;ll have to make do with <code>text/xml</code>.</p>
<p>The representations returned by the server are a bit trickier. First there is the list of policies returned by <code>/policies</code>. This service could either return all the policies in XACML format, or only the IDs. Chances are this service is invoked to determine which policies exist. It&#8217;s not clear that their details are always required, so it may make more sense to just return the IDs, since that keeps the response leaner. <a href="http://tools.ietf.org/html/rfc4287">Atom</a> is always a good representation for lists of entries with links, but XACML 3.0 has a construct named <a href="http://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-cs-01-en.html#_Toc265751061"><code>PolicyIdentifierList</code></a> that specifically represents a list of policy IDs. We should use that instead of Atom, since it&#8217;s extremely likely that the client can already parse XACML, but not that they can also parse Atom.</p>
<p>In order for <a href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven" title="REST APIs must be hypertext-driven">representations to drive the state</a>, which is the point in REST, they should contain links to other resources. So <code>/policies</code> should return not just IDs, but also links to the policies identified by those IDs. <code>PolicyIdentifierList</code> doesn&#8217;t provide for that, however. But we can augment it using the standard way of linking in XML: <a href="http://www.w3.org/TR/xlink/">XLink</a>. An example would be:<br />
<pre class="brush: xml;">
&lt;PolicyIdentifierList xmlns:xlink='http://www.w3.org/1999/xlink
    xmlns=&quot;urn:oasis:names:tc:xacml:3.0:core:schema:wd-17&quot;&gt;
  &lt;PolicyIdReference xlink:href=&quot;/policies/urn:sample:policy:id&quot;&gt;urn:sample:policy:id&lt;/PolicyIdReference&gt;
&lt;/PolicyIdentifierList&gt;
</pre></p>
<p>The result of <code>GET</code> on <code>/policies/{policyId}</code> should simply be the XACML policy in the canonical XML format. The issue of linking comes up here as well, so we&#8217;ll use XLink again. For instance, a policy set can contain a <code>PolicyIdReference</code>. </p>
<p>The result of <code>/decision</code> is a XACML decision, i.e. one of <code>Permit</code>, <code>Deny</code>, <code>NotApplicable</code> or <code>Indeterminate</code>. We should represent that with the XACML <a href="http://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-cs-01-en.html#_Toc265751060"><code>Decision</code> XML element</a>, since the client can likely already parse that.</p>
<p>So this is my proposal for a REST API for XACML. What do you think?</p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/design/'>Design</a>, <a href='http://sinnema313.wordpress.com/category/xacml-2/'>XACML</a> Tagged: <a href='http://sinnema313.wordpress.com/tag/rest/'>rest</a>, <a href='http://sinnema313.wordpress.com/tag/xacml/'>xacml</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/1610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/1610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/1610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/1610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/1610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/1610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/1610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/1610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/1610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/1610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/1610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/1610/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/1610/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/1610/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1610&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2011/11/27/a-rest-api-for-xacml/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>
	</item>
		<item>
		<title>XACML at XML Amsterdam 2011</title>
		<link>http://sinnema313.wordpress.com/2011/10/13/xacml-at-xml-amsterdam-2011/</link>
		<comments>http://sinnema313.wordpress.com/2011/10/13/xacml-at-xml-amsterdam-2011/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 05:38:30 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[XACML]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[xacml]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=1579</guid>
		<description><![CDATA[Less than three weeks till XML Amsterdam 2011 where I&#8217;ll be speaking on XACML. XML Amsterdam is a small, focused conference dedicated to XML. As part of X-Hive EMC&#8217;s XML R&#38;D center, I live and breathe XML, so I&#8217;m glad &#8230; <a href="http://sinnema313.wordpress.com/2011/10/13/xacml-at-xml-amsterdam-2011/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1579&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Less than three weeks till <a href="http://xmlamsterdam.com/" title="XML Amsterdam conference website">XML Amsterdam</a> 2011 where I&#8217;ll be speaking on XACML.</p>
<p>XML Amsterdam is a small, focused conference dedicated to <a href="http://www.w3.org/standards/xml/" target="_blank">XML</a>. As part of <del datetime="2011-10-13T05:10:02+00:00">X-Hive</del> <a href="https://community.emc.com/community/edn/xmltech?view=overview" title="XML technologies @ EMC Developer Network">EMC&#8217;s XML R&amp;D center</a>, I live and breathe XML, so I&#8217;m glad to have an XML conference in the Netherlands. The conference is small, so we won&#8217;t get lost in the crowd and the chances of good networking opportunities are high. And it is completely focused on XML, unlike <a href="http://www.momentumeurope.com/" title="Momentum Europe conference website">Momentum</a>, for instance. Finally, with <a href="http://xmlamsterdam.com/?q=speakers" title="Bio's of speakers" target="_blank">speakers</a> from all major native XML databases (<a href="http://netherlands.emc.com/products/detail/software2/documentum-xdb.htm">xDB</a>, <a href="http://www.marklogic.com/products/marklogic-server.html?PHPSESSID=7m80oj0t1eh2shthhla5p1iau3">MarkLogic</a>, and <a href="http://exist-db.org/">eXists</a>), we can expect some lively discussions <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  . Especially with EMC IIG Chief Architect <a href="http://emccrazycontent.com/" title="Jeroen's vlog">Jeroen van Rotterdam</a> opening the conference with a <a href="http://xmlamsterdam.com/?q=program" title="The conference program">keynote</a> titled <em>Is XML dead</em>?</p>
<p>My presentation will introduce <a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=xacml">eXtensible Access Control Markup Language</a> (XACML), an XML language for access control. I will place XACML in the context of access control models, and show that XACML is a future-proof technology that organizations can start using now, and then stay with as their access control needs evolve. I will continue to explain the architecture, request/response protocol, and policy language that make up XACML.</p>
<p>Here are my <a href="http://www.slideshare.net/sinnema313/xacml-xml-amsterdam2011">slides</a>.</p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/xacml-2/'>XACML</a> Tagged: <a href='http://sinnema313.wordpress.com/tag/conference/'>conference</a>, <a href='http://sinnema313.wordpress.com/tag/xacml/'>xacml</a>, <a href='http://sinnema313.wordpress.com/tag/xml/'>xml</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/1579/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/1579/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/1579/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/1579/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/1579/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/1579/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/1579/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/1579/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/1579/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/1579/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/1579/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/1579/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/1579/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/1579/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1579&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2011/10/13/xacml-at-xml-amsterdam-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>
	</item>
		<item>
		<title>CQRS by Example &#8211; XACML</title>
		<link>http://sinnema313.wordpress.com/2011/09/18/cqrs-by-example-xacml/</link>
		<comments>http://sinnema313.wordpress.com/2011/09/18/cqrs-by-example-xacml/#comments</comments>
		<pubDate>Sun, 18 Sep 2011 17:44:09 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[XACML]]></category>
		<category><![CDATA[cqrs]]></category>
		<category><![CDATA[xacml]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=1567</guid>
		<description><![CDATA[Often, when people talk about dividing a software system up into layers, they mention that you should start with the domain model. Note the word the, suggesting there is only ever a single domain model. Not so with Command-Query Responsibility &#8230; <a href="http://sinnema313.wordpress.com/2011/09/18/cqrs-by-example-xacml/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1567&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Often, when people talk about dividing a software system up into <a href="http://en.wikipedia.org/wiki/Abstraction_layer" title="Wikipedia on Abstraction Layers">layers</a>, they mention that you should start with the <a href="http://en.wikipedia.org/wiki/Domain_model" title="Wikipedia on Domain Model">domain model</a>. Note the word <em>the</em>, suggesting there is only ever a single domain model.</p>
<p>Not so with <a href="http://martinfowler.com/bliki/CQRS.html" title="Martin Fowler on CQRS">Command-Query Responsibility Separation</a> (CQRS, see also <a href="http://www.udidahan.com/2009/12/09/clarified-cqrs/">CQRS Clarified</a>). This is a pattern where the domain is described by more than one model. Updating of information happens by executing <em>commands</em> on one (or more) models. Viewing of information happens by <em>querying</em> one (or more) other models. The command and query models obviously need to be synchronized.</p>
<p>To see the value in such a separation, let&#8217;s consider an example. The <a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=xacml" title="XACML home at OASIS">eXtensible Access Control Markup Language</a> (XACML) defines an XML language for expressing access control policies, and an architecture for evaluating access requests. <a href="https://community.emc.com/docs/DOC-7314" title="Introduction to XACML">The architecture defines different components</a> that play different roles. The most important for the current example are the <em>Policy Administration Point</em> (PAP) that maintains access control policies, and the <em>Policy Decision Point</em> (PDP) that evaluates access requests.</p>
<p>Both the PAP and the PDP work with the same access control policies, but their relationship with these policies is quite different. The PAP should be able to edit and import policies, and must, therefore, understand the canonical XML format of XACML. The PDP, however, should respond as quickly as possible and XML may not be the best format to achieve that. By letting the PDP (query) work with a different model than the PAP (command), an XACML imlementation can perform best on both fronts.</p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/design/'>Design</a>, <a href='http://sinnema313.wordpress.com/category/xacml-2/'>XACML</a> Tagged: <a href='http://sinnema313.wordpress.com/tag/cqrs/'>cqrs</a>, <a href='http://sinnema313.wordpress.com/tag/xacml/'>xacml</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/1567/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/1567/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/1567/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/1567/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/1567/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/1567/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/1567/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/1567/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/1567/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/1567/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/1567/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/1567/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/1567/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/1567/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1567&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2011/09/18/cqrs-by-example-xacml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>
	</item>
		<item>
		<title>XACML 3.0 is now Committee Specification Draft</title>
		<link>http://sinnema313.wordpress.com/2011/07/21/xacml-3-0-is-now-committee-specification-draft/</link>
		<comments>http://sinnema313.wordpress.com/2011/07/21/xacml-3-0-is-now-committee-specification-draft/#comments</comments>
		<pubDate>Thu, 21 Jul 2011 18:48:04 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[XACML]]></category>
		<category><![CDATA[xacml]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=1506</guid>
		<description><![CDATA[Good news! Version 3.0 of the eXtensible Access Control Markup Language (XACML) has just been voted a Committee Specification Draft. There will only be a 15 day public review, since it has already been at that level before we dropped &#8230; <a href="http://sinnema313.wordpress.com/2011/07/21/xacml-3-0-is-now-committee-specification-draft/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1506&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Good news! <a href="http://www.oasis-open.org/committees/download.php/42707/xacml-3.0-core-spec-wd-22-en.doc" title="Working Draft 22, that was voted to Committee Specification Draft">Version 3.0</a> of the <a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=xacml" title="XACML Technical Committee">eXtensible Access Control Markup Language</a> (XACML) has just been voted a <a href="http://www.oasis-open.org/policies-guidelines/tc-process#committeeDraft">Committee Specification Draft</a>. There will only be a 15 day <a href="http://www.oasis-open.org/policies-guidelines/tc-process#publicReview">public review</a>, since it has already been at that level before we dropped back to Working Draft. There is still a <a href="http://www.oasis-open.org/policies-guidelines/tc-process#OASISstandard">long way to go</a> until version 3.0 becomes an OASIS standard, but at least we&#8217;ve started down that path.</p>
<p><strong>What is XACML?</strong><br />
In short, XACML offers an architecture for access control, a policy language for describing and evaluating access control policies, and a protocol for requesting access. I&#8217;ve written about XACML in a series on EMC&#8217;s Developers Network:</p>
<ul>
<li><a href="https://community.emc.com/docs/DOC-7314">Introduction to XACML: Access Control Policies in XML</a></li>
<li><a href="https://community.emc.com/docs/DOC-7410">Real world examples of XACML security policies</a></li>
<li><a href="https://community.emc.com/docs/DOC-8672">Implementing an XACML PEP in Java</a></li>
</ul>
<p><strong>What&#8217;s new in 3.0?</strong><br />
<a href="http://www.axiomatics.com/">Axiomatics</a> were <a href="http://www.axiomatics.com/latest-news/202-axiomatics-is-the-first-organization-to-attest-complete-xacml-30-specification-conformance.html">the first company to implement 3.0</a> (their CTO, Erik Rissanen, is editor of the spec). They&#8217;ve also summarized what has changed since <a href="http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-core-spec-os.pdf">2.0</a>, the current OASIS standard:</p>
<ul>
<li><a href="http://www.kuppingercole.com/events/n40111">Webinar with Kuppinger Cole</a></li>
<li><a href="http://kantarainitiative.org/confluence/download/attachments/3408008/01-100727-XACML3-gebel.pdf">Presentation by Gerry Gebel</a></li>
<li><a href="http://www.webfarmr.eu/2010/07/enhancements-and-new-features-in-xacml-3-axiomatics/">Blog post by David Brossard</a></li>
</ul>
<p><strong>Who&#8217;s using XACML?</strong><br />
Obviously not many people are using 3.0, since it&#8217;s not a standard yet. But 2.0 has been around since 2005 and is used in various places. Below is a sample of places where XACML is being used:</p>
<ul>
<li><a href="http://www.axiomatics.com/latest-news/180-paypal-to-use-axiomatics-intelligent-access-management-solution.html">PayPal</a></li>
<li><a href="http://www.axiomatics.com/latest-news/153-datev-eg-goes-xacml.html">Datev</a></li>
<li><a href="http://www.axiomatics.com/images/stories/pressreleases/pressrelease-bif.pdf">Swedish National Health Service</a></li>
<li><a href="http://www.axiomatics.com/latest-news/126-bell-helicopter-chooses-axiomatics-for-entitlement-management.html">Bell Helicopter Textron Inc.</a></li>
<li>Department of Veterans Affairs</li>
<li>Bank of America</li>
<li><a href="http://www.nextlabs.com/html/?q=case-studies">Other organizations</a>, that remain unnamed</li>
</ul>
<p>I&#8217;ll update this list when I find more examples. If you know of any, please let me know.</p>
<p><strong>Update 2011-08-19</strong>: <a href="http://lists.oasis-open.org/archives/xacml/201108/msg00011.html">BitKOO is the second vendor to attest 3.0 compliance</a>, after <a href="http://markmail.org/message/5lr7vvl54b2rzjvf">Axiomatics</a>.</p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/xacml-2/'>XACML</a> Tagged: <a href='http://sinnema313.wordpress.com/tag/xacml/'>xacml</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/1506/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/1506/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/1506/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/1506/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/1506/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/1506/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/1506/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/1506/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/1506/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/1506/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/1506/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/1506/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/1506/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/1506/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1506&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2011/07/21/xacml-3-0-is-now-committee-specification-draft/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>
	</item>
		<item>
		<title>The Nature of Software Development</title>
		<link>http://sinnema313.wordpress.com/2011/07/03/the-nature-of-software-development/</link>
		<comments>http://sinnema313.wordpress.com/2011/07/03/the-nature-of-software-development/#comments</comments>
		<pubDate>Sun, 03 Jul 2011 14:48:42 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Environment]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[What other people say]]></category>
		<category><![CDATA[collective code ownership]]></category>
		<category><![CDATA[domain driven design]]></category>
		<category><![CDATA[eXtreme Programming]]></category>
		<category><![CDATA[incremental design]]></category>
		<category><![CDATA[maintenance]]></category>
		<category><![CDATA[mental model]]></category>
		<category><![CDATA[on-site customer]]></category>
		<category><![CDATA[silos]]></category>
		<category><![CDATA[system metaphor]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[theory]]></category>
		<category><![CDATA[ubiquitous language]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=1440</guid>
		<description><![CDATA[I&#8217;ve been developing software for a while now. Over fifteen years professionally, and quite some time before that too. One would think that when you&#8217;ve been doing something for a long time, you would develop a good understanding of what &#8230; <a href="http://sinnema313.wordpress.com/2011/07/03/the-nature-of-software-development/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1440&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been developing software for a while now. Over fifteen years professionally, and quite some time before that too. One would think that when you&#8217;ve been doing something for a long time, you would develop a good understanding of what it is that you do. Well, <a href="http://projects.ict.usc.edu/itw/gel/EricssonDeliberatePracticePR93.pdf" title="The Role of Deliberate Practice in the Acquisition of Expert Performance">maybe</a>. But every once in a while I come across something that deepens my insight, that takes it to the next level.</p>
<p>I recently came across <a href="http://dl.dropbox.com/u/502901/naurtf.pdf" title="Programming as Theory Building">an article</a> (from 1985!) that does just that, by providing a theory of what software development really is. If you have anything to do with developing software, please read the article. It&#8217;s a bit dry and terse at times, but please persevere.</p>
<p>The article promotes the view that, in essence, <strong>software development is a theory building activity</strong>. This means that it is first and foremost about building a <a href="http://en.wikipedia.org/wiki/Mental_model">mental model</a> in the developer&#8217;s mind about how the world works and how the software being developed handles and supports that world.</p>
<p>This contrasts with the more dominant manufacturing view that sees software development as an activity where some artifacts are to be produced, like code, tests, and documentation. That&#8217;s not to say that these artifacts are not produced, since obviously they are, but rather that that&#8217;s not the real issue. If we want to be able to develop software that works well, and is maintainable, we&#8217;re better off focusing on building the right theories. The right artifacts will then follow.</p>
<p>This view has huge implications for how we organize software development. Below, I will discuss some things that we need to do differently from what you might expect based on the manufacturing view. The funny thing is that we&#8217;ve known that for some time now, but for different reasons.</p>
<p><strong>We need strong customer collaboration to build good theories</strong><br />
Mental models can never be externalized completely, some subtleties always get lost when we try that. That&#8217;s why requirements as documents don&#8217;t work. It&#8217;s not just that <a href="http://www.amazon.com/Extreme-Programming-Explained-Embrace-Change/dp/0201616416" title="Embrace Change">they will change</a> (Agile), or that <a href="http://www.shmula.com/poppendieck-on-waste-the-handoff/447/" title="Hand-offs are the biggest waste in product development">hand-offs are a waste</a> (Lean), no, they fundamentally cannot work! So <a href="http://www.extremeprogramming.org/rules/customer.html" title="On-Site Customer">we need the customer around</a> to clarify the subtle details, and we need <a href="http://en.wikipedia.org/wiki/Genchi_Genbutsu" title="Genchi genbutsu">to go see</a> how the end users work <a href="http://en.wikipedia.org/wiki/Gemba" title="Gemba">in their own environment</a> to build the best possible theories.</p>
<p>Since this is expensive, and since a customer would not like having to explain the same concept over and over again to different developers, it makes sense to try and capture some of the domain knowledge, even though we know we can never capture every subtle detail. This is where <a href="http://www.extremeprogramming.org/rules/functionaltests.html">automated acceptance tests</a>, for example as produced in <a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development">Behavior_Driven_Development</a>, can come in handy.</p>
<p><strong>Software developers should share the same theory</strong><br />
It&#8217;s of paramount importance that all the developers on the team share the same theory, or else they will develop things that make no sense to their team members and that will not integrate well with their team members&#8217; work. Having the same theory is helped by <a href="http://jamesshore.com/Agile-Book/ubiquitous_language.html" title="Ubiquitous language">using the same terminology</a>. Developers should be careful not to let the <a href="http://www.martinfowler.com/bliki/SemanticDiffusion.html" title="Semantic diffusion">meaning of the terms drift away</a> from how the end users use them.</p>
<p>The need for a shared theory means that <em>strong</em> <a href="http://martinfowler.com/bliki/CodeOwnership.html">code ownership</a> is a bad idea. <em>Weak</em> ownership could work, but we&#8217;d better take measures to prevent silos from forming. <a href="http://en.wikipedia.org/wiki/Code_review">Code reviews</a> are one candidate for this. The best approach, however, is <a href="http://www.extremeprogramming.org/rules/collective.html"><em>collective</em> code ownership</a>, especially when combined with <a href="http://en.wikipedia.org/wiki/Pair_programming">pair programming</a>.</p>
<p>Note that <a href="http://en.wikipedia.org/wiki/Extreme_Programming">eXtreme Programming</a> (XP) makes the shared theory explicit through it&#8217;s <a href="http://www.extremeprogramming.org/rules/metaphor.html">system metaphor</a> concept. This is the XP practice that I&#8217;ve always struggled most with, but now it&#8217;s finally starting to make sense to me.</p>
<p><strong>Theory building is an essential skill for software developers</strong><br />
If software development is first and foremost about building theories, then software developers better be good at it. So it makes sense to teach them this. I&#8217;m not yet aware of how to best do this, but one obvious place to start is the <a href="http://en.wikipedia.org/wiki/Scientific_method">scientific method</a>, since building theories is precisely what scientist do (even though some dispute the scientific method is actually the way scientists build theories). This reminds me of <a href="http://agile2003.agilealliance.org/files/P6Paper.pdf">the relationship between the scientific method and Test-Driven Development</a>.</p>
<p>Another promising approach is <a href="http://en.wikipedia.org/wiki/Domain-driven_design">Domain Driven Design</a>, since that places the domain model at the center of software development. Please let me know if you have more ideas on this subject.</p>
<p><strong>Software developers are not interchangeable resources</strong><br />
If the most crucial part of software development is the building of a theory, than you can&#8217;t just simply replace one developer with another, since the new girl needs to start building her theory from scratch and that takes time. This is precisely why <a href="http://en.wikipedia.org/wiki/Brooks%27s_law" title="Brook's Law">you can&#8217;t add people to a late project without making it later still</a>, as (I wish!) we all know.</p>
<p>Also, developers with a better initial theory are better suited to work on a new project, since they require less theory building. That&#8217;s why it makes sense to use developers with pre-existing <a href="http://en.wikipedia.org/wiki/Domain_knowledge">domain knowledge</a>, if possible. Conversely, that&#8217;s also why it makes sense for a developer to specialize in a given domain.</p>
<p><strong>We should expect designs to undergo significant changes</strong><br />
Taking a hint from science, we see that <a href="http://en.wikipedia.org/wiki/The_Structure_of_Scientific_Revolutions" title="The Structure of Scientific Revolutions">theories sometimes go through radical changes</a>. Now, if the <em>software design is a manifestation of the theory in the developers&#8217; mind</em>, then we can expect the design to undergo radical changes as well. This argues against <a href="http://en.wikipedia.org/wiki/Big_Design_Up_Front" title="Big Design Up Front">too much design up front</a>, and for <a href="http://jamesshore.com/Agile-Book/incremental_design.html">incremental design</a>.</p>
<p><strong>Maintenance should be done by the original developers</strong><br />
Some organizations hand off software to a maintenance team once its initial development is done. From the perspective of software development as theory building, that doesn&#8217;t make a whole lot of sense. The maintenance team doesn&#8217;t have the theories that the original developers built, and will likely make modifications that don&#8217;t fit that theory and are therefore not optimal.</p>
<p>If you do insist on separate maintenance teams, then the maintainers should be phased into the team before the initial stage ends, so they have access to people that already have well formed theories and can learn from them.</p>
<p><strong>Software developers should not be shared between teams</strong><br />
For productivity reasons, <a href="http://www.joelonsoftware.com/articles/fog0000000022.html" title="Task Switching Considered Harmful">software developers shouldn&#8217;t divide their attention between multiple projects</a>. But the theory building view of software development gives another perspective. It&#8217;s hard enough to build one theory at a time, especially if one is also learning other stuff, like new technology. Developers really shouldn&#8217;t need to learn too much in parallel, or they may feel like their head is going to explode.</p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/design/'>Design</a>, <a href='http://sinnema313.wordpress.com/category/environment/'>Environment</a>, <a href='http://sinnema313.wordpress.com/category/process/'>process</a>, <a href='http://sinnema313.wordpress.com/category/what-other-people-say/'>What other people say</a> Tagged: <a href='http://sinnema313.wordpress.com/tag/collective-code-ownership/'>collective code ownership</a>, <a href='http://sinnema313.wordpress.com/tag/domain-driven-design/'>domain driven design</a>, <a href='http://sinnema313.wordpress.com/tag/extreme-programming/'>eXtreme Programming</a>, <a href='http://sinnema313.wordpress.com/tag/incremental-design/'>incremental design</a>, <a href='http://sinnema313.wordpress.com/tag/maintenance/'>maintenance</a>, <a href='http://sinnema313.wordpress.com/tag/mental-model/'>mental model</a>, <a href='http://sinnema313.wordpress.com/tag/on-site-customer/'>on-site customer</a>, <a href='http://sinnema313.wordpress.com/tag/silos/'>silos</a>, <a href='http://sinnema313.wordpress.com/tag/system-metaphor/'>system metaphor</a>, <a href='http://sinnema313.wordpress.com/tag/tdd/'>TDD</a>, <a href='http://sinnema313.wordpress.com/tag/theory/'>theory</a>, <a href='http://sinnema313.wordpress.com/tag/ubiquitous-language/'>ubiquitous language</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/1440/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/1440/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/1440/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/1440/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/1440/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/1440/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/1440/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/1440/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/1440/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/1440/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/1440/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/1440/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/1440/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/1440/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1440&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2011/07/03/the-nature-of-software-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>
	</item>
		<item>
		<title>Top-Down Test-Driven Development</title>
		<link>http://sinnema313.wordpress.com/2011/02/13/top-down-test-driven-development/</link>
		<comments>http://sinnema313.wordpress.com/2011/02/13/top-down-test-driven-development/#comments</comments>
		<pubDate>Sun, 13 Feb 2011 21:34:00 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[EclEmma]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[factory]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[uml]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=1398</guid>
		<description><![CDATA[In Test-Driven Development (TDD), I have a tendency to dive right in at the level of some class that I am sure I&#8217;m gonna need for this cool new feature that I&#8217;m working on. This has bitten me a few &#8230; <a href="http://sinnema313.wordpress.com/2011/02/13/top-down-test-driven-development/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1398&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://en.wikipedia.org/wiki/Test_driven_development">Test-Driven Development</a> (TDD), I have a tendency to dive right in at the level of some class that I am sure I&#8217;m gonna need for this cool new feature that I&#8217;m working on. This has bitten me a few times in the past, where I would start bottom-up and work my way up, only to discover that the design should be a little different and the class I started out with is either not needed, or not needed in the way I envisioned. So today I wanted to try a top-down approach.</p>
<p>I&#8217;m running this experiment on a fresh new project that targets developers. I&#8217;m going to start with a feature that removes some of the mundane tasks of development. Specifically, when I practice TDD in Java, I start out with writing a test class. In that class, I create an instance of the Class Under Test (CUT). Since the CUT doesn&#8217;t exist at this point in time, my code doesn&#8217;t compile. So I need to create the CUT to make it compile. In Java, that consists of a couple of actions that are pretty uninteresting, but that need to be done anyway. This takes away my focus from the test, so it would be kinda cool if it somehow could be automated.</p>
<p>In work mostly in <a href="http://eclipse.org/">Eclipse</a>, and Eclipse has the notion of <a href="http://wiki.eclipse.org/FAQ_What_is_a_Quick_Fix%3F">Quick Fixes</a>. So that seems like a perfect fit. However, I don&#8217;t want my project code to be completely dependent on Eclipse, if only because independent code is easier to test.</p>
<p>So I start out with a top-down test that shows how all of this is accomplished:<br />
<pre class="brush: java;">
public class FixesFactoryTest {

  @Test
  public void missingClassUnderTest() {
    FixesFactory fixesFactory = new FixesFactory();
    Issues issues = new Issues().add(Issue
        .newProblem(new MissingType(new FullyQualifiedName(&quot;Bar&quot;)))
        .at(new FileLocation(
            new Path(&quot;src/test/java/com/acme/foo/BarTest.java&quot;),
            new FilePosition(new LineNumber(11), new ColumnNumber(5)))));
    Fixes fixes = fixesFactory.newInstance(issues);

    Assert.assertNotNull(&quot;Missing fixes&quot;, fixes);
    Assert.assertEquals(&quot;# Fixes&quot;, 1, fixes.size());

    Fix fix = fixes.iterator().next();
    Assert.assertNotNull(&quot;Missing fix&quot;, fix);
    Assert.assertEquals(&quot;Fix&quot;, CreateClassFix.class, fix.getClass());

    CreateClassFix createClassFix = (CreateClassFix) fix;
    Assert.assertEquals(&quot;Name of new class&quot;, new FullyQualifiedName(&quot;com.acme.foo.Bar&quot;),
        createClassFix.nameOfClass());
    Assert.assertEquals(&quot;Path of new class&quot;, new Path(&quot;src/main/java/com/acme/foo/Bar.java&quot;),
        createClassFix.pathOfClass());
  }

}
</pre></p>
<p>This test captures my intented design: a <code>FixesFactory</code> gives <code>Fixes</code> for <code>Issues</code>, where an <code>Issue</code> is a <code>Problem</code> at a given <code>Location</code>. This will usually be a <code>FileLocation</code>, but I envision there could be problems between files as well, like a test class whose name doesn&#8217;t match the name of its CUT. For this particular issue, I expect one fix: to create the missing CUT at the right place.</p>
<p>I&#8217;m trying to follow the rules of <a href="http://www.cs.helsinki.fi/u/luontola/tdd-2009/ext/ObjectCalisthenics.pdf">Object Calistenics</a> here, hence the classes like <code>LineNumber</code> where one may have expected a simple <code>int</code>. Partly because of that, I need a whole bunch of classes and methods before I can get this test to even compile. This feels awkward, because it&#8217;s too big a step for my taste. I want my green bar!</p>
<p>Obviously, I can&#8217;t make this pass with a few lines of code. So I add a <code>@Ignore</code> to this test, and shift focus to one of the smaller classes. Let&#8217;s see, <code>LineNumber</code> is a good candidate. I have no clue as to how I&#8217;ll be using this class, though. All I know at this point, is that it should be a value object:</p>
<p><pre class="brush: java;">
public class LineNumberTest {

  @Test
  public void valueObject() {
    LineNumber lineNumber1a = new LineNumber(313);
    LineNumber lineNumber1b = new LineNumber(313);
    LineNumber lineNumber2 = new LineNumber(42);

    Assert.assertTrue(&quot;1a == 1b&quot;, lineNumber1a.equals(lineNumber1b));
    Assert.assertFalse(&quot;1a == 2&quot;, lineNumber1a.equals(lineNumber2));

    Assert.assertTrue(&quot;# 1a == 1b&quot;, lineNumber1a.hashCode() == lineNumber1b.hashCode());
    Assert.assertFalse(&quot;# 1a == 2&quot;, lineNumber1a.hashCode() == lineNumber2.hashCode());

    Assert.assertEquals(&quot;1a&quot;, &quot;313&quot;, lineNumber1a.toString());
    Assert.assertEquals(&quot;1b&quot;, &quot;313&quot;, lineNumber1b.toString());
    Assert.assertEquals(&quot;2&quot;, &quot;42&quot;, lineNumber2.toString());
  }

}
</pre></p>
<p>This is very easy to implement in Eclipse: just select the Quick Fix to <em>Assign Parameter To Field</em> on the constructor&#8217;s single parameter and then select <em>Generate hashCode() and equals()&#8230;</em>:</p>
<p><pre class="brush: java;">
public class LineNumber {

  private final int lineNumber;

  public LineNumber(int lineNumber) {
    this.lineNumber = lineNumber;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + lineNumber;
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    LineNumber other = (LineNumber) obj;
    if (lineNumber != other.lineNumber) {
      return false;
    }
    return true;
  }

}
</pre></p>
<p>This is not the world&#8217;s most elegant code, so we&#8217;ll refactor this once we&#8217;re green. But first we need to add the trivial <code>toString()</code>:</p>
<p><pre class="brush: java;">
  @Override
  public String toString() {
    return Integer.toString(lineNumber);
  }
</pre><br />
And we&#8217;re green.</p>
<p><a href="http://www.eclemma.org/">EclEmma</a> tells me that some code in <code>LineNumber.equals()</code> is not covered. I can easily fix that by removing the <code>if</code> statements. But the remainder should clearly be refactored, and so should <code>hashCode()</code>:</p>
<p><pre class="brush: java;">
  @Override
  public int hashCode() {
    return 31 + lineNumber;
  }

  @Override
  public boolean equals(Object object) {
    LineNumber other = (LineNumber) object;
    return lineNumber == other.lineNumber;
  }

</pre></p>
<p>The other classes are pretty straightforward as well. The only issue I ran into was a <a href="https://sourceforge.net/tracker/?func=detail&amp;aid=3178921&amp;group_id=177969&amp;atid=883351">bug in EclEmma</a> when I changed an empty class to an interface. But I can work around that by restarting Eclipse.</p>
<p>If you are interested to see where this project is going, feel free to take a look at <a href="https://sourceforge.net/projects/code-colleague/">SourceForge</a>. Maybe you&#8217;d even like to join in!</p>
<p><strong>Retrospective</strong></p>
<p>So what does this exercise teach me? I noted earlier that it felt awkward to be writing a big test that I can&#8217;t get to green. But I now realize that I felt that way because I&#8217;ve trained myself to be thinking about getting to green quickly. After all, that was always the purpose of writing a test.</p>
<p>But it wasn&#8217;t this time. This time it was really about <em>writing down the design</em>. That part I usually did in my head, or on a piece of paper or whiteboard <em>before</em> I would write my first test. By writing the design down as a test, I&#8217;m making it more concrete than UML could ever hope to be. So that&#8217;s definitely a win from my perspective.</p>
<p>The other thing I noted was not so good: I set out to write a top-down test, yet I didn&#8217;t. I didn&#8217;t start at the bottom either, but somewhere in the middle. I was quick to dismiss the Eclipse part, because I wanted at least part of the code to be independent from Eclipse. Instead, I should have coded all of that up in a test. That would have forced me to consider whether I can actually make the design work in an Eclipse plug-in. So I guess I have to practice a bit more at this top-down TDD stuff&#8230;</p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/code/'>Code</a>, <a href='http://sinnema313.wordpress.com/category/design/'>Design</a>, <a href='http://sinnema313.wordpress.com/category/process/'>process</a>, <a href='http://sinnema313.wordpress.com/category/test/'>test</a> Tagged: <a href='http://sinnema313.wordpress.com/tag/eclemma/'>EclEmma</a>, <a href='http://sinnema313.wordpress.com/tag/eclipse/'>eclipse</a>, <a href='http://sinnema313.wordpress.com/tag/factory/'>factory</a>, <a href='http://sinnema313.wordpress.com/tag/java/'>java</a>, <a href='http://sinnema313.wordpress.com/tag/refactoring/'>refactoring</a>, <a href='http://sinnema313.wordpress.com/tag/tdd/'>TDD</a>, <a href='http://sinnema313.wordpress.com/tag/uml/'>uml</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/1398/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/1398/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/1398/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/1398/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/1398/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/1398/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/1398/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/1398/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/1398/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/1398/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/1398/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/1398/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/1398/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/1398/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1398&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2011/02/13/top-down-test-driven-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>
	</item>
		<item>
		<title>Software Craftmanship</title>
		<link>http://sinnema313.wordpress.com/2011/01/16/software-craftmanship/</link>
		<comments>http://sinnema313.wordpress.com/2011/01/16/software-craftmanship/#comments</comments>
		<pubDate>Sun, 16 Jan 2011 09:36:13 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=1378</guid>
		<description><![CDATA[There has been quite some activity in the blogosphere around the term Software Craftmanship lately, and I&#8217;d like to chime in with my two cents. Background Pete McBreen&#8217;s book Software Craftmanship started what now can be called a movement, as &#8230; <a href="http://sinnema313.wordpress.com/2011/01/16/software-craftmanship/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1378&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>There has been quite some activity in the blogosphere around the term Software Craftmanship lately, and I&#8217;d like to chime in with my two cents.</p>
<p><strong>Background</strong><br />
Pete McBreen&#8217;s book <a href="http://www.amazon.com/Software-Craftsmanship-Imperative-Pete-McBreen/dp/0201733862/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1295165069&amp;sr=8-1">Software Craftmanship</a> started what now can be called a movement, as is evidenced by the fact that there is a <a href="http://manifesto.softwarecraftsmanship.org/">manifesto</a>, a <a href="http://groups.google.com/group/software_craftsmanship/topics">mailing list</a>, and conferences in <a href="http://parlezuml.com/softwarecraftsmanship/">Europe</a> and the <a href="http://scna.softwarecraftsmanship.org/">US</a>. One of the best descriptions of the movement, I my opinion anyway, is by <a href="http://www.infoq.com/presentations/Software-Craftsmanship-Beyond-The-Hype">Corey Haines</a>.</p>
<p><strong>The Discussion</strong><br />
It all started with a <a href="http://dannorth.net/2011/01/11/programming-is-not-a-craft/">post by Dan North</a> that was critical of the movement. Members risked being elitist, indulging in navel-gazing, and coding for code&#8217;s sake. Others, like <a href="http://lizkeogh.com/2011/01/14/why-i-didnt-sign-the-software-craftsmanship-manifesto/">Liz Keogh, chimed in</a>.</p>
<p>Replies were inevitable, of course, and came from <a href="http://parlezuml.com/blog/?postid=989">Jason Gorman</a>, <a href="http://nuts.redsquirrel.com/post/2753486676/the-manifesto-for-software-craftsmanship">Dave Hoover</a>, <a href="http://blog.oshineye.com/2011/01/software-craftsmanship-more-than-just.html">Ade Oshineye</a>, and <a href="http://blog.gdinwiddie.com/2011/01/15/software-craftsmanship/">George Dinwiddie</a>, among others.</p>
<p>Dan North just <a href="http://dannorth.net/2011/01/15/on-craftsmanship/">replied to the replies</a>, so I guess the discussion will continue for a while.</p>
<p><strong>My position</strong><br />
So where do I stand?</p>
<p>I signed the manifesto because of two main reasons:</p>
<ol>
<li>I take pride in my work</li>
<li>I want to be the best I can be in what I do</li>
</ol>
<p>And that&#8217;s what I think the manifesto and the movement is all about. Let me explain.</p>
<p><strong>Stages of Learning</strong><br />
The craft model assumes that there are different levels (apprentice, journeyman, master) at which software developers operate. That does not mean that software craftsmen want to return to the Dark Ages of the guilds. It simply means that they acknowledge that there are stages to learning. Whether we name those stages after the five stages in the <a href="http://en.wikipedia.org/wiki/Dreyfus_model_of_skill_acquisition">Dreyfus model</a>, the <a href="http://en.wikipedia.org/wiki/Four_stages_of_competence">four stages of competence</a>, <a href="http://en.wikipedia.org/wiki/Shu_ha_ri">Shu-Ha-Ri</a>, or something else, doesn&#8217;t really matter.</p>
<p>Nor does it matter where exactly we draw the line between those stages. The basic thing to understand here, is that we have to go through different phases on our journey to become ever better. I think that being aware of how we learn, and how learning progresses, helps us learning.</p>
<p><strong>Experience</strong><br />
Another thing the craft model emphasizes, is that there are different schools of thought on what is best. There is no one true way of doing things that we can learn. Instead, we must seek out different experiences in different places if we want to become the best we can be.</p>
<p>Don&#8217;t get me wrong: the journeyman model, however fascinating, is hardly practical for most people. But you don&#8217;t have to literally travel the world to benefit from it. Just keep the model in mind when selecting your next employer, or the next step in your career at the same employer. Take into account what you want to learn, what you haven&#8217;t yet been exposed to.</p>
<p>For instance, I learned the basics about databases in <a href="http://www.eur.nl/english/">college</a>. My knowledge expanded greatly (particularly about the <a href="http://www.oracle.com/us/products/database/index.html">Oracle RDBMS</a>) while working with <a href="http://nl.linkedin.com/in/keesverruijt">Kees Verruijt</a> at <a href="http://www.redwood.com/">Redwood</a>. And then that understanding deepened again when I learned about <a href="https://community.emc.com/community/edn/xmltech/xdb?view=overview">XML databases</a> at X-Hive (acquired by EMC, where I still work).</p>
<p><strong>Practice</strong><br />
So, does the manifesto help at all with learning or with learning how to learn? I&#8217;m afraid not. That&#8217;s why <a href="http://blog.oshineye.com/2011/01/software-craftsmanship-more-than-just.html">some have suggested adding a <em>Further Reading</em> section</a> to it. But that won&#8217;t cut it, since learning is about much more than reading.</p>
<p>You also need to <a href="http://en.wikipedia.org/wiki/Practice_%28learning_method%29">practice</a> and <a href="http://en.wikipedia.org/wiki/Reflective_practice">reflect</a> to grow. That&#8217;s why there is so much talk about <a href="http://codingdojo.org/">coding dojos</a>, <a href="http://en.wikipedia.org/wiki/Kata_%28programming%29">katas</a>, <a href="http://coderetreat.com/">code retreats</a>, or even <a href="http://jamesshore.com/Blog/Etudes-for-Excellence.html">etudes</a> and <a href="http://www.cs.helsinki.fi/u/luontola/tdd-2009/ext/ObjectCalisthenics.pdf">object calisthenics</a>.</p>
<p>I can understand that some people get uneasy by all that weird terminology. But I encourage them to look beyond the words. The point is simply that <a href="http://projects.ict.usc.edu/itw/gel/EricssonDeliberatePracticePR93.pdf">in order to become an expert, you need to practice</a>, as the craft model teaches us.</p>
<p><strong>Beyond the Manifesto</strong><br />
In summary, my position is that there is value in thinking about software development as a craft. That doesn&#8217;t mean that I think that the Manifesto is perfect. In fact, it doesn&#8217;t help me much in learning or in learning about learning. So where do we go from here? We need more concrete help on our journey to mastery.</p>
<p>But I don&#8217;t particularly like the idea of re-introducing guilds through some formal institution like a <em>Software Craftsmanship Council</em>. I also don&#8217;t think we need it.</p>
<p>We already have ways of knowing how good people are. We have to, or else how could we hire good software developers? So I think we should start by looking at the types of things we look for in candidates during our hiring process. Something like a <a href="http://www.starling-software.com/employment/programmer-competency-matrix.html">Software Competency Matrix</a> would be a good start for an aspiring craftsman to get a feel for what areas to improve.</p>
<p>Score yourself on each of the items in the matrix. Find your weak spots, and improve them through practice, practice, and some more practice. And have fun doing it!</p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/uncategorized/'>Uncategorized</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/1378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/1378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/1378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/1378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/1378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/1378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/1378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/1378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/1378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/1378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/1378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/1378/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/1378/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/1378/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1378&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2011/01/16/software-craftmanship/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>
	</item>
		<item>
		<title>The verdict on Perforce</title>
		<link>http://sinnema313.wordpress.com/2010/11/10/the-verdict-on-perforce/</link>
		<comments>http://sinnema313.wordpress.com/2010/11/10/the-verdict-on-perforce/#comments</comments>
		<pubDate>Wed, 10 Nov 2010 11:01:43 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[Environment]]></category>
		<category><![CDATA[bazaar]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[perforce]]></category>
		<category><![CDATA[scm]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=1320</guid>
		<description><![CDATA[At work, I&#8217;m now forced to use the Perforce version control system, since that&#8217;s what our company has standardized upon. I&#8217;ve had some bad feelings about that from the start (based on reading about it), but I&#8217;ve hold off on &#8230; <a href="http://sinnema313.wordpress.com/2010/11/10/the-verdict-on-perforce/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1320&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>At work, I&#8217;m now forced to use the <a href="http://www.perforce.com/">Perforce version control</a> system, since that&#8217;s what our company has standardized upon. I&#8217;ve had some bad feelings about that from the start (based on reading about it), but I&#8217;ve hold off on publicizing them so I could give Perforce a fair chance. After all, I have been wrong before <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . So now that I&#8217;ve worked with it for several months, here&#8217;s my verdict.</p>
<p><strong>Speed</strong><br />
The Perforce slogan is <em>Perforce, The Fast Software Configuration Management System</em>. So they&#8217;re basically claiming that they are faster than their competitors. How does this claim hold up?</p>
<p>That question is not so easy to answer, since their competitors are not a homogeneous bunch. But let&#8217;s look at one category of competitors: the <a href="http://en.wikipedia.org/wiki/Distributed_revision_control">distributed version control systems</a>. The most well-known of these are <a href="http://git-scm.com/">Git</a>, <a href="http://bazaar.canonical.com/en/">Bazaar</a>, and <a href="http://mercurial.selenic.com/">Mercurial</a>. Interestingly, Git calls itself <em>The <strong>fast </strong>version control system</em> and Mercurial&#8217;s slogan is <em>Work easier, Work <strong>faster</strong></em>.</p>
<p>Distributed version control systems work locally, meaning they don&#8217;t need a network connection. Contrast this with Perforce, that needs a network connection for everything. And I mean everything, to a ridiculous level. For instance, even the help command needs a network connection:</p>
<pre>$ p4 help
Perforce client error:
        Connect to server failed; check $P4PORT.
        TCP connect to perforce failed.
        perforce: host unknown.</pre>
<p>Now, obviously network access is going to slow things down a lot, so it&#8217;s difficult to see how Perforce can still beat their competitors on speed. And my experience has been very clear: it doesn&#8217;t! In fact, <strong>Perforce is very slow</strong>. Now obviously, that depends on your network bandwidth, so your mileage may vary.</p>
<p>But it gets worse. My primary interface to Perforce is not the command line client, but the <a href="http://www.perforce.com/perforce/products/p4wsad.html">Eclipse integration</a>, P4WSAD. And although Perforce claims that this is <em>the best of both worlds</em>, my opinion is that this is a piece of crap. There, I said it. <strong>P4WSAD makes my life as a developer a hell.</strong></p>
<p>Perforce makes all files read-only by default. Only once you&#8217;ve checked out a file, will it become writable. And, you&#8217;ve guessed it, that requires network access. In practice, this means that everytime I want to change some source file, I have to wait until P4SWAD checks out the file, which can take up to five seconds! This is extremely annoying, because it completely breaks my flow. And if you think one file is bad, try doing a refactoring that affects multiple files&#8230; It is reason enough for me to not ever want to work with Perforce again.</p>
<p>BTW, it is interesting to note that none of the aforementioned distributed version control systems appear in <a href="http://www.perforce.com/perforce/reviews.html">Perforce&#8217;s comparison with its competitors</a>.</p>
<p><strong>More connection troubles</strong><br />
Now if all this slowness actually bought me some nice features, that could change the story, right? Well, yes, it could. But it doesn&#8217;t.</p>
<p>The same cause for slowness, accessing the network for everything, is also limiting what you can do.</p>
<p>For instance, I have a long commute in the train, so I like to work there. And guess what, I don&#8217;t have an internet connection there. Not to worry, Perforce has a workaround called <a href="http://kb.perforce.com/?article=002">offline mode</a>. This basically means that <strong>P4WSAD will nag you for confirmation</strong> every time you try to change a file.</p>
<p>It also means that <strong>it looses track of which files were changed</strong>, so that when you get back online, you forget to submit some files and break the build. <a href="http://sinnema313.wordpress.com/2010/07/25/root-cause-analysis/">That has happened to me</a> quite a few times now, because the <em>reconcile</em> feature is not available in P4SWAD. You need to use the <a href="http://www.perforce.com/perforce/products/p4v.html">Perforce Visual Client</a> (P4V) for that. So now I need to use two tools to get my work done.</p>
<p>Another limitation of P4WSAD is that <strong>it will block a refactoring</strong> affecting a file that you haven&#8217;t already modified since you went offline. This means you have to hunt down all the places where, say, a method to be renamed is used, and force a &#8220;checkout&#8221; of all those places by changing something in the file. Only then can you do your refactoring. Very annoying.</p>
<p><strong>Transactions</strong><br />
Perforce claims to support <a href="http://www.perforce.com/perforce/bullet.html#atomic">transactions</a>, which is a must for a source code control system. We don&#8217;t want our automated build to pick up part of a set of changed files and break because of that!</p>
<p>Unfortunately, transactions in Perforce only work when they work. In other words, when an error occurs, it&#8217;s very well possible that Perforce will have comitted only a subset of the files in the &#8220;transaction&#8221;. This is not a really big deal, as it doesn&#8217;t happen all that often, but still.</p>
<p><strong>Directories</strong><br />
Perforce is completely file based; it doesn&#8217;t track directories. So it&#8217;s impossible to add an empty directory to a repository, for instance. Also, when someone removes a directory, Perforce by default will leave empty directories on people&#8217;s file systems when they synchronize. There is a <a href="http://kb.perforce.com/article/42/deleting-empty-directories">setting</a> to fix that, but it&#8217;s set to the wrong value by default. I consider this only a minor flaw, but it&#8217;s annoying nonetheless.</p>
<p><strong>Conclusion</strong><br />
Would I recommend Perforce to anybody? Not really. I think there are better alternatives out there. Free ones, mind you. So save yourself some money and check out (pun intended) Git, Mercurial, or Bazaar.</p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/environment/'>Environment</a> Tagged: <a href='http://sinnema313.wordpress.com/tag/bazaar/'>bazaar</a>, <a href='http://sinnema313.wordpress.com/tag/git/'>git</a>, <a href='http://sinnema313.wordpress.com/tag/mercurial/'>mercurial</a>, <a href='http://sinnema313.wordpress.com/tag/perforce/'>perforce</a>, <a href='http://sinnema313.wordpress.com/tag/scm/'>scm</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/1320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/1320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/1320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/1320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/1320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/1320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/1320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/1320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/1320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/1320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/1320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/1320/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/1320/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/1320/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1320&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2010/11/10/the-verdict-on-perforce/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>
	</item>
		<item>
		<title>Bowling Again</title>
		<link>http://sinnema313.wordpress.com/2010/08/05/bowling-again/</link>
		<comments>http://sinnema313.wordpress.com/2010/08/05/bowling-again/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 00:47:44 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[bowling]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[refactoring]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=1266</guid>
		<description><![CDATA[It&#8217;s been a while since I&#8217;ve done the bowling game scoring exercise. For those of you who don&#8217;t know it, the bowling game (ten-pin) is almost the Hello, world! of TDD. I want to learn Groovy, but I&#8217;m going to &#8230; <a href="http://sinnema313.wordpress.com/2010/08/05/bowling-again/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1266&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I&#8217;ve done the bowling game scoring exercise. For those of you who don&#8217;t know it, the bowling game (<a href="http://en.wikipedia.org/wiki/Tenpin">ten-pin</a>) is almost the <code>Hello, world!</code> of <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a>. <a href="http://sinnema313.wordpress.com/2010/07/25/root-cause-analysis/">I want to learn Groovy</a>, but I&#8217;m going to re-do it in Java first, so that I have recent code and feelings to compare when I sink my teeth in Groovy.</p>
<p>Here&#8217;s the goal for this exercise: <em>write a program that can score a bowling game. Inputs are the rolls, output the score</em>.</p>
<p>The first thing to note is that the inputs are rolls (number of pins knocked down), while the score depends on <em>frames</em>. A frame consists of up to two rolls: if the first roll knocks all 10 pins down, then we&#8217;re talking about a <em>strike</em> and the frame consist of just the one roll. Otherwise, the frame consists of two rolls. If the second roll knocks down all pins, the frame is called a <em>spare</em>, else it&#8217;s a regular frame. The only exception is the last frame. If that is a strike or a spare, it will consist of three rolls. We call those <em>bonus frames</em>.</p>
<p><strong>Frames</strong></p>
<p>So our first task is to distinguish the several types of frames. Let&#8217;s start simple, with a regular frame:<br />
<pre class="brush: java;">
public class RegularFrameTest {

  @Test
  public void frame() {
    final Frame frame = new RegularFrame(2, 5);
    Assert.assertEquals(&quot;# rolls&quot;, 2, frame.numRolls());
    Assert.assertEquals(&quot;First&quot;, 2, frame.pins(0));
    Assert.assertEquals(&quot;Second&quot;, 5, frame.pins(1));
  }

}
</pre></p>
<p>This forces me to write the <code>Frame</code> interface:<br />
<pre class="brush: java;">
public interface Frame {

  int numRolls();
  int pins(int index);

}
</pre></p>
<p>The implementation is straightforward:<br />
<pre class="brush: java;">
public class RegularFrame implements Frame {

  private final int first;
  private final int second;

  public RegularFrame(final int first, final int second) {
    this.first = first;
    this.second = second;
  }

  @Override
  public int numRolls() {
    return 2;
  }

  @Override
  public int pins(final int index) {
    return index == 0 ? first : second;
  }

}
</pre></p>
<p>Now, let&#8217;s do a spare:<br />
<pre class="brush: java;">
public class SpareTest {

  @Test
  public void frame() {
    final Frame frame = new Spare(3);
    Assert.assertEquals(&quot;# rolls&quot;, 2, frame.numRolls());
    Assert.assertEquals(&quot;First&quot;, 3, frame.pins(0));
    Assert.assertEquals(&quot;Second&quot;, 7, frame.pins(1));
  }

}
</pre></p>
<p>Again, pretty easy:<br />
<pre class="brush: java;">
public class Spare implements Frame {

  private final int first;

  public Spare(final int first) {
    this.first = first;
  }

  @Override
  public int numRolls() {
    return 2;
  }

  @Override
  public int pins(final int index) {
    return index == 0 ? first : 10 - first;
  }

}
</pre></p>
<p>OK, so by now, strike should be familiar territory:<br />
<pre class="brush: java;">
public class StrikeTest {

  @Test
  public void frame() {
    final Frame frame = new Strike();
    Assert.assertEquals(&quot;# rolls&quot;, 1, frame.numRolls());
    Assert.assertEquals(&quot;first&quot;, 10, frame.pins(0));
  }

}
</pre><br />
<pre class="brush: java;">
public class Strike implements Frame {

  @Override
  public int numRolls() {
    return 1;
  }

  @Override
  public int pins(final int index) {
    return 10;
  }

}
</pre></p>
<p>And finally, the bonus frame:<br />
<pre class="brush: java;">
public class BonusFrameTest {

  @Test
  public void frame() {
    final Frame frame = new BonusFrame(10, 3, 5);
    Assert.assertEquals(&quot;# rolls&quot;, 3, frame.numRolls());
    Assert.assertEquals(&quot;first&quot;, 10, frame.pins(0));
    Assert.assertEquals(&quot;second&quot;, 3, frame.pins(1));
    Assert.assertEquals(&quot;third&quot;, 5, frame.pins(2));
  }

}
</pre><br />
<pre class="brush: java;">
public class BonusFrame implements Frame {

  private final int first;
  private final int second;
  private final int third;

  public BonusFrame(final int first, final int second, final int third) {
    this.first = first;
    this.second = second;
    this.third = third;
  }

  @Override
  public int numRolls() {
    return 3;
  }

  @Override
  public int pins(final int index) {
    switch (index) {
      case 0: return first;
      case 1: return second;
      default: return third;
    }
  }

}
</pre></p>
<p>Note that I never bothered to specify what <code>pins</code> should return for an invalid index.</p>
<p>Now, there is a lot of duplication in these classes, so let&#8217;s extract a common base class. First, I&#8217;m going to focus on <code>BonusFrame</code>, since that one has the most code.</p>
<p>I&#8217;m going to take baby steps, keeping the code green as much as possible. First, I introduce a list to hold the three separate values:<br />
<pre class="brush: java;">
public class BonusFrame implements Frame {

  private final List&lt;Integer&gt; pins = new ArrayList&lt;Integer&gt;();

  public BonusFrame(final int first, final int second, final int third) {
    this.first = first;
    this.second = second;
    this.third = third;
    pins.add(first);
    pins.add(second);
    pins.add(third);
  }

  // ...
}
</pre></p>
<p>Next, I implement <code>numRolls</code> using the new list:<br />
<pre class="brush: java;">
public class BonusFrame implements Frame {

  @Override
  public int numRolls() {
    return pins.size();
  }

  // ...
}
</pre></p>
<p>Then the <code>pins</code> method:<br />
<pre class="brush: java;">
public class BonusFrame implements Frame {

  @Override
  public int pins(final int index) {
    return pins.get(index);
  }

  // ...
}
</pre></p>
<p>Now the original fields are unused, and I can delete them safely. Never in this refactoring did I break the tests, not even for a second.</p>
<p>The second stage of this refactoring is to extract a base class that will hold the list of pins. Since the constructor is using the fields, I need to change it slightly, so that I can safely move the list. First I&#8217;ll introduce a new constructor that accepts a list of pins:<br />
<pre class="brush: java;">
public class BonusFrame implements Frame {

  protected BonusFrame(final List&lt;Integer&gt; pins) {
    this.pins.addAll(pins);
  }

  // ..
}
</pre></p>
<p>Then I change the original constructor to call the new one:<br />
<pre class="brush: java;">
public class BonusFrame implements Frame {

  public BonusFrame(final int first, final int second, final int third) {
    this(Arrays.asList(first, second, third));
  }

  // ...
}
</pre></p>
<p>Now I can do an automated <em>Extract Superclass</em> refactoring to get my coveted base class:<br />
<pre class="brush: java;">
public class BonusFrame extends BaseFrame implements Frame {

  public BonusFrame(final int first, final int second, final int third) {
    this(Arrays.asList(first, second, third));
  }

  protected BonusFrame(final List&lt;Integer&gt; pins) {
    this.pins.addAll(pins);
  }

}
</pre><br />
Unfortunately, there is no way to have Eclipse also move the constructor that I had prepared <img src='http://s0.wp.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  Also, the <code>BaseFrame </code>class doesn&#8217;t implement <code>Frame</code> yet:<br />
<pre class="brush: java;">
public class BaseFrame {

  protected final List&lt;Integer&gt; pins = new ArrayList&lt;Integer&gt;();

  public BaseFrame() {
    super();
  }

  @Override
  public int numRolls() {
    return pins.size();
  }

  @Override
  public int pins(final int index) {
    return pins.get(index);
  }

}</pre><br />
This is bad, since now the code doesn&#8217;t even compile anymore, thanks to the <code>@Override</code>! Let&#8217;s add the missing <code>implements</code>, so we&#8217;re back to green. The public no-arg constructor can also go, it will be generated for us.</p>
<p>Now to clean up the mess. Eclipse doesn&#8217;t offer to <em>Pull Up</em> constructors, which is a shame. So let&#8217;s move it by hand:<br />
<pre class="brush: java;">
public class BonusFrame extends BaseFrame implements Frame {

  public BonusFrame(final int first, final int second, final int third) {
    super(Arrays.asList(first, second, third));
  }

}
</pre><br />
<pre class="brush: java;">
public class BaseFrame implements Frame {

  protected BaseFrame(final List&lt;Integer&gt; pins) {
    this.pins.addAll(pins);
  }

  // ...
}
</pre></p>
<p>The list should be private, and the <code>implements Frame</code> on <code>BonusFrame</code> can go.</p>
<p>We can now use <code>BaseFrame</code> as a base class for the other classes as wel:<br />
<pre class="brush: java;">
public class Strike extends BaseFrame {

  public Strike() {
    super(Arrays.asList(10));
  }

}
</pre><br />
<pre class="brush: java;">
public class Spare extends BaseFrame {

  public Spare(final int first) {
    super(Arrays.asList(first, 10 - first));
  }

}
</pre><br />
<pre class="brush: java;">
public class RegularFrame extends BaseFrame {

  public RegularFrame(final int first, final int second) {
    super(Arrays.asList(first, second));
  }

}
</pre><br />
I&#8217;m happy with the result, so let&#8217;s move on.</p>
<p><b>From Rolls To Frames</b></p>
<p>Now that we have the different kinds of frames in place, we need a way to create them from the rolls that are our input. We basically need to convert  a series of rolls into a series of frames. This <em>series</em> idea we can capture in an <code>Iterator</code>:<br />
<pre class="brush: java;">
public class FrameIteratorTest {

  @Test
  public void regular() {
    final Iterator&lt;Frame&gt; frames = new FrameIterator(Arrays.asList(1, 2));
    Assert.assertTrue(&quot;Missing frame&quot;, frames.hasNext());

    final Frame frame = frames.next();
    Assert.assertEquals(&quot;Frame&quot;, new RegularFrame(1, 2), frame);
    Assert.assertFalse(&quot;Extra frame&quot;, frames.hasNext());
  }

}
</pre></p>
<p>But for this to work, we need to implement <code>equals</code> on <code>BaseFrame</code>:<br />
<pre class="brush: java;">
public class BaseFrameTest {

  @Test
  public void equality() {
    final Frame frame1 = new BaseFrame(Arrays.asList(4, 2));
    Assert.assertTrue(&quot;Same&quot;, frame1.equals(new BaseFrame(Arrays.asList(4, 2))));
    Assert.assertFalse(&quot;Different&quot;, frame1.equals(new BaseFrame(Arrays.asList(2, 4))));
  }

}
</pre></p>
<p>This is easy to implement, since Eclipse can generate the <code>equals</code> and <code>hashCode</code> for us:<br />
<pre class="brush: java;">
public class BaseFrame implements Frame {

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((pins == null) ? 0 : pins.hashCode());
    return result;
  }

  @Override
  public boolean equals(final Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    final BaseFrame other = (BaseFrame) obj;
    if (pins == null) {
      if (other.pins != null) {
        return false;
      }
    } else if (!pins.equals(other.pins)) {
      return false;
    }
    return true;
  }

  // ...
}
</pre></p>
<p>Now we can return to our <code>FrameIterator</code>:<br />
<pre class="brush: java;">
public class FrameIterator implements Iterator&lt;Frame&gt; {

  private final Iterator&lt;Integer&gt; rolls;

  public FrameIterator(final List&lt;Integer&gt; rolls) {
    this.rolls = rolls.iterator();
  }

  @Override
  public boolean hasNext() {
    return rolls.hasNext();
  }

  @Override
  public Frame next() {
    final int first = rolls.next();
    final int second = rolls.next();
    return new RegularFrame(first, second);
  }

  @Override
  public void remove() {
    throw new UnsupportedOperationException();
  }

}
</pre></p>
<p>OK, so how about a spare?<br />
<pre class="brush: java;">
public class FrameIteratorTest {

  @Test
  public void spare() {
    final Iterator&lt;Frame&gt; frames = new FrameIterator(Arrays.asList(8, 2));
    Assert.assertTrue(&quot;Missing frame&quot;, frames.hasNext());

    final Frame frame = frames.next();
    Assert.assertEquals(&quot;Frame&quot;, new Spare(8), frame);
  }

  // ...
}
</pre><br />
<pre class="brush: java;">
public class FrameIterator implements Iterator&lt;Frame&gt; {

  @Override
  public Frame next() {
    final int first = rolls.next();
    final int second = rolls.next();
    final Frame result;
    if (first + second == 10) {
      result = new Spare(first);
    } else {
      result = new RegularFrame(first, second);
    }
    return result;
  }

  // ...
}
</pre></p>
<p>OK, then a strike shouldn&#8217;t be too hard:<br />
<pre class="brush: java;">
public class FrameIteratorTest {

  @Test
  public void strike() {
    final Iterator&lt;Frame&gt; frames = new FrameIterator(Arrays.asList(10));
    Assert.assertTrue(&quot;Missing frame&quot;, frames.hasNext());

    final Frame frame = frames.next();
    Assert.assertEquals(&quot;Frame&quot;, new Strike(), frame);
  }

  // ...
}
</pre></p>
<p>This test doesn&#8217;t just fail, but it throws a <code>NoSuchElementException</code>, since we only provide one roll. Not too hard to fix, though:<br />
<pre class="brush: java;">
public class FrameIterator implements Iterator&lt;Frame&gt; {

  @Override
  public Frame next() {
    final Frame result;
    final int first = rolls.next();
    if (first == 10) {
      result = new Strike();
    } else {
      final int second = rolls.next();
      if (first + second == 10) {
        result = new Spare(first);
      } else {
        result = new RegularFrame(first, second);
      }
    }
    return result;
  }

  // ...
}
</pre></p>
<p>OK, that works, but the code is a bit messy. Not only do we have a magic constant, we now have it in two places! So let&#8217;s get rid of that:<br />
<pre class="brush: java;">
public class FrameIterator implements Iterator&lt;Frame&gt; {

  private static final int PINS_PER_LANE = 10;

  @Override
  public Frame next() {
    final Frame result;
    final int first = rolls.next();
    if (isAllDown(first)) {
      result = new Strike();
    } else {
      final int second = rolls.next();
      if (isAllDown(first + second)) {
        result = new Spare(first);
      } else {
        result = new RegularFrame(first, second);
      }
    }
    return result;
  }

  private boolean isAllDown(final int pins) {
    return pins == PINS_PER_LANE;
  }

  // ...
}
</pre></p>
<p>I&#8217;m still not all that happy with this code, although I guess it does state the rules quite clearly now. Maybe the messyness of the code follows the messyness of the rules? I dont know, so let&#8217;s let our background processor think that over some more while I continue.</p>
<p>We now have all the normal frames in place, but we still lack the bonus frames. First a spare:<br />
<pre class="brush: java;">
public class FrameIteratorTest {

  @Test
  public void bonusSpare() {
    final Iterator&lt;Frame&gt; frames = new FrameIterator(Arrays.asList(10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 8, 3));
    for (int i = 0; i &lt; 9; i++) {
      Assert.assertTrue(&quot;Missing frame &quot; + i, frames.hasNext());

      final Frame frame = frames.next();
      Assert.assertEquals(&quot;Frame &quot; + i, new Strike(), frame);
    }

    Assert.assertTrue(&quot;Missing bonus frame&quot;, frames.hasNext());

    final Frame frame = frames.next();
    Assert.assertEquals(&quot;Bonus frame&quot;, new BonusFrame(2, 8, 3), frame);
  }

  // ...
}
</pre><br />
<pre class="brush: java;">
public class FrameIterator implements Iterator&lt;Frame&gt; {

  private static final int NUM_FRAMES_PER_GAME = 10;

  private int numFrames;

  @Override
  public Frame next() {
    numFrames++;
    final Frame result;
    final int first = rolls.next();
    if (isAllDown(first)) {
      result = new Strike();
    } else {
      final int second = rolls.next();
      if (isAllDown(first + second)) {
        if (isFinalFrame()) {
          result = new BonusFrame(first, second, rolls.next());
        } else {
          result = new Spare(first);
        }
      } else {
        result = new RegularFrame(first, second);
      }
    }
    return result;
  }

  private boolean isFinalFrame() {
    return numFrames == NUM_FRAMES_PER_GAME;
  }

  // ...
}
</pre></p>
<p>And then the strike:<br />
<pre class="brush: java;">
public class FrameIteratorTest {

  @Test
  public void bonusStrike() {
    final Iterator&lt;Frame&gt; frames = new FrameIterator(Arrays.asList(10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 7, 2));
    for (int i = 0; i &lt; 9; i++) {
      Assert.assertTrue(&quot;Missing frame &quot; + i, frames.hasNext());

      final Frame frame = frames.next();
      Assert.assertEquals(&quot;Frame &quot; + i, new Strike(), frame);
    }

    Assert.assertTrue(&quot;Missing bonus frame&quot;, frames.hasNext());

    final Frame frame = frames.next();
    Assert.assertEquals(&quot;Bonus frame&quot;, new BonusFrame(10, 7, 2), frame);
  }

  // ...
}
</pre><br />
<pre class="brush: java;">
public class FrameIterator implements Iterator&lt;Frame&gt; {

  @Override
  public Frame next() {
    numFrames++;
    final Frame result;
    final int first = rolls.next();
    if (isAllDown(first)) {
      if (isFinalFrame()) {
        final int second = rolls.next();
        result = new BonusFrame(first, second, rolls.next());
      } else {
        result = new Strike();
      }
    } else {
      final int second = rolls.next();
      if (isAllDown(first + second)) {
        if (isFinalFrame()) {
          result = new BonusFrame(first, second, rolls.next());
        } else {
          result = new Spare(first);
        }
      } else {
        result = new RegularFrame(first, second);
      }
    }
    return result;
  }

  // ...
}
</pre></p>
<p>OK, now we really have to simplify the code! Let&#8217;s extract all the strike and spare stuff:<br />
<pre class="brush: java;">
public class FrameIterator implements Iterator&lt;Frame&gt; {

  @Override
  public Frame next() {
    numFrames++;
    final Frame result;
    final int first = rolls.next();
    if (isAllDown(first)) {
      result = newStrike(first);
    } else {
      final int second = rolls.next();
      if (isAllDown(first + second)) {
        result = newSpare(first, second);
      } else {
        result = new RegularFrame(first, second);
      }
    }
    return result;
  }

  private Frame newStrike(final int first) {
    final Frame result;
    if (isFinalFrame()) {
      final int second = rolls.next();
      result = new BonusFrame(first, second, rolls.next());
    } else {
      result = new Strike();
    }
    return result;
  }

  private Frame newSpare(final int first, final int second) {
    final Frame result;
    if (isFinalFrame()) {
      result = new BonusFrame(first, second, rolls.next());
    } else {
      result = new Spare(first);
    }
    return result;
  }

  // ...
}
</pre></p>
<p>I think I could further simplify the code by refactoring to a <em>Strategy</em> pattern and then do a <em>Replace Conditional With Polymorphism</em> to get rid of all those pesky <code>if</code> statements. But although that would make the individual methods easier to read, we would lose the overview, and it may just make the rules harder to retrieve from the code. So, I&#8217;m inclined to leave it as it is.</p>
<p>On to scoring then!</p>
<p><b>Scoring</b></p>
<p><em>This is where the fun begins.</em></p>
<p>The basic score for a frame is just the number of pins that were knocked down:<br />
<pre class="brush: java;">
public class BaseFrameTest {

  @Test
  public void baseScore() {
    final Frame frame = new BaseFrame(Arrays.asList(3, 6));
    Assert.assertEquals(&quot;Base score&quot;, 9, frame.getBaseScore());
  }

  // ...
}
</pre><br />
<pre class="brush: java;">
public interface Frame {

  int getBaseScore();

  // ...
}
</pre><br />
<pre class="brush: java;">
public class BaseFrame implements Frame {

  @Override
  public int getBaseScore() {
    int result = 0;
    for (final int pins : this.pins) {
      result += pins;
    }
    return result;
  }

  // ...
}
</pre></p>
<p>Writing that only now makes me realize that I named the list of rolls <code>pins</code>. But it&#8217;s not the pins knocked down, but the <em>list</em> of pins per roll that were knocked down:<br />
<pre class="brush: java;">
public class BaseFrame implements Frame {

  private final List&lt;Integer&gt; rolls = new ArrayList&lt;Integer&gt;();

  protected BaseFrame(final List&lt;Integer&gt; rolls) {
    this.rolls.addAll(rolls);
  }

  @Override
  public int numRolls() {
    return rolls.size();
  }

  @Override
  public int pins(final int index) {
    return rolls.get(index);
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((rolls == null) ? 0 : rolls.hashCode());
    return result;
  }

  @Override
  public boolean equals(final Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    final BaseFrame other = (BaseFrame) obj;
    if (rolls == null) {
      if (other.rolls != null) {
        return false;
      }
    } else if (!rolls.equals(other.rolls)) {
      return false;
    }
    return true;
  }

  @Override
  public int getBaseScore() {
    int result = 0;
    for (final int pins : rolls) {
      result += pins;
    }
    return result;
  }

}
</pre></p>
<p>Now, that was the easy part of scoring. Apart from the base score, strikes and spares also have extra scores. We don&#8217;t want to deal with exceptions, though. That will just lead to code littered with <code>if</code> statements. Instead, we can use polymorphism and the <em>Null Object</em> pattern:<br />
<pre class="brush: java;">
public class BaseFrameTest {

  @Test
  public void extraScore() {
    final Frame frame = new BaseFrame(Arrays.asList(3, 4));
    Assert.assertTrue(&quot;Extra score&quot;, frame.getExtraScore() instanceof NoExtraScore);
  }

  // ...
}
</pre><br />
<pre class="brush: java;">
public interface Frame {

  ExtraScore getExtraScore();

  // ...
}
</pre><br />
<pre class="brush: java;">
public interface ExtraScore {

}
</pre><br />
<pre class="brush: java;">
public class NoExtraScore implements ExtraScore {

}
</pre><br />
Note that the <code>ExtraScore</code> interface is empty for now. We will get to that in a minute. First let&#8217;s make the test pass:<br />
<pre class="brush: java;">
public class BaseFrame implements Frame {

  @Override
  public ExtraScore getExtraScore() {
    return new NoExtraScore();
  }

  // ...
}
</pre></p>
<p>For spares, the extra score is one roll:<br />
<pre class="brush: java;">
public class SpareTest {

  @Test
  public void extraScore() {
    final Frame frame = new Spare(4);
    Assert.assertTrue(&quot;Extra score&quot;, frame.getExtraScore() instanceof OneRollExtraScore);
  }

  // ...
}
</pre><br />
<pre class="brush: java;">
public class OneRollExtraScore implements ExtraScore {

}
</pre><br />
<pre class="brush: java;">
public class Spare extends BaseFrame {

  @Override
  public ExtraScore getExtraScore() {
    return new OneRollExtraScore();
  }

  // ...
}
</pre></p>
<p>For strikes, the extra score is two rolls:<br />
<pre class="brush: java;">
public class StrikeTest {

  @Test
  public void extraScore() {
    final Frame frame = new Strike();
    Assert.assertTrue(&quot;Extra score&quot;, frame.getExtraScore() instanceof TwoRollsExtraScore);
  }

  // ...
}
</pre><br />
<pre class="brush: java;">
public class TwoRollsExtraScore implements ExtraScore {

}
</pre><br />
<pre class="brush: java;">
public class Strike extends BaseFrame {

  @Override
  public ExtraScore getExtraScore() {
    return new TwoRollsExtraScore();
  }

  // ...
}
</pre></p>
<p>Allright, what about that <code>ExtraScore</code> interface? We don&#8217;t want to go back to dealing with rolls, since we have our lovely <code>FrameIterator</code> that gives us frames. So the extra score must deal with frames. First, it must tells us whether it needs any at all:<br />
<pre class="brush: java;">
public class NoExtraScoreTest {

  @Test
  public void needFrame() {
    final ExtraScore extraScore = new NoExtraScore();
    Assert.assertFalse(&quot;Need more&quot;, extraScore.needFrame());
  }

}
</pre><br />
<pre class="brush: java;">
public interface ExtraScore {

  boolean needFrame();

}
</pre><br />
<pre class="brush: java;">
public class NoExtraScore implements ExtraScore {

  @Override
  public boolean needFrame() {
    return false;
  }

}
</pre></p>
<p>We have a little bit more work for the one roll extra score:<br />
<pre class="brush: java;">
public class OneRollExtraScoreTest {

  @Test
  public void extraScore() {
    final ExtraScore extraScore = new OneRollExtraScore();
    Assert.assertTrue(&quot;Need more&quot;, extraScore.needFrame());

    final Frame frame = new RegularFrame(3, 4);
    final int score = extraScore.getScore(frame);
    Assert.assertEquals(&quot;Extra score&quot;, 3, score);
    Assert.assertFalse(&quot;Need still more&quot;, extraScore.needFrame());
  }

}
</pre><br />
<pre class="brush: java;">
public interface ExtraScore {

  int getScore(Frame frame);

  // ...
}
</pre><br />
<pre class="brush: java;">
public class OneRollExtraScore implements ExtraScore {

  private boolean needMore = true;

  @Override
  public boolean needFrame() {
    return needMore;
  }

  @Override
  public int getScore(final Frame frame) {
    needMore = false;
    return frame.pins(0);
  }

}
</pre></p>
<p>And the extra score for a strike is the most complex:<br />
<pre class="brush: java;">
public class TwoRollsExtraScoreTest {

  @Test
  public void regular() {
    final ExtraScore extraScore = new TwoRollsExtraScore();
    Assert.assertTrue(&quot;Need more&quot;, extraScore.needFrame());

    final Frame frame = new RegularFrame(6, 3);
    final int score = extraScore.getScore(frame);
    Assert.assertEquals(&quot;Extra score&quot;, 9, score);
    Assert.assertFalse(&quot;Still need more&quot;, extraScore.needFrame());
  }

  @Test
  public void strike() {
    final ExtraScore extraScore = new TwoRollsExtraScore();
    Assert.assertTrue(&quot;Need more&quot;, extraScore.needFrame());

    Frame frame = new Strike();
    int score = extraScore.getScore(frame);
    Assert.assertEquals(&quot;Extra score&quot;, 10, score);
    Assert.assertTrue(&quot;Still need more&quot;, extraScore.needFrame());

    frame = new RegularFrame(6, 3);
    score = extraScore.getScore(frame);
    Assert.assertEquals(&quot;Extra score 2&quot;, 6, score);
    Assert.assertFalse(&quot;Still need more 2&quot;, extraScore.needFrame());
  }

}
</pre><br />
<pre class="brush: java;">
public class TwoRollsExtraScore implements ExtraScore {

  private int numNeeded = 2;

  @Override
  public boolean needFrame() {
    return numNeeded &gt; 0;
  }

  @Override
  public int getScore(final Frame frame) {
    int result = 0;
    final int numGotten = Math.min(numNeeded, frame.numRolls());
    for (int i = 0; i &lt; numGotten; i++) {
      result += frame.pins(i);
    }
    numNeeded -= numGotten;
    return result;
  }

}
</pre></p>
<p>Now we need to glue all the previous together to calculate the game&#8217;s score:<br />
<pre class="brush: java;">
public class FramesScorerTest {

  @Test
  public void score() {
    final FramesScorer scorer = new FramesScorer();
    Frame frame = new FakeFrame(2);
    scorer.add(frame);
    Assert.assertEquals(&quot;Score&quot;, 9, scorer.getScore());

    List&lt;ExtraScore&gt; extraScores = scorer.getExtraScores();
    Assert.assertNotNull(&quot;Missing extra scores&quot;, extraScores);
    Assert.assertEquals(&quot;# Extra scores&quot;, 1, extraScores.size());
    Assert.assertTrue(&quot;Extra score&quot;, extraScores.get(0) instanceof FakeExtraScore);

    frame = new FakeFrame(1);
    scorer.add(frame);
    Assert.assertEquals(&quot;Score 2&quot;, 19, scorer.getScore());
    extraScores = scorer.getExtraScores();
    Assert.assertEquals(&quot;# Extra scores 2&quot;, 2, extraScores.size());

    frame = new FakeFrame(0);
    scorer.add(frame);
    Assert.assertEquals(&quot;Score 3&quot;, 30, scorer.getScore());
    extraScores = scorer.getExtraScores();
    Assert.assertEquals(&quot;# Extra scores 3&quot;, 3, extraScores.size());

    scorer.add(frame);
    Assert.assertEquals(&quot;Score 4&quot;, 41, scorer.getScore());
    extraScores = scorer.getExtraScores();
    Assert.assertEquals(&quot;# Extra scores 4&quot;, 3, extraScores.size());
  }


  private static class FakeFrame extends BaseFrame {

    protected FakeFrame(final int pins) {
      super(Arrays.asList(pins, 9 - pins));
    }

    @Override
    public ExtraScore getExtraScore() {
      return new FakeExtraScore(pins(0));
    }

  }


  private static class FakeExtraScore implements ExtraScore {

    private final int numNeeded;

    public FakeExtraScore(final int numNeeds) {
      numNeeded = numNeeds;
    }

    @Override
    public boolean needFrame() {
      return numNeeded  &gt; 0;
    }

    @Override
    public int getScore(final Frame frame) {
      return 1;
    }

  }

}
</pre><br />
This test is a lot more involved than normal, and it took some time to get it right. This is because it&#8217;s really the sequence of steps that we want to test, as all the individual steps are already tested.</p>
<p>Let&#8217;s implement this assert by assert. First, the base score:<br />
<pre class="brush: java;">
public class FramesScorer {

  private int score;

  public void add(final Frame frame) {
    score += frame.getBaseScore();
  }

  public int getScore() {
    return score;
  }

  public List&lt;ExtraScore&gt; getExtraScores() {
    return null;
  }

}
</pre></p>
<p>Next, we need to remember the extra score object:<br />
<pre class="brush: java;">
public class FramesScorer {

  private final List&lt;ExtraScore&gt; extraScores = new ArrayList&lt;ExtraScore&gt;();

  public void add(final Frame frame) {
    score += frame.getBaseScore();
    extraScores.add(frame.getExtraScore());
  }

  public List&lt;ExtraScore&gt; getExtraScores() {
    return extraScores;
  }

  // ...
}
</pre></p>
<p>Then we need to add the collected extra scores:<br />
<pre class="brush: java;">
public class FramesScorer {

  public void add(final Frame frame) {
    score += frame.getBaseScore();
    final Iterator&lt;ExtraScore&gt; iterator = extraScores.listIterator();
    while (iterator.hasNext()) {
      final ExtraScore extraScore = iterator.next();
      score += extraScore.getScore(frame);
    }
    extraScores.add(frame.getExtraScore());
  }

  // ...
}
</pre></p>
<p>And we must not forget to remove extra scores that are done:<br />
<pre class="brush: java;">
public class FramesScorer {

  public void add(final Frame frame) {
    score += frame.getBaseScore();
    final Iterator&lt;ExtraScore&gt; iterator = extraScores.listIterator();
    while (iterator.hasNext()) {
      final ExtraScore extraScore = iterator.next();
      if (extraScore.needFrame()) {
        score += extraScore.getScore(frame);
      } else {
        iterator.remove();
      }
    }
    extraScores.add(frame.getExtraScore());
  }

  // ...
}
</pre></p>
<p>Actually, the way I implemented this puts the <code>ExtraScore</code> object on the list even if it is a <code>NoExtraScore</code> object, which seems a bit wasteful. So let&#8217;s fix that:<br />
<pre class="brush: java;">
public class FramesScorerTest {

  @Test
  public void score() {
    final FramesScorer scorer = new FramesScorer();
    Frame frame = new FakeFrame(2);
    scorer.add(frame);
    Assert.assertEquals(&quot;Score&quot;, 9, scorer.getScore());

    List&lt;ExtraScore&gt; extraScores = scorer.getExtraScores();
    Assert.assertNotNull(&quot;Missing extra scores&quot;, extraScores);
    Assert.assertEquals(&quot;# Extra scores&quot;, 1, extraScores.size());
    Assert.assertTrue(&quot;Extra score&quot;, extraScores.get(0) instanceof FakeExtraScore);

    frame = new FakeFrame(1);
    scorer.add(frame);
    Assert.assertEquals(&quot;Score 2&quot;, 19, scorer.getScore());
    extraScores = scorer.getExtraScores();
    Assert.assertEquals(&quot;# Extra scores 2&quot;, 2, extraScores.size());

    frame = new FakeFrame(0);
    scorer.add(frame);
    Assert.assertEquals(&quot;Score 3&quot;, 30, scorer.getScore());
    extraScores = scorer.getExtraScores();
    Assert.assertEquals(&quot;# Extra scores 3&quot;, 2, extraScores.size());

    scorer.add(frame);
    Assert.assertEquals(&quot;Score 4&quot;, 41, scorer.getScore());
    extraScores = scorer.getExtraScores();
    Assert.assertEquals(&quot;# Extra scores 4&quot;, 2, extraScores.size());
  }

  // ...
}
</pre><br />
<pre class="brush: java;">
public class FramesScorer {

  public void add(final Frame frame) {
    score += frame.getBaseScore();
    final Iterator&lt;ExtraScore&gt; iterator = extraScores.listIterator();
    while (iterator.hasNext()) {
      final ExtraScore extraScore = iterator.next();
      score += extraScore.getScore(frame);
      if (!extraScore.needFrame()) {
        iterator.remove();
      }
    }

    final ExtraScore extraScore = frame.getExtraScore();
    if (extraScore.needFrame()) {
      extraScores.add(extraScore);
    }
  }

  //  ...
}
</pre></p>
<p>Now we need to clean this up a bit:<br />
<pre class="brush: java;">
public class FramesScorer {

  private int score;
  private final List&lt;ExtraScore&gt; extraScores = new ArrayList&lt;ExtraScore&gt;();

  public void add(final Frame frame) {
    score += frame.getBaseScore() + extraScore(frame);
    rememberExtraScore(frame);
  }

  private int extraScore(final Frame frame) {
    int result = 0;
    final Iterator&lt;ExtraScore&gt; iterator = extraScores.listIterator();
    while (iterator.hasNext()) {
      final ExtraScore extraScore = iterator.next();
      result += extraScore.getScore(frame);
      if (!extraScore.needFrame()) {
        iterator.remove();
      }
    }
    return result;
  }

  private void rememberExtraScore(final Frame frame) {
    final ExtraScore extraScore = frame.getExtraScore();
    if (extraScore.needFrame()) {
      extraScores.add(extraScore);
    }
  }

  // ...
}
</pre></p>
<p>All that&#8217;s left to do, is collect the rolls and provide them to the scorer. First the collecting:<br />
<pre class="brush: java;">
public class GameTest {

  @Test
  public void rolls() {
    final Game game = new Game();
    game.roll(3);
    game.roll(1);
    game.roll(3);
    Assert.assertEquals(&quot;Rolls&quot;, Arrays.asList(3, 1, 3), game.getRolls());
  }

}
</pre><br />
<pre class="brush: java;">
public class Game {

  private final List&lt;Integer&gt; rolls = new ArrayList&lt;Integer&gt;();

  public void roll(final int pins) {
    rolls.add(pins);
  }

  protected List&lt;Integer&gt; getRolls() {
    return rolls;
  }

}
</pre></p>
<p>And finally the glue that ties the scoring together:<br />
<pre class="brush: java;">
public class GameTest {

  @Test
  public void score() {
    final Game game = new Game();
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    game.roll(1);
    Assert.assertEquals(&quot;Score&quot;, 20, game.getScore());
  }

}
</pre><br />
<pre class="brush: java;">
public class Game {

  public int getScore() {
    final FramesScorer scorer = new FramesScorer();
    final FrameIterator frames = new FrameIterator(getRolls());
    while (frames.hasNext()) {
      scorer.add(frames.next());
    }
    return scorer.getScore();
  }

  // ...
}
</pre></p>
<p>I&#8217;m confident that the code works, but let&#8217;s make sure by adding some tests with well-known answers:<br />
<pre class="brush: java;">
public class GameTest {

  @Test
  public void perfect() {
    final Game game = new Game();
    game.roll(10);
    game.roll(10);
    game.roll(10);
    game.roll(10);
    game.roll(10);
    game.roll(10);
    game.roll(10);
    game.roll(10);
    game.roll(10);
    game.roll(10);
    game.roll(10);
    game.roll(10);
    Assert.assertEquals(&quot;Score&quot;, 300, game.getScore());
  }

  @Test
  public void alternateStrikesAndSpares() {
    final Game game = new Game();
    for (int i = 0; i &lt; 5; i++) {
      game.roll(10);
      game.roll(4);
      game.roll(6);
    }
    game.roll(10);
    Assert.assertEquals(&quot;Score&quot;, 200, game.getScore());
  }

}
</pre><br />
All green, so I guess we&#8217;re done!</p>
<p><strong>Reflection</strong></p>
<p>Let&#8217;s take another look at all the code to see if there is anything that needs some more attention.</p>
<p>One thing I notice, is that the code for <code>TwoRollsExtraScore</code> is a generalization for the other extra scores, so we could extract a base class. First, I introduce a constructor to set the private field:<br />
<pre class="brush: java;">
public class TwoRollsExtraScore implements ExtraScore {

  private int numNeeded;

  public TwoRollsExtraScore() {
    this(2);
  }

  protected TwoRollsExtraScore(final int numNeeded) {
    this.numNeeded = numNeeded;
  }

  // ...
}
</pre></p>
<p>Then use <em>Extract Superclass</em> (again with manual cleanup of the errors that Eclipse introduces):<br />
<pre class="brush: java;">
public class TwoRollsExtraScore extends BaseExtraScore {

  public TwoRollsExtraScore() {
    super(2);
  }

}
</pre><br />
<pre class="brush: java;">
public class BaseExtraScore implements ExtraScore {

  private int numNeeded;

  protected BaseExtraScore(final int numNeeded) {
    this.numNeeded = numNeeded;
  }

  @Override
  public boolean needFrame() {
    return numNeeded &gt; 0;
  }

  @Override
  public int getScore(final Frame frame) {
    int result = 0;
    final int numGotten = Math.min(numNeeded, frame.numRolls());
    for (int i = 0; i &lt; numGotten; i++) {
      result += frame.pins(i);
    }
    numNeeded -= numGotten;
    return result;
  }

}
</pre></p>
<p>And now we can use the base class to derive the other extra score classes from:<br />
<pre class="brush: java;">
public class OneRollExtraScore extends BaseExtraScore {

  protected OneRollExtraScore() {
    super(1);
  }

}
</pre><br />
<pre class="brush: java;">
public class NoExtraScore extends BaseExtraScore {

  protected NoExtraScore() {
    super(0);
  }

}
</pre></p>
<p>With that little code in the classes, one may wonder wether they are still pulling their weight. I like to think so, since they express the concepts in the game well. I introduced them because of that, after all. So I&#8217;m keeping them.</p>
<p>I also find a &#8220;bug&#8221; in <code>FakeExtraScore</code>: the <code>numNeeded</code> field is never decreased, so basically it will always keep requesting new frames. Here&#8217;s the fix:<br />
<pre class="brush: java;">
public class FramesScorerTest {

  @Test
  public void score() {
    final FramesScorer scorer = new FramesScorer();
    Frame frame = new FakeFrame(2);
    scorer.add(frame);
    Assert.assertEquals(&quot;Score&quot;, 9, scorer.getScore());

    List&lt;ExtraScore&gt; extraScores = scorer.getExtraScores();
    Assert.assertNotNull(&quot;Missing extra scores&quot;, extraScores);
    Assert.assertEquals(&quot;# Extra scores&quot;, 1, extraScores.size());
    Assert.assertTrue(&quot;Extra score&quot;, extraScores.get(0) instanceof FakeExtraScore);

    frame = new FakeFrame(1);
    scorer.add(frame);
    Assert.assertEquals(&quot;Score 2&quot;, 19, scorer.getScore());
    extraScores = scorer.getExtraScores();
    Assert.assertEquals(&quot;# Extra scores 2&quot;, 2, extraScores.size());

    frame = new FakeFrame(0);
    scorer.add(frame);
    Assert.assertEquals(&quot;Score 3&quot;, 30, scorer.getScore());
    extraScores = scorer.getExtraScores();
    Assert.assertEquals(&quot;# Extra scores 3&quot;, 0, extraScores.size());
  }


  private static class FakeFrame extends BaseFrame {

    protected FakeFrame(final int pins) {
      super(Arrays.asList(pins, 9 - pins));
    }

    @Override
    public ExtraScore getExtraScore() {
      return new FakeExtraScore(pins(0));
    }

  }


  private static class FakeExtraScore implements ExtraScore {

    private int numNeeded;

    public FakeExtraScore(final int numNeeds) {
      numNeeded = numNeeds;
    }

    @Override
    public boolean needFrame() {
      return numNeeded  &gt; 0;
    }

    @Override
    public int getScore(final Frame frame) {
      numNeeded--;
      return 1;
    }

  }

}
</pre></p>
<p>The rest of the code seems fine.</p>
<p>I must say that of all the times I&#8217;ve done this exercise, this time I ended up with the most classes/interfaces: 14 all together! But these total just 356 lines, or about 25 lines per type. Between all the syntactic cruft that Java makes me write and the generous use of blank lines that I prefer, I&#8217;d say that&#8217;s a pretty good score. I wonder how that will turn out in Groovy. Stay tuned.</p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/code/'>Code</a>, <a href='http://sinnema313.wordpress.com/category/test/'>test</a> Tagged: <a href='http://sinnema313.wordpress.com/tag/bowling/'>bowling</a>, <a href='http://sinnema313.wordpress.com/tag/eclipse/'>eclipse</a>, <a href='http://sinnema313.wordpress.com/tag/java/'>java</a>, <a href='http://sinnema313.wordpress.com/tag/refactoring/'>refactoring</a>, <a href='http://sinnema313.wordpress.com/tag/tdd/'>TDD</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/1266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/1266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/1266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/1266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/1266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/1266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/1266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/1266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/1266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/1266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/1266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/1266/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/1266/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/1266/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1266&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2010/08/05/bowling-again/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>
	</item>
		<item>
		<title>Root Cause Analysis</title>
		<link>http://sinnema313.wordpress.com/2010/07/25/root-cause-analysis/</link>
		<comments>http://sinnema313.wordpress.com/2010/07/25/root-cause-analysis/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 19:04:38 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[process]]></category>
		<category><![CDATA[ant]]></category>
		<category><![CDATA[cause effect diagram]]></category>
		<category><![CDATA[gradle]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[osgi]]></category>
		<category><![CDATA[perforce]]></category>
		<category><![CDATA[root cause analysis]]></category>
		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=1241</guid>
		<description><![CDATA[I&#8217;ve moved on to a new project recently. It&#8217;s quite different from the previous one. Before I worked on a monolythic web application, now we&#8217;re using OSGi. As a result, our project consists of a lot of sub-projects (OSGi bundles) &#8230; <a href="http://sinnema313.wordpress.com/2010/07/25/root-cause-analysis/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1241&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve <a href="https://community.emc.com/docs/DOC-5689">moved on to a new project</a> recently. It&#8217;s quite different from the previous one. Before I worked on a monolythic web application, now we&#8217;re using <a href="http://www.osgi.org/Main/HomePage">OSGi</a>. As a result, our project consists of a lot of sub-projects (OSGi bundles) which makes it very inconvenient to use <a href="http://ant.apache.org/">Ant</a>. So we&#8217;ve switched to <a href="http://gradle.org/">Gradle</a>. Our company has also standardized on <a href="http://www.perforce.com/">Perforce,</a> where we used <a href="http://subversion.apache.org/">Subversion</a> before.</p>
<p>To summarize, a lot has changed and I&#8217;m not really up to speed yet. This is evidenced by the fact that I broke our build 4 times in 5 days. As an aspiring <a href="http://manifesto.softwarecraftsmanship.org/">software craftsman</a>, I feel really bad about that. So why did this happen so often? And can I do anything to prevent it from happening again? Enter Root Cause Analysis.</p>
<p><a href="http://en.wikipedia.org/wiki/Root_cause_analysis">Root cause analysis</a> is performed to not just treat the symptoms, but cure the disease:</p>
<blockquote><p><em>The key to effective problem solving is to first make sure you understand the problem that you are<br />
trying to solve &#8211; why it needs to be solved, how you will know when you’ve solved it, and what the<br />
root cause is.<br />
Often symptoms show up in one place while the actual cause of the problem is somewhere<br />
completely different. If you just “solve” the symptom without digging deeper it is highly likely that<br />
problem will just reappear later in a different shape.</em></p></blockquote>
<p>Henrik Kniberg has written about one way of doing root cause analysis: using <a href="http://www.crisp.se/henrik.kniberg/cause-effect-diagrams.pdf">Cause-Effect diagrams</a>. Using this method, I ended up with the following:<br />
<div id="attachment_1255" class="wp-caption alignnone" style="width: 394px"><a href="http://sinnema313.files.wordpress.com/2010/07/build-failure-root-cause-analysis1.png"><img src="http://sinnema313.files.wordpress.com/2010/07/build-failure-root-cause-analysis1.png?w=640" alt="" title="Build Failure Cause Effect Diagram"   class="size-full wp-image-1255" /></a><p class="wp-caption-text">Build Failure Cause Effect Diagram</p></div></p>
<p>I started out with the problem: Build Failure, in the orange rectangle. I then repeatedly asked myself why this is a bad thing and added the <em>effects</em> in the red rectangles. Just repeat this until you find something that conflicts with your goal. Finally, I repeatedly added <em>causes</em> in blue rectangles. You can stop when you&#8217;ve found something you can fix, but in general it&#8217;s good to keep asking a bit deeper than feels comfortable. This is where the <a href="http://en.wikipedia.org/wiki/5_Whys">Five Whys</a> technique comes in handy.</p>
<p>As you can see, my main problem is impatience. For those who know me, that won&#8217;t come as a surprise <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  However, in this case this personal flaw of mine gets in the way of my goal of making customers happy.</p>
<p>With the causes identified, it&#8217;s time to think up some countermeasures. Pick some causes that you can fix, and think of a way to treat them. The ones I&#8217;m going to work on are marked with a star in the figure above:</p>
<ul>
<li>Use a checklist when submitting code to the source code repository. This will prevent me from making silly mistakes, such as forgetting to add a new file</li>
<li>Take the time to learn the tools better, in particular Gradle and <a href="http://groovy.codehaus.org/">Groovy</a></li>
<li>In general, try to <a href="http://www.wikihow.com/Be-Patient">be more patient</a></li>
</ul>
<p>The last one is the hard one, of course. Wish me luck!</p>
<p><strong>Update 2010-08-01:</strong> I have created a checklist with things to consider before submitting code to our Perforce repository and used this checklist all week. I broke the build twice this week, both times because of special circumstances that were not accounted for on the checklist. So I think I&#8217;m improving, but I&#8217;m not there yet.</p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/process/'>process</a> Tagged: <a href='http://sinnema313.wordpress.com/tag/ant/'>ant</a>, <a href='http://sinnema313.wordpress.com/tag/cause-effect-diagram/'>cause effect diagram</a>, <a href='http://sinnema313.wordpress.com/tag/gradle/'>gradle</a>, <a href='http://sinnema313.wordpress.com/tag/groovy/'>groovy</a>, <a href='http://sinnema313.wordpress.com/tag/osgi/'>osgi</a>, <a href='http://sinnema313.wordpress.com/tag/perforce/'>perforce</a>, <a href='http://sinnema313.wordpress.com/tag/root-cause-analysis/'>root cause analysis</a>, <a href='http://sinnema313.wordpress.com/tag/subversion/'>subversion</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/1241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/1241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/1241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/1241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/1241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/1241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/1241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/1241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/1241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/1241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/1241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/1241/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/1241/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/1241/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1241&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2010/07/25/root-cause-analysis/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>

		<media:content url="http://sinnema313.files.wordpress.com/2010/07/build-failure-root-cause-analysis1.png" medium="image">
			<media:title type="html">Build Failure Cause Effect Diagram</media:title>
		</media:content>
	</item>
		<item>
		<title>The Case for Test-Driven Development</title>
		<link>http://sinnema313.wordpress.com/2010/04/03/the-case-for-test-driven-development/</link>
		<comments>http://sinnema313.wordpress.com/2010/04/03/the-case-for-test-driven-development/#comments</comments>
		<pubDate>Sat, 03 Apr 2010 00:17:31 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=1030</guid>
		<description><![CDATA[Not everybody is convinced that Test-Driven Development (TDD) is a good idea. So here&#8217;s my attempt to change that . Changing the world is hard, though, so this will be a long post. Feedback There is value in faster feedback: &#8230; <a href="http://sinnema313.wordpress.com/2010/04/03/the-case-for-test-driven-development/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1030&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Not everybody is convinced that <a href="http://en.wikipedia.org/wiki/Test_driven">Test-Driven Development</a> (TDD) is a good idea. So here&#8217;s my attempt to change that <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . Changing the world is hard, though, so this will be a long post.</p>
<p><strong>Feedback</strong><br />
There is value in faster <a href="http://en.wikipedia.org/wiki/Feedback">feedback</a>: it allows us to steer earlier, giving us a better chance to accomplish our goals. In software development, the only <em>reliable</em> way to get feedback is by trying the software out in the wild, i.e. by having real end users perform their work with it.</p>
<p>Don&#8217;t be fooled into thinking that having someone review a design document is appropriate feedback. The reviewer does give feedback, of course, but not of the kind that will guarantee that we&#8217;ll ship a workable product. Just as the original author of the design document may miss things, so may the reviewer. The only way to be sure that our software works, is to see it working for our users. That doesn&#8217;t mean a design review isn&#8217;t valuable, just that it&#8217;s not enough. We need <a href="http://successfulsoftware.net/2008/07/09/using-defence-in-depth-to-produce-high-quality-software/">defense in depth</a> <em>all the way through</em>.</p>
<p>So, the only real way of ensuring early feedback is to deliver working software frequently and get it into the hands of end users. This is done in <strong>iterations</strong>, short time-boxed periods of development. Since we value feedback, we want our iterations to be <a href="http://jrothman.com/blog/mpd/2010/02/how-short-can-your-iterations-be.html">as short as possible</a>. And <a href="http://xprogramming.com/blog/what-is-really-essential/">short iterations require automated testing</a>, because a manual tester simply doesn&#8217;t have enough time to test the entire application.</p>
<p>TDD is one form of automated testing. It is a way of coming up with lots of small, focused, and fast tests. That&#8217;s why <a href="http://jamesshore.com/Blog/Alternatives-to-Acceptance-Testing.html">it&#8217;s more suited for rapid feedback than automated <em>acceptance</em> testing</a>. But again, we need to use all techniques in our defense in depth.</p>
<p>So that&#8217;s reason #1 for using TDD: <em>it&#8217;s required to get real feedback early and often, which gives us a better chance at delivering on time, on budget by allowing us to steer often</em>.</p>
<p><strong>Quality: reliability</strong><br />
There are at least two aspects of quality in software development. The most obvious one is <a href="http://softwaretestingfundamentals.com/defect-density/">defect density</a>. This is the <em>external</em> view of quality, the one experienced by our end users, and therefore the ultimate one.</p>
<p>Traditionally, quality was achieved using inspection, i.e. looking at some (intermediate) product and determining whether it was good enough. Manual acceptance testing falls into this category, but so do design and code reviews.</p>
<p>One problem with this approach is that testing comes at the end and is thus the most likely to suffer from schedule overruns. By writing the test before the code is written, you guarantee that testing will happen, since you can&#8217;t ship without the code.</p>
<p>Another problem is that inspection of products is expensive. You first put effort into creating a product, then into inspecting it, then into reworking it, inspecting it again, etc. That&#8217;s why many organizations changed their ways to <a href="http://www.gemba.com/tool-kit.cfm?id=631">build quality in from the start</a>, i.e. to inspect the <em>process</em> instead of the product produced by the process.</p>
<p>TDD is a way to do just that: build quality in, i.e. prevent bugs from happening because you write the tests first. We know the code will work, since it passes the test. And since no code is written unless a test fails, we know that <em>all</em> code works. (Unless, of course, a test is wrong, incomplete, or missing, which is why we also need other tools in our defense in depth.)</p>
<p>So that&#8217;s reason #2 for using TDD: <em>it builds in quality, leading to fewer defects, leading to happier customers and better productivity</em> (through less time spent fixing bugs).</p>
<p><strong>Quality: modifyability</strong><br />
But there is also the <em>internal</em> view of quality. Here we&#8217;re talking about code quality from a developer&#8217;s perspective. This is obviously less important than making our customers happy, but it&#8217;s significant nonetheless. Poor code slows us down when making changes, because it&#8217;s hard to understand. And it might be correct <em>now</em>, but if we don&#8217;t understand it well, we have a higher chance of introducing a defect when we change it.</p>
<p>So, what makes code difficult to understand? It&#8217;s the complexity of the code: the more things that are going on, the higher the chance that you&#8217;re missing some of the subtle interactions between them. The formal name is <a href="http://en.wikipedia.org/wiki/Cyclomatic_complexity">cyclomatic complexity</a>, which is a measure of the number of possible paths of execution through a piece of code. <a href="http://www.enerjy.com/blog/?p=198">Higher cyclomatic complexity is linked to higher defects</a>.</p>
<p>Static code analyzers, like <a href="http://checkstyle.sourceforge.net/config_metrics.html#CyclomaticComplexity">CheckStyle, can measure it</a> and report warnings when limits are exceeded, so that you can then fix the code. But <a href="http://www.keithbraithwaite.demon.co.uk/professional/presentations/2008/qcon/MeasureForMeasure.pdf">low cyclomatic complexity is also a byproduct of TDD</a>, since simpler code is easier to test. Thus using TDD prevents the rework of fixing the CheckStyle warnings.</p>
<p>It&#8217;s a pain to have to set up a whole bunch of objects just so you can test one of them. That&#8217;s why writing the tests first naturally encourages having objects depend on not to many other objects. This is called low <a href="http://en.wikipedia.org/wiki/Coupling_%28computer_science%29">coupling</a>, and together with high <a href="http://en.wikipedia.org/wiki/Cohesion_%28computer_science%29">cohesion</a>, it&#8217;s also a very important aspect of code quality.</p>
<p>So that&#8217;s reason #3 for using TDD: <em>it improves code quality, which leads to better productivity and fewer defects</em> (which leads to better productivity as well).</p>
<p><strong>Design</strong><br />
<em>&#8220;<a href="http://www.jigsawlounge.co.uk/film/reviews/this-is-where-the-fun-begins-another-take-on-revenge-of-the-sith/">This is where the fun begins</a>.&#8221;</em></p>
<p>Some people claim that TDD is not primarily a testing technique, but a <em>design</em> technique. They say TDD stands for Test-Driven <em>Design</em> and the tests are just a fortunate by-product of the design process. </p>
<p>To evaluate that claim we need to look at what design really is: moving from a problem (requirements) to a solution (working software that fulfills those requirements). Here&#8217;s a rough outline of how we do that:</p>
<ol>
<li>We take one requirement and think of how it constraints the solution.</li>
<li>We then think of possible ways of satisfying those constraits.</li>
<li>We take the next requirement and do the same.</li>
<li>We modify any solutions for the first requirement that conflict with those for the second one.</li>
<li>We repeat until we have satisfied all requirements.</li>
</ol>
<p>Now compare that with how TDD works:</p>
<ol>
<li>We take one requirement and think of how it constraints the solution. Then we express these constraints with one or more tests.</li>
<li>We write <a href="http://www.xprogramming.com/Practices/PracSimplest.html">the simplest code that can make the test pass</a> and then <a href="http://refactoring.com/">refactor</a> to improve the code organization.</li>
<li>We take the next requirement and do the same.</li>
<li>We fix any test or code for the first requirement that broke while implementing the second one.</li>
<li>We repeat until we have satisfied all requirements.</li>
</ol>
<p>As you can see, doing TDD <em>is</em> doing design. In fact, TDD is a leaner, more effecient way of doing design, since it limits <a href="http://moduscooperandi.com/personalkanban/why-limit-work-in-progress/">work in progress</a>. And <a href="http://www.learnleanblog.com/2008/01/lean-manufacturing-inventory-and-work.html">limiting work in progess is an important driver for productivity gains</a> in <a href="http://en.wikipedia.org/wiki/Lean_manufacturing">Lean</a>, as work in progress is seen as one of the 7 forms of <a href="http://en.wikipedia.org/wiki/Lean_manufacturing#Types_of_wastes">waste</a>.</p>
<p>So  how does TDD limit work in progress? First, TDD <a href="http://www.jbrains.ca/permalink/285">prevents rework from testing to coding</a> by limiting the amount of untested code.</p>
<p>Second, it limits the amount of design decisions awaiting implementation. Any programmer who has ever been handed a design written by someone else will know that the devil is in the details and those details will require the design to be modified. (In reality it&#8217;s likely that the design will <em>not</em> be updated, which is even worse.)</p>
<p>So that&#8217;s reason #4 for using TDD: <em>it&#8217;s a leaner, more efficient way of designing</em>.</p>
<p><strong>Documentation</strong><br />
Don&#8217;t be fooled by the lack of a design <em>document</em> in the above description. Not having a design document does <em>not</em> mean there is no design or that there is no thinking before coding. The <a href="http://www.developerdotstar.com/mag/articles/reeves_design.html">design is in the code</a>, and the tests document it. That doesn&#8217;t mean we <em>can&#8217;t</em> write documentation, just that we don&#8217;t <em>have to</em>.</p>
<p>Not only are the tests documentation, they are a superior form of documentation: you can check whether the code matches the design by compiling and running the tests. And since tests are code as well, you get the full power of your IDE to help you keep the tests up-to-date when refactoring your code under test.</p>
<p>So that&#8217;s reason #5 for using TDD: <em>it&#8217;s a leaner, more efficient way of keeping the design documentation up-to-date</em>.</p>
<p><strong>Conclusion</strong><br />
There you have it, 5 very good reasons to practice TDD:</p>
<ol>
<li>It&#8217;s required to get real feedback early and often.</li>
<li>It builds in quality, preventing rework.</li>
<li>It improves code quality, making maintenance easier.</li>
<li>It&#8217;s a leaner, more efficient way of designing.</li>
<li>It&#8217;s a leaner, more efficient way of keeping the design documentation up-to-date.</li>
</ol>
<p><strong>What others are saying</strong><br />
Don&#8217;t just take my word for it, read what others have to say as well:</p>
<ol>
<li><a href="http://blog.crisp.se/perlundholm/2010/03/03/1267608420000.html">TDD Illustrated</a></li>
<li><a href="http://jamesshore.com/Agile-Book/test_driven_development.html">The Art of Agile on TDD</a></li>
<li><a href="http://junit.sourceforge.net/doc/testinfected/testing.htm">Test infected</a></li>
<li><a href="http://anarchycreek.com/2010/02/17/the-lump-of-coding-fallacy/">TDD doesn&#8217;t slow you down</a></li>
<li><a href="http://spin.atomicobject.com/2010/01/04/faster-better-cheaper-tdd-wins-in-a-simple-experiment?utm_source=social-media&amp;utm_medium=social-media&amp;utm_campaign=social-media">Faster, better, cheaper! TDD wins in a simple experiment</a></li>
</ol>
<p>But there is more than just opinions. Although it&#8217;s always hard to scientifically test any activity that involves humans, <a href="http://biblio.gdinwiddie.com/biblio/StudiesOfTestDrivenDevelopment">some experiments have been performed</a> to assess the effectiveness and efficiency of TDD.</p>
<p><strong>Moving forward</strong><br />
So now that you&#8217;re convinced <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  of the power of TDD, how do you start?</p>
<p>Well, read <a href="http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1270251058&amp;sr=8-1">the book</a> on it. And maybe read some more on the web, e.g.</p>
<ol>
<li><a href="http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd">The Three Laws of TDD</a></li>
<li>Unit test patterns, like <a href="http://xunitpatterns.com/Four%20Phase%20Test.html">Four-Phase Test</a></li>
<li>The <a href="http://java.dzone.com/articles/tdd-checklist-red-green?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+zones%2Fagile+%28Agile+Zone%29&amp;utm_content=Google+Reader">TDD Checklist</a> (Red-Green-Refactor in Detail)</li>
<li><a href="http://blog.thecodewhisperer.com/post/333781027/what-your-tests-dont-need-to-know-will-hurt-you">Keep insignificant details out of tests</a></li>
<li><a href="http://nat.truemesh.com/archives/000714.html">Test data builders</a></li>
</ol>
<p>Or, you could just give it a spin. Download one of the xUnit families of unit testing frameworks, like <a href="http://junit.org/">JUnit</a> or <a href="http://www.nunit.org/">NUnit</a>, and get you hands dirty. And once you&#8217;ve been there and done it, get the <a href="http://www.cafepress.com/testdriven.87124879">T-shirt</a>.</p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/design/'>Design</a>, <a href='http://sinnema313.wordpress.com/category/process/'>process</a>, <a href='http://sinnema313.wordpress.com/category/test/'>test</a> Tagged: <a href='http://sinnema313.wordpress.com/tag/tdd/'>TDD</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/1030/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/1030/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/1030/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/1030/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/1030/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/1030/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/1030/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/1030/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/1030/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/1030/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/1030/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/1030/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/1030/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/1030/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1030&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2010/04/03/the-case-for-test-driven-development/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>
	</item>
		<item>
		<title>Brian Marick: I think I finally understand mocks</title>
		<link>http://sinnema313.wordpress.com/2010/03/21/brian-marick-i-think-i-finally-understand-mocks/</link>
		<comments>http://sinnema313.wordpress.com/2010/03/21/brian-marick-i-think-i-finally-understand-mocks/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 13:55:07 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[meeting]]></category>
		<category><![CDATA[agile holland]]></category>
		<category><![CDATA[devnology]]></category>
		<category><![CDATA[mock]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=1004</guid>
		<description><![CDATA[Yesterday I attended a meeting co-organized by Devnology and Agile Holland and hosted by the Dutch eBay markplaats.nl where Brian Marick talked about mocks. Brian started out with a visual demonstration of what object oriented programming is all about: interaction &#8230; <a href="http://sinnema313.wordpress.com/2010/03/21/brian-marick-i-think-i-finally-understand-mocks/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1004&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Yesterday I attended a meeting co-organized by <a href="http://devnology.nl/en/about-devnology">Devnology</a> and <a href="http://agileholland.com/en">Agile Holland</a> and hosted by the Dutch eBay <a href="http://marktplaats.nl">markplaats.nl</a> where <a href="http://www.exampler.com/about.html">Brian Marick</a> talked about <a href="http://en.wikipedia.org/wiki/Mock_object">mocks</a>.</p>
<p>Brian started out with a <a href="http://www.flickr.com/photos/devnology/sets/72157623662369462/">visual demonstration</a> of what object oriented programming is all about: interaction between objects. Each object doesn&#8217;t do very much by itself, but it&#8217;s the complex web of interacting objects that gets the job done. He visualized this interaction by having &#8220;volunteers&#8221; (representing objects) passing around a little ball (representing the flow of control):<br />
<a href="http://www.flickr.com/photos/devnology/sets/72157623662369462/"><img src="http://farm3.static.flickr.com/2804/4450603140_702af0bc85.jpg" alt="Visual Demonstration of Object Interactions" /></a></p>
<p>He then went on to introduce <em>interaction based testing</em> using mock objects. This approach is a really white form of <a href="http://en.wikipedia.org/wiki/White-box_testing">white box testing</a>, since it not only knows about objects and their methods, but also about how these methods are implemented, i.e. what other objects they call and how.</p>
<p>Interaction based testing lends itself naturally to a <em>top-down</em> approach of <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a>. This maximizes the chance that the objects that are designed into existence by the tests fit seamlessly with the objects calling them.</p>
<p>Brian described some other differences between interaction based (&#8220;London school&#8221;) and the more traditional <em>state based</em> (&#8220;Detroit school&#8221;) of TDD. Both have pros and cons, but ultimately Brian feels that interaction based testing using mocks makes it more likely to <em>work with ease</em>.<br />
<a href="http://www.exampler.com/"><img src="http://www.exampler.com/images/posting-medium.png" alt="Work with Ease" /></a></p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/meeting/'>meeting</a> Tagged: <a href='http://sinnema313.wordpress.com/tag/agile-holland/'>agile holland</a>, <a href='http://sinnema313.wordpress.com/tag/devnology/'>devnology</a>, <a href='http://sinnema313.wordpress.com/tag/mock/'>mock</a>, <a href='http://sinnema313.wordpress.com/tag/tdd/'>TDD</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/1004/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/1004/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/1004/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/1004/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/1004/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/1004/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/1004/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/1004/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/1004/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/1004/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/1004/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/1004/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/1004/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/1004/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=1004&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2010/03/21/brian-marick-i-think-i-finally-understand-mocks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>

		<media:content url="http://farm3.static.flickr.com/2804/4450603140_702af0bc85.jpg" medium="image">
			<media:title type="html">Visual Demonstration of Object Interactions</media:title>
		</media:content>

		<media:content url="http://www.exampler.com/images/posting-medium.png" medium="image">
			<media:title type="html">Work with Ease</media:title>
		</media:content>
	</item>
		<item>
		<title>Performance tuning an Ant build</title>
		<link>http://sinnema313.wordpress.com/2010/03/17/performance-tuning-an-ant-build/</link>
		<comments>http://sinnema313.wordpress.com/2010/03/17/performance-tuning-an-ant-build/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 09:33:13 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[ant]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=988</guid>
		<description><![CDATA[Common advice in the Agile world is to maintain an automated build that runs in under 10 minutes. I doubt anybody would disagree that a faster build is better than a slower one. But how do we keep the build &#8230; <a href="http://sinnema313.wordpress.com/2010/03/17/performance-tuning-an-ant-build/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=988&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Common advice in the Agile world is to maintain an automated build that runs in <a href="http://jamesshore.com/Agile-Book/ten_minute_build.html">under 10 minutes</a>. I doubt anybody would disagree that a faster build is better than a slower one. But how do we keep the build slick?</p>
<p>Usually the bulk of the build time is spend in executing tests, so that is the first place to start. But <em>as with any optimization effort, you shouldn&#8217;t guess where the pain is, but measure</em>. So how do we do that for an <a href="http://ant.apache.org/">Ant</a> build?</p>
<p>This turns out to be not hard at all. Ant will happily inform your <a href="http://ant.apache.org/manual/listeners.html">listener</a> of any interesting event, such as task started or stopped. Using that information, it is pretty straightforward to write a listener that records the time the tasks and targets take.</p>
<p>But you don&#8217;t even have to do that, you can simply use the open source <a href="https://antutility.dev.java.net/">Ant Utilities</a> project. Simply place the jar in Ant&#8217;s <code>lib</code> directory and run Ant as follows:</p>
<blockquote><pre>ant -listener net.java.antutility.BuildMetricsListener
[target]</pre>
</blockquote>
<p>At the end of the Ant build, a profile report will be displayed:</p>
<blockquote><pre>...
BUILD SUCCESSFUL
Total time: 4 minutes 6 seconds
BUILD METRICS:
Local Time, Child Time, Invocation Count, Type, Name, Location
88453, 0, 1, TASK, macker, build-core.xml:448:
70955, 0, 8, TASK, javac, dist\build.xml:608:
36563, 0, 6, TASK, jar, dist\build.xml:628:
31047, 0, 1, TASK, checkstyle, build-core.xml:251:
4031, 0, 1, TASK, exec, dist\build.xml:947:
1922, 0, 1, TASK, taskdef, build-core.xml:345:
1797, 0, 1, TASK, signjar, build-core.xml:233:
1688, 0, 1, TASK, uptodate, build-core.xml:425:
1018, 1557, 21, TASK, for, build.xml:19:
688, 0, 1, TASK, taskdef, build-core.xml:404:
609, 0, 1, TASK, property, build-core.xml:171:
533, 0, 21, TASK, taskdef, dist\build.xml:15:</pre>
</blockquote>
<p>The first column indicates the time spent in the element (task or target), the last two the name of the element and the build file name and line number.</p>
<p>But it gets <a href="http://greensopinion.blogspot.com/2009/12/ant-build-analysis-gets-facelift.html">better still</a>. You can also run your Ant build from <a href="http://eclipse.org/">Eclipse</a> and get a visual indication of the pain points in your editor:<br />
<img src="http://4.bp.blogspot.com/_vw9l2nnub6c/SyCYu7uqmzI/AAAAAAAAALk/wDJdtYqW0rc/s400/antutility-buildfile-overlay.png" alt="Visual indication of slow Ant elements in Eclipse" /></p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/code/'>Code</a> Tagged: <a href='http://sinnema313.wordpress.com/tag/ant/'>ant</a>, <a href='http://sinnema313.wordpress.com/tag/performance/'>performance</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/988/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/988/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/988/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/988/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/988/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/988/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/988/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/988/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/988/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/988/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/988/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/988/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/988/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/988/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=988&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2010/03/17/performance-tuning-an-ant-build/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>

		<media:content url="http://4.bp.blogspot.com/_vw9l2nnub6c/SyCYu7uqmzI/AAAAAAAAALk/wDJdtYqW0rc/s400/antutility-buildfile-overlay.png" medium="image">
			<media:title type="html">Visual indication of slow Ant elements in Eclipse</media:title>
		</media:content>
	</item>
		<item>
		<title>Questioning Automated Acceptance Testing</title>
		<link>http://sinnema313.wordpress.com/2010/03/03/questioning-automated-acceptance-testing/</link>
		<comments>http://sinnema313.wordpress.com/2010/03/03/questioning-automated-acceptance-testing/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 10:13:02 +0000</pubDate>
		<dc:creator>sinnema313</dc:creator>
				<category><![CDATA[process]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://sinnema313.wordpress.com/?p=979</guid>
		<description><![CDATA[The controversy There has been a flurry of activity in the blogosphere and twitterverse about the practice of automated acceptance testing. It all started when James Shore said that &#8220;acceptance testing isn&#8217;t worth the cost. I no longer use it &#8230; <a href="http://sinnema313.wordpress.com/2010/03/03/questioning-automated-acceptance-testing/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=979&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>The controversy</strong><br />
There has been a flurry of activity in the blogosphere and twitterverse about the practice of automated acceptance testing. It all started when James Shore said that &#8220;<a href="http://jamesshore.com/Blog/The-Problems-With-Acceptance-Testing.html">acceptance testing isn&#8217;t worth the cost. I no longer use it or recommend it.</a>&#8221; </p>
<p>Now, when one of the <a href="http://www.amazon.com/Art-Agile-Development-James-Shore/dp/0596527675/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1267607192&amp;sr=8-1">thought leaders</a> in the Agile community says something that goes against the established wisdom, it is sure to provoke reactions:</p>
<ul>
<li><a href="http://gojko.net/2010/03/01/are-tools-necessary-for-acceptance-testing-or-are-they-just-evil/">Gojko Adzic</a> wonders whether the cost is due to the tools and whether we could do without those tools.</li>
<li><a href="http://blog.gdinwiddie.com/2010/03/01/the-reality-of-automated-acceptance-testing/">George Dinwiddie</a> thinks Shore is throwing out the baby with the bathwater and that the problems are fixable.</li>
<li><a href="http://xprogramming.com/xpmag/problems-with-acceptance-testing">Ron Jeffries</a> doesn&#8217;t want to give up on the notion of having automated acceptance tests be part of the definition of done, but acknowledges that <a href="http://fit.c2.com/">Fit</a> is a pain to work with.</li>
<li><a href="http://blogs.stickyminds.com/Blogs/tabid/91/EntryId/172/The-One-Right-Way.aspx">Lisa Crispin</a> thinks that there is no one right way and that everybody should experiment to find out what works for them.</li>
</ul>
<p>James Shore responded to all of them in an excellent post where he explains that he found <a href="http://jamesshore.com/Blog/Alternatives-to-Acceptance-Testing.html">other ways</a> to get the benefits that automated acceptance tests bring, without incurring the costs. Some of the comments on this post are excellent as well.</p>
<p>All of these bright minds bring good points to the table. They show that the Agile community is not the dogmatic clique that it is sometimes made out to be.</p>
<p><strong>My two cents</strong><br />
I personally sympathize with Ron Jeffries. Seems like a real shame to not have automated acceptance tests be part of the definition of done. So what can we do?</p>
<p>Well, bottom line is that everybody seems to agree that customers providing examples is a good idea. The disagreement is only over whether those examples should be automated or not, and if so, how. </p>
<p>It&#8217;s true that customers don&#8217;t want to write tests. Why would they have to? Because they don&#8217;t trust tests written by others, James Shore says. Well, what about some collaboration? Why can&#8217;t the customer give examples that are turned into tests <em>on the spot</em> by developers or testers? Would the customer still not trust these? Where does the distrust come from, exactly?</p>
<p>As for the high costs, isn&#8217;t there something that we can do to lower the costs to the point where they are justified? What exactly is it that makes the costs so high? Is it the tooling, as Gojko Adzic implies? If so, why don&#8217;t we improve our tools?</p>
<br />Filed under: <a href='http://sinnema313.wordpress.com/category/process/'>process</a>, <a href='http://sinnema313.wordpress.com/category/test/'>test</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/sinnema313.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/sinnema313.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/sinnema313.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/sinnema313.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/sinnema313.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/sinnema313.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/sinnema313.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/sinnema313.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/sinnema313.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/sinnema313.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/sinnema313.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/sinnema313.wordpress.com/979/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/sinnema313.wordpress.com/979/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/sinnema313.wordpress.com/979/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=sinnema313.wordpress.com&amp;blog=3802920&amp;post=979&amp;subd=sinnema313&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://sinnema313.wordpress.com/2010/03/03/questioning-automated-acceptance-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7654bfdb2b650b7d68b569c06a6b390d?s=96&#38;d=wavatar&#38;r=G" medium="image">
			<media:title type="html">sinnema313</media:title>
		</media:content>
	</item>
	</channel>
</rss>
