<?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:creativeCommons="http://backend.userland.com/creativeCommonsRssModule">

<channel>
	<title>Thinking Inside a Bigger Box &#187; Extreme Programming</title>
	<atom:link href="http://johannesbrodwall.com/category/extreme-programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://johannesbrodwall.com</link>
	<description>Johannes Brodwall&#039;s Musings on Software Architecture and Programming</description>
	<lastBuildDate>Mon, 03 May 2010 20:24:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>		<item>
		<title>Six ideas that improve your software design</title>
		<link>http://johannesbrodwall.com/2010/05/02/six-ideas-that-improve-your-software-design/</link>
		<comments>http://johannesbrodwall.com/2010/05/02/six-ideas-that-improve-your-software-design/#comments</comments>
		<pubDate>Sun, 02 May 2010 23:00:39 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Extreme Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://johannesbrodwall.com/?p=536</guid>
		<description><![CDATA["Design" is a verb, not a noun. If I want to create a good program, studying the process of getting there is much more important than the resulting software. This is why I use coding katas as a form of study. I find an interesting problem problem and then solve the same problem over and over again. In this blog post, I will focus on six principles of software design. I will illustrate each with a screencast from a kata.

One of my favorite problems is that of creating a Java EE application from scratch. I call this kata "The Java EE Spike Kata". In order to understand the role of frameworks, I use no web frameworks in the process of creating this application. I've completed this particular exercise about forty times on my own and more than ten times with various pair-programming partners. The whole exercise takes me about 90 minutes, and I still learn new things.

The total time of the screencasts is around 40 minutes, so you may want to pick and choose. Each section provides a link to the starting point for the source code if you want to follow along.

<em><strong>Please notice</strong>: The videos are accompanied by loud, pounding music. Keep you headphones on or your volume down if you share offices with someone else. Or mute the videos if you dislike the music.</em>


<h3>Idea 1: Build your software from the outside-in</h3>

<embed src="http://blip.tv/play/AYHWhGIA" type="application/x-shockwave-flash" width="480" height="380" allowscriptaccess="always" allowfullscreen="true"></embed>

(10 minutes, <a href="http://github.com/jhannes/java-ee-spike-kata/tree/1-outside-in">github starting point</a>)

I start building the application by writing tests that access the application over HTTP and looks at the resulting HTML. As you might have gathered, when I start this test, there is no web application. Only when the tests require a web application to continue do I start creating it. In this example, I had created a basic sketch of the interaction between the three web pages in the application before I started coding. No further design was necessary.

This particular approach uses <a href="http://code.google.com/p/selenium/wiki/GettingStarted">WebDriver</a> and <a href="http://jetty.codehaus.org/jetty/">Jetty</a> to run. The cute assertion library that you may have noticed at the end of the video is <a href="http://fest.easytesting.org/assert/">FEST-assert</a>.


<h3>Idea 2: Specify behavior rather than implementation</h3>

<embed src="http://blip.tv/play/AYHWhF4A" type="application/x-shockwave-flash" width="480" height="380" allowscriptaccess="always" allowfullscreen="true"></embed>

(6 minutes, <a href="http://github.com/jhannes/java-ee-spike-kata/tree/2-1-servlet-test">github starting point</a>)

I don't make much of a distinction between different types of tests. All good tests try to describe <em>what</em> the software should do at some level, rather than <em>how</em> the software does it. But the <em>how</em> at some level may be the <em>what</em> at another level. My first test specified the interaction between the web browser and the server. In this test, one step may be to fill in the form element of a web page. This second video shows <em>how</em> this form works in terms of actual HTML. But the details of what framework (if any) is used, is not visible in the test.

The second thing you'll notice in the video is that I run the tests more frequently. And each test run is much quicker. As our tests move close to the code, the rate of feedback improves.

This particular test uses <a href="http://mockito.org/">Mockito</a> to mock out the Servlet API. The assertions use <a href="http://fest.easytesting.org/assert/">FEST-assert</a>.


<h3>Idea 3: Increase the rate of feedback</h3>

<embed src="http://blip.tv/play/AYHWhCEA" type="application/x-shockwave-flash" width="480" height="380" allowscriptaccess="always" allowfullscreen="true"></embed>

(5 minutes, <a href="http://github.com/jhannes/java-ee-spike-kata/tree/3-equals-test">github starting point</a>)

This video illustrates the frequency of feedback. The example test-drives creating an <code>equals</code>-method. This task is often not worth test-driving. The resulting method is usually simple and/or generated by your IDE. But it is a good example to of how quick the cycle between test and production code <em>can</em> be when you're writing tests that are close to the problem at hand. When I pair program this part of the kata, we usually use a technique called ping-pong programming: One programmer writes a failing test (or failing assertion) and hands the keyboard to his partner, the other programmer makes the test pass and writes another failing test before passing the keyboard back. On a good run, we will switch who's got the keyboard more often than once per minute.

Notice that I also focus on the <em>behavior</em> of the <code>equals</code>-method in this test.


<h3>Idea 4: Grow the API rather than designing it up front</h3>

<embed src="http://blip.tv/play/AYHWhEwA" type="application/x-shockwave-flash" width="480" height="380" allowscriptaccess="always" allowfullscreen="true"></embed>

(8 minutes, <a href="http://github.com/jhannes/java-ee-spike-kata/tree/4-search-for-people">github starting point</a>)

As the web application grows under my fingers, I discover the need for a Data Access Object (DAO). However, as this represents a major internal interface in my application, I use Mockito to mock the implementation until I'm done with the behavior of my servlet. When this is done, I test-drive the implementation of the DAO in a separate test class.

The video also illustrates another important lesson: The code is getting ripe for a refactoring. But it's important to resist the urge to refactor until the tests are green. If you refactor on red tests, you have much higher chances of running down a dead-end road and you'll have to throw away your progress, wondering what went wrong.

The example uses <a href="http://mockito.org">Mockito</a> to mock out the DAO API.

If you want to see how I implement the DAO with Hibernate, you can see the video on <a href="http://jhannes.blip.tv/file/3487456/">blip.tv</a>.


<h3>Idea 5: Grow the design rather than speculating</h3>

<embed src="http://blip.tv/play/AYHWhEsA" type="application/x-shockwave-flash" width="480" height="380" allowscriptaccess="always" allowfullscreen="true"></embed>

(3 minutes, <a href="http://github.com/jhannes/java-ee-spike-kata/tree/5-2-refactoring">github starting point</a>)

The video is only a partial example of this principle. Throughout the whole application, I've been refactoring, gradually pulling out structure to more well-structured methods and classes. The video illustrates some of the power of IDE's when it comes to refactoring. Using the IDE to massage your code into a better design makes evolutionary design much easier to do in practice. Make sure to learn your IDE's most useful refactorings!

The kata may seem like a non-realistic example at this time, but I've actually grown a very successful architecture on my current project using much the same approach. If you want to explore where to go next, the next step needed for this application is to factor out the views into separate classes and then use either a <a href="http://martinfowler.com/eaaCatalog/templateView.html">View Template</a> language (like Velocity) or a <a href="http://martinfowler.com/eaaCatalog/transformView.html">View Transformer</a> (using, for example dom4j) to generate the HTML. (Let me know if you'd like to see the screencast of this as well).


<h3>Idea 6: It's supposed to work the first time around</h3>

<embed src="http://blip.tv/play/AYHWhF8A" type="application/x-shockwave-flash" width="480" height="380" allowscriptaccess="always" allowfullscreen="true"></embed>

(5 minutes, <a href="http://github.com/jhannes/java-ee-spike-kata/tree/6-getting-it-to-work">github starting point</a>)

In this video, I return to the first test, <code>PersonWebTest</code>, to finish the configuration of the application. I discover a few mistakes I made in the web test as I complete the exercise. Then I try out the code in the browser. And all the scenarios I had planned for work out of the box.

When you try out your code for the first time, it should work. When you master test-driven development, you will probably forget how you programs <em>didn't</em> use to work the first time. Only when you occasionally run into an unexpected error during manual testing it becomes clear how test-driven development changes you life.

If you want to see the whole, uninterrupted 75 minute code kata, the video is available at <a href="http://jhannes.blip.tv/file/3487566/">blip.tv</a>. You can also take a look at the finished source code at <a href="http://github.com/jhannes/java-ee-spike-kata/tree/commit_per_test">github</a>.

Happy programming!


<hr />

<em>A big thanks to Trond, Thomas, Ram and Christian who helped improve this post. Thank you to Finn-Robert, Øistein, Mats, Anders, Siv, Peyman, Ivar, Øystein, Cecilia, Nicolay, and Karianne who have pair-programmed this exercise with me. I especially appreciate how Ivar and Karianne both helped influence the way the application is wired together and showed me that even after 30 iterations, I still had things to learn; and how Øistein showed me how two trained developers could complete the exercise faster with pair-programming than alone. And thank you to Nicolay who graciously brought food to our pair-programming exercise.</em>

The videos were made with the excellent (and free!) <a href="http://www.bbsoftware.co.uk/BBFlashBack_FreePlayer.aspx">BB FlashBack Express</a>. The keyboard echo is courtesy of <a href="http://katastrophos.net/magnus/blog/2008/08/01/keypose-flavour-your-screencasts-with-shortcuts/">KeyPosé</a> by Magnus Jungsbluth.]]></description>
			<content:encoded><![CDATA[<p>&#8220;Design&#8221; is a verb, not a noun. If I want to create a good program, studying the process of getting there is much more important than the resulting software. This is why I use coding katas as a form of study. I find an interesting problem problem and then solve the same problem over and over again. In this blog post, I will focus on six principles of software design. I will illustrate each with a screencast from a kata.</p>
<p>One of my favorite problems is that of creating a Java EE application from scratch. I call this kata &#8220;The Java EE Spike Kata&#8221;. In order to understand the role of frameworks, I use no web frameworks in the process of creating this application. I&#8217;ve completed this particular exercise about forty times on my own and more than ten times with various pair-programming partners. The whole exercise takes me about 90 minutes, and I still learn new things.</p>
<p>The total time of the screencasts is around 40 minutes, so you may want to pick and choose. Each section provides a link to the starting point for the source code if you want to follow along.</p>
<p><em><strong>Please notice</strong>: The videos are accompanied by loud, pounding music. Keep you headphones on or your volume down if you share offices with someone else. Or mute the videos if you dislike the music.</em></p>
<h3>Idea 1: Build your software from the outside-in</h3>
<p><embed src="http://blip.tv/play/AYHWhGIA" type="application/x-shockwave-flash" width="480" height="380" allowscriptaccess="always" allowfullscreen="true"></embed></p>
<p>(10 minutes, <a href="http://github.com/jhannes/java-ee-spike-kata/tree/1-outside-in">github starting point</a>)</p>
<p>I start building the application by writing tests that access the application over HTTP and looks at the resulting HTML. As you might have gathered, when I start this test, there is no web application. Only when the tests require a web application to continue do I start creating it. In this example, I had created a basic sketch of the interaction between the three web pages in the application before I started coding. No further design was necessary.</p>
<p>This particular approach uses <a href="http://code.google.com/p/selenium/wiki/GettingStarted">WebDriver</a> and <a href="http://jetty.codehaus.org/jetty/">Jetty</a> to run. The cute assertion library that you may have noticed at the end of the video is <a href="http://fest.easytesting.org/assert/">FEST-assert</a>.</p>
<h3>Idea 2: Specify behavior rather than implementation</h3>
<p><embed src="http://blip.tv/play/AYHWhF4A" type="application/x-shockwave-flash" width="480" height="380" allowscriptaccess="always" allowfullscreen="true"></embed></p>
<p>(6 minutes, <a href="http://github.com/jhannes/java-ee-spike-kata/tree/2-1-servlet-test">github starting point</a>)</p>
<p>I don&#8217;t make much of a distinction between different types of tests. All good tests try to describe <em>what</em> the software should do at some level, rather than <em>how</em> the software does it. But the <em>how</em> at some level may be the <em>what</em> at another level. My first test specified the interaction between the web browser and the server. In this test, one step may be to fill in the form element of a web page. This second video shows <em>how</em> this form works in terms of actual HTML. But the details of what framework (if any) is used, is not visible in the test.</p>
<p>The second thing you&#8217;ll notice in the video is that I run the tests more frequently. And each test run is much quicker. As our tests move close to the code, the rate of feedback improves.</p>
<p>This particular test uses <a href="http://mockito.org/">Mockito</a> to mock out the Servlet API. The assertions use <a href="http://fest.easytesting.org/assert/">FEST-assert</a>.</p>
<h3>Idea 3: Increase the rate of feedback</h3>
<p><embed src="http://blip.tv/play/AYHWhCEA" type="application/x-shockwave-flash" width="480" height="380" allowscriptaccess="always" allowfullscreen="true"></embed></p>
<p>(5 minutes, <a href="http://github.com/jhannes/java-ee-spike-kata/tree/3-equals-test">github starting point</a>)</p>
<p>This video illustrates the frequency of feedback. The example test-drives creating an <code>equals</code>-method. This task is often not worth test-driving. The resulting method is usually simple and/or generated by your IDE. But it is a good example to of how quick the cycle between test and production code <em>can</em> be when you&#8217;re writing tests that are close to the problem at hand. When I pair program this part of the kata, we usually use a technique called ping-pong programming: One programmer writes a failing test (or failing assertion) and hands the keyboard to his partner, the other programmer makes the test pass and writes another failing test before passing the keyboard back. On a good run, we will switch who&#8217;s got the keyboard more often than once per minute.</p>
<p>Notice that I also focus on the <em>behavior</em> of the <code>equals</code>-method in this test.</p>
<h3>Idea 4: Grow the API rather than designing it up front</h3>
<p><embed src="http://blip.tv/play/AYHWhEwA" type="application/x-shockwave-flash" width="480" height="380" allowscriptaccess="always" allowfullscreen="true"></embed></p>
<p>(8 minutes, <a href="http://github.com/jhannes/java-ee-spike-kata/tree/4-search-for-people">github starting point</a>)</p>
<p>As the web application grows under my fingers, I discover the need for a Data Access Object (DAO). However, as this represents a major internal interface in my application, I use Mockito to mock the implementation until I&#8217;m done with the behavior of my servlet. When this is done, I test-drive the implementation of the DAO in a separate test class.</p>
<p>The video also illustrates another important lesson: The code is getting ripe for a refactoring. But it&#8217;s important to resist the urge to refactor until the tests are green. If you refactor on red tests, you have much higher chances of running down a dead-end road and you&#8217;ll have to throw away your progress, wondering what went wrong.</p>
<p>The example uses <a href="http://mockito.org">Mockito</a> to mock out the DAO API.</p>
<p>If you want to see how I implement the DAO with Hibernate, you can see the video on <a href="http://jhannes.blip.tv/file/3487456/">blip.tv</a>.</p>
<h3>Idea 5: Grow the design rather than speculating</h3>
<p><embed src="http://blip.tv/play/AYHWhEsA" type="application/x-shockwave-flash" width="480" height="380" allowscriptaccess="always" allowfullscreen="true"></embed></p>
<p>(3 minutes, <a href="http://github.com/jhannes/java-ee-spike-kata/tree/5-2-refactoring">github starting point</a>)</p>
<p>The video is only a partial example of this principle. Throughout the whole application, I&#8217;ve been refactoring, gradually pulling out structure to more well-structured methods and classes. The video illustrates some of the power of IDE&#8217;s when it comes to refactoring. Using the IDE to massage your code into a better design makes evolutionary design much easier to do in practice. Make sure to learn your IDE&#8217;s most useful refactorings!</p>
<p>The kata may seem like a non-realistic example at this time, but I&#8217;ve actually grown a very successful architecture on my current project using much the same approach. If you want to explore where to go next, the next step needed for this application is to factor out the views into separate classes and then use either a <a href="http://martinfowler.com/eaaCatalog/templateView.html">View Template</a> language (like Velocity) or a <a href="http://martinfowler.com/eaaCatalog/transformView.html">View Transformer</a> (using, for example dom4j) to generate the HTML. (Let me know if you&#8217;d like to see the screencast of this as well).</p>
<h3>Idea 6: It&#8217;s supposed to work the first time around</h3>
<p><embed src="http://blip.tv/play/AYHWhF8A" type="application/x-shockwave-flash" width="480" height="380" allowscriptaccess="always" allowfullscreen="true"></embed></p>
<p>(5 minutes, <a href="http://github.com/jhannes/java-ee-spike-kata/tree/6-getting-it-to-work">github starting point</a>)</p>
<p>In this video, I return to the first test, <code>PersonWebTest</code>, to finish the configuration of the application. I discover a few mistakes I made in the web test as I complete the exercise. Then I try out the code in the browser. And all the scenarios I had planned for work out of the box.</p>
<p>When you try out your code for the first time, it should work. When you master test-driven development, you will probably forget how you programs <em>didn&#8217;t</em> use to work the first time. Only when you occasionally run into an unexpected error during manual testing it becomes clear how test-driven development changes you life.</p>
<p>If you want to see the whole, uninterrupted 75 minute code kata, the video is available at <a href="http://jhannes.blip.tv/file/3487566/">blip.tv</a>. You can also take a look at the finished source code at <a href="http://github.com/jhannes/java-ee-spike-kata/tree/commit_per_test">github</a>.</p>
<p>Happy programming!</p>
<hr />
<p><em>A big thanks to Trond, Thomas, Ram and Christian who helped improve this post. Thank you to Finn-Robert, Øistein, Mats, Anders, Siv, Peyman, Ivar, Øystein, Cecilia, Nicolay, and Karianne who have pair-programmed this exercise with me. I especially appreciate how Ivar and Karianne both helped influence the way the application is wired together and showed me that even after 30 iterations, I still had things to learn; and how Øistein showed me how two trained developers could complete the exercise faster with pair-programming than alone. And thank you to Nicolay who graciously brought food to our pair-programming exercise.</em></p>
<p>The videos were made with the excellent (and free!) <a href="http://www.bbsoftware.co.uk/BBFlashBack_FreePlayer.aspx">BB FlashBack Express</a>. The keyboard echo is courtesy of <a href="http://katastrophos.net/magnus/blog/2008/08/01/keypose-flavour-your-screencasts-with-shortcuts/">KeyPosé</a> by Magnus Jungsbluth.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2010/05/02/six-ideas-that-improve-your-software-design/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Why TDD makes a lot of sense for Sudoko</title>
		<link>http://johannesbrodwall.com/2010/04/06/why-tdd-makes-a-lot-of-sense-for-sudoko/</link>
		<comments>http://johannesbrodwall.com/2010/04/06/why-tdd-makes-a-lot-of-sense-for-sudoko/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 15:59:02 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Extreme Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://johannesbrodwall.com/?p=526</guid>
		<description><![CDATA[My colleague Thomas sent me a <a href="http://devgrind.com/2007/04/25/how-to-not-solve-a-sudoku/">very interesting link</a> about attempts to solve Sudoku using test-driven development. The article, somewhat unfairly, pits Ron Jeffries' explorations of Sudoku using test-driven development against Peter Norvig's "design driven" approach.

I found both attempts lacking. However, while Ron Jeffries freely admitted that he didn't even know the rules of Sudoku when he started, both Norvig himself and his readers fawn over his solution. I didn't find it very understandable.

So I took it upon myself to examine the problem myself. I did some up-front thinking in the shower and on the subway, then attacked the problem with TDD. I ended up with a solution that works in <em>all</em> cases (unlike Norvig). My implementation has readable code, readable tests, and solves the problem reasonably fast.

<h3>Observations and conjectures</h3>

Here are a few things I learned from the exercise:

<ul>
  <li>When you're using TDD to solve a tricky algorithm, you have to think about both the algorithm and the test approach.</li>
  <li>Solving a problem with a known algorithm using TDD gives more readable code than I otherwise would expect.</li>
  <li>When I solved the problem with TDD, running the solution on real problems worked the very first time I tried it.</li>
  <li>The trick to making TDD work is to work from the outside in.</li>
  <li>When creating a Sudoku solver, don't think like a human! Think like a machine! The human algorithm is difficult to understand and likely to not work on all problems. This was the biggest problem with Norvig's code</li>
</ul>

<h3>The journey</h3>

I decided on the following approach:

<ol>
  <li>I had decided upon an initial design with a solver class and a board class. The solver should use a recursive depth first search. The solver asks the board what options exists per cell, but it has no knowledge of the rules of Sudoku (such as no duplicate numbers on the same row).</li>
  <li>The first step was to get the solver ("the outside") correct. For this step, I mocked out the board</li>
  <li>The second step was to implement the interface that the solver needed for the board. Mainly, this is a matter of specifying the rules for what numbers can occur in which cell on a Sudoku board.</li>
  <li>Finally, I wrote some code to read and write the Sudoku board. When trying the solver on real problems, it worked the first time, and solved <a href="http://magictour.free.fr/top95">95 hard problems</a> correct. It was somewhat slow, though.</li>
</ol>

After solving the problem the first time, I practices a few times and recorded a screen cast of the solution:

<embed src="http://blip.tv/play/AYHTrDcA" type="application/x-shockwave-flash" width="480" height="380" allowscriptaccess="always" allowfullscreen="true"></embed>

<h3>The solver</h3>

Testing the solver is a matter of creating a mock board and ensuring that the solver does the correct things. This is the most complex test case:

<pre lang="java">
@Test
public void shouldBacktrackWhenNoMoreOptions() throws Exception {
    SudokuSolver solver = new SudokuSolver();
    SudokuBoard board = mock(SudokuBoard.class);
    when(board.getOptionsForCell(anyInt(), anyInt()))
            .thenReturn(singleOption());

    when(board.getOptionsForCell(8, 7))
            .thenReturn(moreOptions(1, 2));
    when(board.getOptionsForCell(8, 8))
            .thenReturn(noOptions())
            .thenReturn(singleOption());

    assertThat(solver.findSolution(board)).isTrue();
    InOrder order = inOrder(board);
    order.verify(board).setValueInCell(1, 8,7);
    order.verify(board).setValueInCell(2, 8,7);
}
</pre>

It specifies that all cells, except (8,7) and (8,8) return exactly one option. (8,7) returns two options. (8,8) returns no options the first time it is called, and one option the second time. The test verifies that a solution is found, and the solver tries to set both options for (8,7).

This drives a rather simple algorithm. Here's basically the whole algorithm:

<pre lang="java">
public boolean findSolution(Board board, int cell) {
    if (cell == SIZE*SIZE) return true;

    boolean wasEmpty = board.isEmpty(row(cell), col(cell));
    for (Integer value : board.getCellOptions(row(cell), col(cell))) {
        board.setValueInCell(value, row(cell), col(cell));
        if (findSolution(board, cell+1)) return true;
    }
    if (wasEmpty) board.clearValueInCell(row(cell), col(cell));

    return false;
}
</pre>

The algorithm tries all available options for a cell in order. If no solution works for the rest of the board, the algorithm returns false (for "no solution").

The algorithm is not how a human would solve Sudoku. But then again, we're not writing a tutorial on how to solve Sudoku, we're writing a <em>program</em> that solves Sudoku.
The board

As I implemented the solver, the interface for the board started to emerge. At that point in time, I had to create tests for the Sudoku board itself. A typical test verifies that the board doesn't allow duplicate values in a row:

<pre lang="java">
@Test
public void shouldDisallowOptionsInSameRow() throws Exception {
    int row = 4;
    board.setValueInCell(1, row, 5);
    board.setValueInCell(2, row, 8);
    board.setValueInCell(3, row+1, 5);
    assertThat(board.getOptionsForCell(row, 0))
            .excludes(1,2).contains(3);
}
</pre>

The essence of SudokuBoard is finding out what values are legal in an open cell:

<pre lang="java">
public List getOptionsForCell(int row, int col) {
    if (!isEmpty(row,col)) return Arrays.asList(cells[row][col]);
    List result = allOptions();
    removeAllInRow(result, row);
    removeAllInCol(result, col);
    removeAllInBox(result, row, col);
    return result;
}
</pre>

<h3>TDD as a design guide</h3>

I invite you to compare <a href="http://norvig.com/sudoku.html">Peter Norvig's solution</a> to mine (you can find the full source code for my solution in <a href="http://github.com/jhannes/sudoku-kata">my github repository</a>).

It would probably have been possible for me to code the solution faster without tests, but it probably would not have worked the first time I tried it. I also would have much less confidence in the code. Finally, I think the design imposed by the tests made my code easier to understand.
]]></description>
			<content:encoded><![CDATA[<p>My colleague Thomas sent me a <a href="http://devgrind.com/2007/04/25/how-to-not-solve-a-sudoku/">very interesting link</a> about attempts to solve Sudoku using test-driven development. The article, somewhat unfairly, pits Ron Jeffries&#8217; explorations of Sudoku using test-driven development against Peter Norvig&#8217;s &#8220;design driven&#8221; approach.</p>
<p>I found both attempts lacking. However, while Ron Jeffries freely admitted that he didn&#8217;t even know the rules of Sudoku when he started, both Norvig himself and his readers fawn over his solution. I didn&#8217;t find it very understandable.</p>
<p>So I took it upon myself to examine the problem myself. I did some up-front thinking in the shower and on the subway, then attacked the problem with TDD. I ended up with a solution that works in <em>all</em> cases (unlike Norvig). My implementation has readable code, readable tests, and solves the problem reasonably fast.</p>
<h3>Observations and conjectures</h3>
<p>Here are a few things I learned from the exercise:</p>
<ul>
<li>When you&#8217;re using TDD to solve a tricky algorithm, you have to think about both the algorithm and the test approach.</li>
<li>Solving a problem with a known algorithm using TDD gives more readable code than I otherwise would expect.</li>
<li>When I solved the problem with TDD, running the solution on real problems worked the very first time I tried it.</li>
<li>The trick to making TDD work is to work from the outside in.</li>
<li>When creating a Sudoku solver, don&#8217;t think like a human! Think like a machine! The human algorithm is difficult to understand and likely to not work on all problems. This was the biggest problem with Norvig&#8217;s code</li>
</ul>
<h3>The journey</h3>
<p>I decided on the following approach:</p>
<ol>
<li>I had decided upon an initial design with a solver class and a board class. The solver should use a recursive depth first search. The solver asks the board what options exists per cell, but it has no knowledge of the rules of Sudoku (such as no duplicate numbers on the same row).</li>
<li>The first step was to get the solver (&#8220;the outside&#8221;) correct. For this step, I mocked out the board</li>
<li>The second step was to implement the interface that the solver needed for the board. Mainly, this is a matter of specifying the rules for what numbers can occur in which cell on a Sudoku board.</li>
<li>Finally, I wrote some code to read and write the Sudoku board. When trying the solver on real problems, it worked the first time, and solved <a href="http://magictour.free.fr/top95">95 hard problems</a> correct. It was somewhat slow, though.</li>
</ol>
<p>After solving the problem the first time, I practices a few times and recorded a screen cast of the solution:</p>
<p><embed src="http://blip.tv/play/AYHTrDcA" type="application/x-shockwave-flash" width="480" height="380" allowscriptaccess="always" allowfullscreen="true"></embed></p>
<h3>The solver</h3>
<p>Testing the solver is a matter of creating a mock board and ensuring that the solver does the correct things. This is the most complex test case:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@Test
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> shouldBacktrackWhenNoMoreOptions<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    SudokuSolver solver <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SudokuSolver<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    SudokuBoard board <span style="color: #339933;">=</span> mock<span style="color: #009900;">&#40;</span>SudokuBoard.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    when<span style="color: #009900;">&#40;</span>board.<span style="color: #006633;">getOptionsForCell</span><span style="color: #009900;">&#40;</span>anyInt<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, anyInt<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            .<span style="color: #006633;">thenReturn</span><span style="color: #009900;">&#40;</span>singleOption<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    when<span style="color: #009900;">&#40;</span>board.<span style="color: #006633;">getOptionsForCell</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">8</span>, <span style="color: #cc66cc;">7</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            .<span style="color: #006633;">thenReturn</span><span style="color: #009900;">&#40;</span>moreOptions<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    when<span style="color: #009900;">&#40;</span>board.<span style="color: #006633;">getOptionsForCell</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">8</span>, <span style="color: #cc66cc;">8</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            .<span style="color: #006633;">thenReturn</span><span style="color: #009900;">&#40;</span>noOptions<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            .<span style="color: #006633;">thenReturn</span><span style="color: #009900;">&#40;</span>singleOption<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    assertThat<span style="color: #009900;">&#40;</span>solver.<span style="color: #006633;">findSolution</span><span style="color: #009900;">&#40;</span>board<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">isTrue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    InOrder order <span style="color: #339933;">=</span> inOrder<span style="color: #009900;">&#40;</span>board<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    order.<span style="color: #006633;">verify</span><span style="color: #009900;">&#40;</span>board<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setValueInCell</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">8</span>,<span style="color: #cc66cc;">7</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    order.<span style="color: #006633;">verify</span><span style="color: #009900;">&#40;</span>board<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setValueInCell</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">8</span>,<span style="color: #cc66cc;">7</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>It specifies that all cells, except (8,7) and (8,8) return exactly one option. (8,7) returns two options. (8,8) returns no options the first time it is called, and one option the second time. The test verifies that a solution is found, and the solver tries to set both options for (8,7).</p>
<p>This drives a rather simple algorithm. Here&#8217;s basically the whole algorithm:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">boolean</span> findSolution<span style="color: #009900;">&#40;</span>Board board, <span style="color: #000066; font-weight: bold;">int</span> cell<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>cell <span style="color: #339933;">==</span> SIZE<span style="color: #339933;">*</span>SIZE<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">boolean</span> wasEmpty <span style="color: #339933;">=</span> board.<span style="color: #006633;">isEmpty</span><span style="color: #009900;">&#40;</span>row<span style="color: #009900;">&#40;</span>cell<span style="color: #009900;">&#41;</span>, col<span style="color: #009900;">&#40;</span>cell<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Integer</span> value <span style="color: #339933;">:</span> board.<span style="color: #006633;">getCellOptions</span><span style="color: #009900;">&#40;</span>row<span style="color: #009900;">&#40;</span>cell<span style="color: #009900;">&#41;</span>, col<span style="color: #009900;">&#40;</span>cell<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        board.<span style="color: #006633;">setValueInCell</span><span style="color: #009900;">&#40;</span>value, row<span style="color: #009900;">&#40;</span>cell<span style="color: #009900;">&#41;</span>, col<span style="color: #009900;">&#40;</span>cell<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>findSolution<span style="color: #009900;">&#40;</span>board, cell<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>wasEmpty<span style="color: #009900;">&#41;</span> board.<span style="color: #006633;">clearValueInCell</span><span style="color: #009900;">&#40;</span>row<span style="color: #009900;">&#40;</span>cell<span style="color: #009900;">&#41;</span>, col<span style="color: #009900;">&#40;</span>cell<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The algorithm tries all available options for a cell in order. If no solution works for the rest of the board, the algorithm returns false (for &#8220;no solution&#8221;).</p>
<p>The algorithm is not how a human would solve Sudoku. But then again, we&#8217;re not writing a tutorial on how to solve Sudoku, we&#8217;re writing a <em>program</em> that solves Sudoku.<br />
The board</p>
<p>As I implemented the solver, the interface for the board started to emerge. At that point in time, I had to create tests for the Sudoku board itself. A typical test verifies that the board doesn&#8217;t allow duplicate values in a row:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@Test
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> shouldDisallowOptionsInSameRow<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">int</span> row <span style="color: #339933;">=</span> <span style="color: #cc66cc;">4</span><span style="color: #339933;">;</span>
    board.<span style="color: #006633;">setValueInCell</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, row, <span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    board.<span style="color: #006633;">setValueInCell</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span>, row, <span style="color: #cc66cc;">8</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    board.<span style="color: #006633;">setValueInCell</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span>, row<span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    assertThat<span style="color: #009900;">&#40;</span>board.<span style="color: #006633;">getOptionsForCell</span><span style="color: #009900;">&#40;</span>row, <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            .<span style="color: #006633;">excludes</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The essence of SudokuBoard is finding out what values are legal in an open cell:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> getOptionsForCell<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> row, <span style="color: #000066; font-weight: bold;">int</span> col<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>isEmpty<span style="color: #009900;">&#40;</span>row,col<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #003399;">Arrays</span>.<span style="color: #006633;">asList</span><span style="color: #009900;">&#40;</span>cells<span style="color: #009900;">&#91;</span>row<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>col<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">List</span> result <span style="color: #339933;">=</span> allOptions<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    removeAllInRow<span style="color: #009900;">&#40;</span>result, row<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    removeAllInCol<span style="color: #009900;">&#40;</span>result, col<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    removeAllInBox<span style="color: #009900;">&#40;</span>result, row, col<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> result<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>TDD as a design guide</h3>
<p>I invite you to compare <a href="http://norvig.com/sudoku.html">Peter Norvig&#8217;s solution</a> to mine (you can find the full source code for my solution in <a href="http://github.com/jhannes/sudoku-kata">my github repository</a>).</p>
<p>It would probably have been possible for me to code the solution faster without tests, but it probably would not have worked the first time I tried it. I also would have much less confidence in the code. Finally, I think the design imposed by the tests made my code easier to understand.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2010/04/06/why-tdd-makes-a-lot-of-sense-for-sudoko/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>What is the right iteration length?</title>
		<link>http://johannesbrodwall.com/2010/02/25/what-is-the-right-iteration-length/</link>
		<comments>http://johannesbrodwall.com/2010/02/25/what-is-the-right-iteration-length/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 19:59:42 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Extreme Programming]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://johannesbrodwall.com/?p=516</guid>
		<description><![CDATA[When picking iteration length for an agile project, there are mainly two forces that you have to balance: The rate of learning is proportional with the number of iterations, rather than the length of the project. This means that shorter iterations help you get better faster. But each iteration has some overhead with sprint reviews, retrospectives and planning. You don't want this overhead to dominate the effort spent on the project.

For some reason, most projects I've seen with little experience in iterative development prefer three week iterations. Personally, I prefer two week iterations. Here is the breakdown:

<ul>
  <li><strong>Three week iterations</strong>: After three months, you've spent about 7% of your time on iteration meetings. You've had 4 opportunities to improve.</li>
  <li><strong>Two week iterations</strong>: After three months, you've spent about 10% of your time on iteration meetings. You've had 6 opportunities to improve.</li>
  <li><strong>One week iterations</strong>: After three months, you've spent about 20% of your time on iteration meetings. You've had 12 opportunities to improve.</li>
</ul>

Going from 93% to 90% efficiency for a 50% increase in learning seems like a good deal. Going from 90% to 80% efficiency for a 100% increase in learning, not so much.

These numbers are of course greatly simplified. You might also consider:

<ul>
  <li>With shorter iterations, the planning time may go down. But this takes practice - it doesn't happen automatically.</li>
  <li>With very short iterations, you may not have experienced enough to learn much from the retrospective. However, if you find that you do a timeline, and most of the things people remember happened the last week, it may not be because that's the only time something significant happened.</li>
  <li>You may consider different frequencies for different ceremonies. For example, on my current project we want to have demos with our power users. But they have to travel far to visit us. So we only have a full demo every other four weeks. We plan every two weeks and have an internal review and retrospective every two weeks.</li>
</ul>

What's the right iteration length for your project?]]></description>
			<content:encoded><![CDATA[<p>When picking iteration length for an agile project, there are mainly two forces that you have to balance: The rate of learning is proportional with the number of iterations, rather than the length of the project. This means that shorter iterations help you get better faster. But each iteration has some overhead with sprint reviews, retrospectives and planning. You don&#8217;t want this overhead to dominate the effort spent on the project.</p>
<p>For some reason, most projects I&#8217;ve seen with little experience in iterative development prefer three week iterations. Personally, I prefer two week iterations. Here is the breakdown:</p>
<ul>
<li><strong>Three week iterations</strong>: After three months, you&#8217;ve spent about 7% of your time on iteration meetings. You&#8217;ve had 4 opportunities to improve.</li>
<li><strong>Two week iterations</strong>: After three months, you&#8217;ve spent about 10% of your time on iteration meetings. You&#8217;ve had 6 opportunities to improve.</li>
<li><strong>One week iterations</strong>: After three months, you&#8217;ve spent about 20% of your time on iteration meetings. You&#8217;ve had 12 opportunities to improve.</li>
</ul>
<p>Going from 93% to 90% efficiency for a 50% increase in learning seems like a good deal. Going from 90% to 80% efficiency for a 100% increase in learning, not so much.</p>
<p>These numbers are of course greatly simplified. You might also consider:</p>
<ul>
<li>With shorter iterations, the planning time may go down. But this takes practice &#8211; it doesn&#8217;t happen automatically.</li>
<li>With very short iterations, you may not have experienced enough to learn much from the retrospective. However, if you find that you do a timeline, and most of the things people remember happened the last week, it may not be because that&#8217;s the only time something significant happened.</li>
<li>You may consider different frequencies for different ceremonies. For example, on my current project we want to have demos with our power users. But they have to travel far to visit us. So we only have a full demo every other four weeks. We plan every two weeks and have an internal review and retrospective every two weeks.</li>
</ul>
<p>What&#8217;s the right iteration length for your project?</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2010/02/25/what-is-the-right-iteration-length/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Getting started with pair programming</title>
		<link>http://johannesbrodwall.com/2010/01/13/getting-started-with-pair-programming/</link>
		<comments>http://johannesbrodwall.com/2010/01/13/getting-started-with-pair-programming/#comments</comments>
		<pubDate>Thu, 14 Jan 2010 00:02:36 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Extreme Programming]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://johannesbrodwall.com/?p=505</guid>
		<description><![CDATA[As it turns out, one of the least used practices of agile development is also one of the most powerful.

Up into the start of last year, I only worked sporadically with pair programming. Last year, I was lucky enough to be part of a team that used pair programming all the time. Since I've experienced real pair programming, I never want to give it up.

Pair programming offers benefits to many stakeholders:

<ul>
  <li>As a developer, you will have more fun at work. You will get to know your colleagues better and experience flow practically the whole day. You will be tired by the end of the day, but you will also feel like you've accomplished good work.</li>
  <li>The team will have a higher quality code base that everyone is comfortable with.</li>
  <li>As an architect or team lead, you will have a good way to contribute even if you only have a little time before a meeting. You will also have a better chance to influence the rest of the team, instead of just issuing edicts that nobody follows.</li>
  <li>As the project manager, you will have a more flexible team. If someone gets sick, goes on vacation or moves to another project, there won't be a big problem.</li>
  <li>As the customer, you will get better quality code faster.</li>
</ul>

With these benefits in mind, why doesn't everybody pair program? Well, it is unfamiliar, a little scary, and exhausting when you start out. Most developers are not used to having other watch them code. Or to focus on the task at hand the whole day.

Here are some techniques I've seen have effect for teams transitioning to pair programming:

<ul>
  <li>Code dojos: Everyone on the team gets together and programs a sample program or a spike together. Two people sit at the keyboard, while the rest watch on a projector. Rotate pairs frequently. This lets everyone get comfortable with coding as a social activity.</li>
  <li>Pair programming should be the norm, but allow for exceptions. If people only pair program occasionally, they end up not pair programming at all. If people are forced to pair program when they just need some time by themselves to think, they will not be happy pair programming.</li>
  <li>The pair programming star: Write the names of the team members in a circle. Every time two people pair program, draw a line between their names. Keep the pair programming star in a visible location.</li>
  <li>Facilities: The furniture can make it harder to get started pair programming. Consider using two mice, two keyboards and perhaps two monitors per PC to make it easier. Or use VNC for desktop sharing.</li>
  <li>Give it time: Pair programming is exhausting when you first start doing it. It will take a while before people are comfortable with the new pace. But once they switch, they will never want to go back.</li>
</ul>

<h3>Resources</h3>

For more inspiration, see these presentations from the <a href="http://smidig2009.no">Smidig 2009</a> conference (in Norwegian):

<ul>
  <li><a href="http://tcs.java.no/tcs/?id=379B438E-11FA-418E-8A04-D02AF83B1698">Jøran Lillesand: Derre e itj smidi!</a>: On why pair programming is the very foundation of successful agile projects</li>
  <li><a href="http://tcs.java.no/tcs/?id=3D998ED6-1BF4-46D7-BF40-25CC06BD1AA1">Ørjan Lillevik og Kari Røssland: Parprogrammering gir driv</a>: On what it feels like to be on a team that adopts pair programming. From reluctance to joy.</li>
</ul>
]]></description>
			<content:encoded><![CDATA[<p>As it turns out, one of the least used practices of agile development is also one of the most powerful.</p>
<p>Up into the start of last year, I only worked sporadically with pair programming. Last year, I was lucky enough to be part of a team that used pair programming all the time. Since I&#8217;ve experienced real pair programming, I never want to give it up.</p>
<p>Pair programming offers benefits to many stakeholders:</p>
<ul>
<li>As a developer, you will have more fun at work. You will get to know your colleagues better and experience flow practically the whole day. You will be tired by the end of the day, but you will also feel like you&#8217;ve accomplished good work.</li>
<li>The team will have a higher quality code base that everyone is comfortable with.</li>
<li>As an architect or team lead, you will have a good way to contribute even if you only have a little time before a meeting. You will also have a better chance to influence the rest of the team, instead of just issuing edicts that nobody follows.</li>
<li>As the project manager, you will have a more flexible team. If someone gets sick, goes on vacation or moves to another project, there won&#8217;t be a big problem.</li>
<li>As the customer, you will get better quality code faster.</li>
</ul>
<p>With these benefits in mind, why doesn&#8217;t everybody pair program? Well, it is unfamiliar, a little scary, and exhausting when you start out. Most developers are not used to having other watch them code. Or to focus on the task at hand the whole day.</p>
<p>Here are some techniques I&#8217;ve seen have effect for teams transitioning to pair programming:</p>
<ul>
<li>Code dojos: Everyone on the team gets together and programs a sample program or a spike together. Two people sit at the keyboard, while the rest watch on a projector. Rotate pairs frequently. This lets everyone get comfortable with coding as a social activity.</li>
<li>Pair programming should be the norm, but allow for exceptions. If people only pair program occasionally, they end up not pair programming at all. If people are forced to pair program when they just need some time by themselves to think, they will not be happy pair programming.</li>
<li>The pair programming star: Write the names of the team members in a circle. Every time two people pair program, draw a line between their names. Keep the pair programming star in a visible location.</li>
<li>Facilities: The furniture can make it harder to get started pair programming. Consider using two mice, two keyboards and perhaps two monitors per PC to make it easier. Or use VNC for desktop sharing.</li>
<li>Give it time: Pair programming is exhausting when you first start doing it. It will take a while before people are comfortable with the new pace. But once they switch, they will never want to go back.</li>
</ul>
<h3>Resources</h3>
<p>For more inspiration, see these presentations from the <a href="http://smidig2009.no">Smidig 2009</a> conference (in Norwegian):</p>
<ul>
<li><a href="http://tcs.java.no/tcs/?id=379B438E-11FA-418E-8A04-D02AF83B1698">Jøran Lillesand: Derre e itj smidi!</a>: On why pair programming is the very foundation of successful agile projects</li>
<li><a href="http://tcs.java.no/tcs/?id=3D998ED6-1BF4-46D7-BF40-25CC06BD1AA1">Ørjan Lillevik og Kari Røssland: Parprogrammering gir driv</a>: On what it feels like to be on a team that adopts pair programming. From reluctance to joy.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2010/01/13/getting-started-with-pair-programming/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>My first katacast</title>
		<link>http://johannesbrodwall.com/2009/12/31/my-first-katacast/</link>
		<comments>http://johannesbrodwall.com/2009/12/31/my-first-katacast/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 10:29:13 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Extreme Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://johannesbrodwall.com/?p=500</guid>
		<description><![CDATA[After seeing some of the great examples of coders working on practiced problems on <a href="http://www.katacasts.com/">KataCasts</a>, I decided to try make my own. I am not happy with the pacing of the video. I'm about a minute too early relative to the music.

But I thought I'd post the video here, to see what you all think. Comments are welcome!

I hope the video will demonstrate how to use refactoring effectively to drive the design of a program.

I chose the FizzBuzz kata - that is, to generate a sequence of numbers where every number divisible by three is replaced by "fizz" and every number divisible by five is replaced by "five". The music changes to be more aggressive just as I induce a new requirement into the kata: The FizzBuzz generator should be programmable, so, in the kata, numbers divisible by two are replaced by "coconut" and numbers divisible by seven are replaced by "banana".

Thanks to Emily Bache for the inspiration for the kata.

Enjoy!

<object width="400" height="300"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8459948&#38;server=vimeo.com&#38;show_title=1&#38;show_byline=1&#38;show_portrait=0&#38;color=&#38;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8459948&#38;server=vimeo.com&#38;show_title=1&#38;show_byline=1&#38;show_portrait=0&#38;color=&#38;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object><p><a href="http://vimeo.com/8459948">Fizz buzz code kata</a> from <a href="http://vimeo.com/user2873956">Johannes Brodwall</a> on <a href="http://vimeo.com">Vimeo</a>.</p>

The video was made with <a href="http://www.jetbrains.com/idea/free_java_ide.html">IntelliJ IDEA Community Edition</a> on Windows Vista (!) with <a href="http://www.bbsoftware.co.uk/BBFlashBack_FreePlayer.aspx?cc=true">BB FlashBack Express</a> (free screen recorder), converted to AVI with Windows Media 1 codec and uploaded to Vimeo.]]></description>
			<content:encoded><![CDATA[<p>After seeing some of the great examples of coders working on practiced problems on <a href="http://www.katacasts.com/">KataCasts</a>, I decided to try make my own. I am not happy with the pacing of the video. I&#8217;m about a minute too early relative to the music.</p>
<p>But I thought I&#8217;d post the video here, to see what you all think. Comments are welcome!</p>
<p>I hope the video will demonstrate how to use refactoring effectively to drive the design of a program.</p>
<p>I chose the FizzBuzz kata &#8211; that is, to generate a sequence of numbers where every number divisible by three is replaced by &#8220;fizz&#8221; and every number divisible by five is replaced by &#8220;five&#8221;. The music changes to be more aggressive just as I induce a new requirement into the kata: The FizzBuzz generator should be programmable, so, in the kata, numbers divisible by two are replaced by &#8220;coconut&#8221; and numbers divisible by seven are replaced by &#8220;banana&#8221;.</p>
<p>Thanks to Emily Bache for the inspiration for the kata.</p>
<p>Enjoy!</p>
<p><object width="400" height="300"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=8459948&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=8459948&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"></embed></object>
<p><a href="http://vimeo.com/8459948">Fizz buzz code kata</a> from <a href="http://vimeo.com/user2873956">Johannes Brodwall</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<p>The video was made with <a href="http://www.jetbrains.com/idea/free_java_ide.html">IntelliJ IDEA Community Edition</a> on Windows Vista (!) with <a href="http://www.bbsoftware.co.uk/BBFlashBack_FreePlayer.aspx?cc=true">BB FlashBack Express</a> (free screen recorder), converted to AVI with Windows Media 1 codec and uploaded to Vimeo.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2009/12/31/my-first-katacast/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Å trene på Java EE</title>
		<link>http://johannesbrodwall.com/2009/12/02/trene-pa-java-ee/</link>
		<comments>http://johannesbrodwall.com/2009/12/02/trene-pa-java-ee/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 19:25:52 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Extreme Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Norsk]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://johannesbrodwall.com/?p=489</guid>
		<description><![CDATA[For å bli bedre må man trene. For å bli bedre med avanserte ting, må man forstå de grunnleggende tingene bra. For å vite hvorfor man bruker avanserte verktøy, må man prøve å jobbe uten dem. Derfor har jeg de siste ukene trent mange ganger på å lage en veldig enkel webapplikasjon i Java. For hele applikasjonen har jeg startet med å skrive testene før koden som implementerer funksjonaliteten.

Dersom du vil prøve deg på samme øvelse, inneholder denne artikkelen litt informasjon for å komme i gang. Start med koden under og <em>følg feilmeldingene.</em> Send en kommentar dersom du ikke kommer videre fra en feilmelding, så får vi en FAQ.

<h3>Oppgaven</h3>

Løs et så enkelt som mulig problem som involverer websider og database med så enkel teknologi om mulig.

Oppgaven jeg har laget går ut på å <em>opprette personer med fullt navn og søke etter personer basert på navnet deres</em>. For å gjøre oppgaven så lite som mulig har jeg valgt å la personer kun ha ett informasjonsfelt: Fullt navn. Denne oppgaven tar cirka 2-3 timer uten øvelse og du kan få den ned i 60-90 minutter med trening.

Du kan naturligvis velge en annen oppgave, men uansett hva du velger: Det er mer lærerikt å gjenta den samme oppgaven flere ganger enn å utføre en avansert oppgave.

Når jeg utfører oppgaven er det viktigste jeg lærer meg å forstå feilmeldingene som guider meg gjennom utviklingen. Dersom du trenger hjelp til å komme til de første feilmeldingene kan du se resten av artikkelen.
]]></description>
			<content:encoded><![CDATA[<p>For å bli bedre må man trene. For å bli bedre med avanserte ting, må man forstå de grunnleggende tingene bra. For å vite hvorfor man bruker avanserte verktøy, må man prøve å jobbe uten dem. Derfor har jeg de siste ukene trent mange ganger på å lage en veldig enkel webapplikasjon i Java. For hele applikasjonen har jeg startet med å skrive testene før koden som implementerer funksjonaliteten.</p>
<p>Dersom du vil prøve deg på samme øvelse, inneholder denne artikkelen litt informasjon for å komme i gang. Start med koden under og <em>følg feilmeldingene.</em> Send en kommentar dersom du ikke kommer videre fra en feilmelding, så får vi en FAQ.</p>
<h3>Oppgaven</h3>
<p>Løs et så enkelt som mulig problem som involverer websider og database med så enkel teknologi om mulig.</p>
<p>Oppgaven jeg har laget går ut på å <em>opprette personer med fullt navn og søke etter personer basert på navnet deres</em>. For å gjøre oppgaven så lite som mulig har jeg valgt å la personer kun ha ett informasjonsfelt: Fullt navn. Denne oppgaven tar cirka 2-3 timer uten øvelse og du kan få den ned i 60-90 minutter med trening.</p>
<p>Du kan naturligvis velge en annen oppgave, men uansett hva du velger: Det er mer lærerikt å gjenta den samme oppgaven flere ganger enn å utføre en avansert oppgave.</p>
<p>Når jeg utfører oppgaven er det viktigste jeg lærer meg å forstå feilmeldingene som guider meg gjennom utviklingen. Dersom du trenger hjelp til å komme til de første feilmeldingene kan du se resten av artikkelen.</p>
<p><!-- more --></p>
<h3>Steg for steg: Startpunktet</h3>
<p>Selv om jeg valgte veldig enkel teknologi for implementasjonen, har jeg valgt et større sett med biblioteker for å skrive testene. Jeg bruker følgende når jeg skriver testene:</p>
<ul>
<li>JUnit 4.6</li>
<li>Jetty 6.1.22</li>
<li>HSqlDb 1.8.0.10</li>
<li>WebDriver-HtmlUnit 0.6.1039</li>
<li>Mockito 1.8.0</li>
<li>FEST-assert 1.2 (ikke påkrevd, men gjør testene søtere)</li>
</ul>
<p>Den eneste teknologien jeg har valgt for implementasjonen er Servlet-API 2.5 og Hibernate-Annotations 3.4.0.GA.</p>
<p>For at du skal slippe å plundre så mye med avhengigheter før du kommer i gang har jeg laget en <a href="http://svn.brodwall.com/demo/java-ee-spike-kata/pom.xml">pom.xml</a>-fil som du kan ta utgangspunkt i.</p>
<h3>Web-tester</h3>
<p>For å starte utviklingen, er det lurt med en test som starter på utsiden av applikasjonen. Noe slikt:</p>
<ol>
<li>Start opp miljøet</li>
<li>Legg inn en person</li>
<li>Søk etter personen</li>
</ol>
<p>Slik kommer du i gang med en test som går mot en web applikasjon:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">int</span> SERVER_PICKS_PORT <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
org.<span style="color: #006633;">mortbay</span>.<span style="color: #006633;">jetty</span>.<span style="color: #006633;">Server</span> server <span style="color: #339933;">=</span> 
       <span style="color: #000000; font-weight: bold;">new</span> org.<span style="color: #006633;">mortbay</span>.<span style="color: #006633;">jetty</span>.<span style="color: #006633;">Server</span><span style="color: #009900;">&#40;</span>SERVER_PICKS_PORT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
server.<span style="color: #006633;">addHandler</span><span style="color: #009900;">&#40;</span>
       <span style="color: #000000; font-weight: bold;">new</span> org.<span style="color: #006633;">mortbay</span>.<span style="color: #006633;">jetty</span>.<span style="color: #006633;">webapp</span>.<span style="color: #006633;">WebAppContext</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;src/main/webapp&quot;</span>, <span style="color: #0000ff;">&quot;/&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
server.<span style="color: #006633;">start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">int</span> serverPort <span style="color: #339933;">=</span> server.<span style="color: #006633;">getConnectors</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">getLocalPort</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
org.<span style="color: #006633;">openqa</span>.<span style="color: #006633;">selenium</span>.<span style="color: #006633;">WebDriver</span> browser <span style="color: #339933;">=</span>
       <span style="color: #000000; font-weight: bold;">new</span> org.<span style="color: #006633;">openqa</span>.<span style="color: #006633;">selenium</span>.<span style="color: #006633;">htmlunit</span>.<span style="color: #006633;">HtmlUnitDriver</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
browser.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://localhost:&quot;</span> <span style="color: #339933;">+</span> serverPort <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;/&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
browser.<span style="color: #006633;">findElement</span><span style="color: #009900;">&#40;</span>By.<span style="color: #006633;">linkText</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Create person&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Dette oppsettet forventer å finne <code>web.xml</code>-fila på <code>src/main/webapp/WEB-INF/web.xml</code>.</p>
<h3>Funksjonell test</h3>
<p>En funksjonell test definerer <em>kravene</em> i applikasjonen. Det er lurt å gjøre funksjonelle tester så raske som overhode mulig, samtidig som de går gjennom alle kravene. En funksjonell test trenger ikke være en ende-til-ende test, slik som eksempelet over. Dette er viktig, fordi ende-til-ende tester er ofte veldig trege. Her er noen eksempler på funksjonelle tester:</p>
<ul>
<li>Vis en siden for å opprette nye personer</li>
<li>Opprett en ny person</li>
<li>Verifiser at personens navn er oppgitt og ikke inneholder ulovlige tegn</li>
<li>Vis en side for å søke etter personer</li>
<li>Vis alle personer dersom søkestreng ikke er angitt</li>
<li>Søk etter angitt søkestreng</li>
</ul>
<p>En funksjonell test kan se slik ut:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">PersonServlet servlet <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PersonServlet<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
HttpServletRequest req <span style="color: #339933;">=</span>
    org.<span style="color: #006633;">mockito</span>.<span style="color: #006633;">Mockito</span>.<span style="color: #006633;">mock</span><span style="color: #009900;">&#40;</span>HttpServletRequest.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
HttpServletResponse resp <span style="color: #339933;">=</span>
    org.<span style="color: #006633;">mockito</span>.<span style="color: #006633;">Mockito</span>.<span style="color: #006633;">mock</span><span style="color: #009900;">&#40;</span>HttpServletResponse.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
PersonDao personDao <span style="color: #339933;">=</span>
    org.<span style="color: #006633;">mockito</span>.<span style="color: #006633;">Mockito</span>.<span style="color: #006633;">mock</span><span style="color: #009900;">&#40;</span>PersonDao.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
servlet.<span style="color: #006633;">setPersonDao</span><span style="color: #009900;">&#40;</span>personDao<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
org.<span style="color: #006633;">mockito</span>.<span style="color: #006633;">Mockito</span>.<span style="color: #006633;">when</span><span style="color: #009900;">&#40;</span>req.<span style="color: #006633;">getMethod</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #006633;">thenReturn</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;POST&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
org.<span style="color: #006633;">mockito</span>.<span style="color: #006633;">Mockito</span>.<span style="color: #006633;">when</span><span style="color: #009900;">&#40;</span>req.<span style="color: #006633;">getPathInfo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #006633;">thenReturn</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/create.html&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
org.<span style="color: #006633;">mockito</span>.<span style="color: #006633;">Mockito</span>.<span style="color: #006633;">when</span><span style="color: #009900;">&#40;</span>req.<span style="color: #006633;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;full_name&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #006633;">thenReturn</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Johannes Brodwall&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003399;">StringWriter</span> pageSource <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">StringWriter</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
org.<span style="color: #006633;">mockito</span>.<span style="color: #006633;">Mockito</span>.<span style="color: #006633;">when</span><span style="color: #009900;">&#40;</span>resp.<span style="color: #006633;">getWriter</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #006633;">thenReturn</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">PrintWriter</span><span style="color: #009900;">&#40;</span>pageSource<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
servlet.<span style="color: #006633;">service</span><span style="color: #009900;">&#40;</span>req, resp<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
org.<span style="color: #006633;">mockito</span>.<span style="color: #006633;">Mockito</span>.<span style="color: #006633;">verify</span><span style="color: #009900;">&#40;</span>personDao<span style="color: #009900;">&#41;</span>
    .<span style="color: #006633;">create</span><span style="color: #009900;">&#40;</span>Person.<span style="color: #006633;">byName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Johannes Brodwall&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
org.<span style="color: #006633;">fest</span>.<span style="color: #006633;">assertions</span>.<span style="color: #006633;">Assertions</span>.<span style="color: #006633;">assertThat</span><span style="color: #009900;">&#40;</span>pageSource.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Personen er opprettet&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h3>Data-aksess-test</h3>
<p>Hibernate forenkler databasebruken mye. Men Hibernate er selv komplekst og når man bruker det på mer avanserte måter fortjener det egne tester. En typisk test med Hibernate kan være:</p>
<ol>
<li>Legg i tre personer i database</li>
<li>Søk etter en del av navnet på en av dem</li>
<li>Sjekk at du får tilbake akkurat den du forventet</li>
</ol>
<p>Når jeg starter med Hibernate, lager jeg en test som dette, og følger feilmeldingene. Pass på å både følge feilmeldinger i loggen og stack tracer.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">AnnotationConfiguration conf <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> AnnotationConfiguration<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #006633;">setProperty</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Environment</span>.<span style="color: #003399;">URL</span>, <span style="color: #0000ff;">&quot;jdbc:hsqldb:mem:persondaotest&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
PersonDao dao <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HibernatePersonDao<span style="color: #009900;">&#40;</span>conf.<span style="color: #006633;">buildSessionFactory</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
dao.<span style="color: #006633;">create</span><span style="color: #009900;">&#40;</span>Person.<span style="color: #006633;">withName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;foo&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
org.<span style="color: #006633;">fest</span>.<span style="color: #006633;">assertions</span>.<span style="color: #006633;">Assertions</span>.<span style="color: #006633;">assertThat</span><span style="color: #009900;">&#40;</span>dao.<span style="color: #006633;">find</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    .<span style="color: #006633;">containsExactly</span><span style="color: #009900;">&#40;</span>Person.<span style="color: #006633;">withName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;foo&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Følg feilmeldingene herfra.</p>
<h3>Integrasjon</h3>
<p>En veldig vanlig måte for web serveren å overlevere spesielt ting som DataSources til applikasjonen er via JNDI. I Jetty kan du gjøre dette i Web-testen på følgende måte:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">org.<span style="color: #006633;">hsqldb</span>.<span style="color: #006633;">jdbc</span>.<span style="color: #006633;">jdbcDataSource</span> ds <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> org.<span style="color: #006633;">hsqldb</span>.<span style="color: #006633;">jdbc</span>.<span style="color: #006633;">jdbcDataSource</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ds.<span style="color: #006633;">setDatabase</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;jdbc:hsqldb:mem:personwebtest&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ds.<span style="color: #006633;">setUser</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;sa&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">new</span> org.<span style="color: #006633;">mortbay</span>.<span style="color: #006633;">jetty</span>.<span style="color: #006633;">plus</span>.<span style="color: #006633;">naming</span>.<span style="color: #006633;">Resource</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;jdbc/primaryDs&quot;</span>, ds<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Oppstart av Jetty som vist over</span></pre></div></div>

<h3>Konklusjon</h3>
<p>Å gjøre en liten øvelse som dette er en god måte å bli bevisst hvilke vaner du har og hvor lang tid det egentlig tar for deg å gjøre oppgavene dine. Du vil oppleve at det å skrive tester før koden føles som om det går saktere enn du tror du er vant til.</p>
<p>Men dersom du er som meg, vil du også oppleve noe annet: Når du tester ut applikasjonen første gang (du kan gjøre dette med Jetty, naturligvis) så er sjansene gode for at den vil være nokså feilfri og at debugging i stor grad er overflødig. Jeg vet ikke med deg, men debugging er en aktivitet jeg gjerne blir kvitt.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2009/12/02/trene-pa-java-ee/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Why don&#8217;t we call our customers &#8220;clients&#8221;?</title>
		<link>http://johannesbrodwall.com/2009/11/15/why-dont-we-call-our-customers-clients/</link>
		<comments>http://johannesbrodwall.com/2009/11/15/why-dont-we-call-our-customers-clients/#comments</comments>
		<pubDate>Sun, 15 Nov 2009 16:07:01 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Extreme Programming]]></category>
		<category><![CDATA[Non-technical]]></category>

		<guid isPermaLink="false">http://johannesbrodwall.com/?p=483</guid>
		<description><![CDATA[Lately I've been thinking a lot about how easy it is to lose sight of the goal of the project and instead focus on whatever means someone first thought was a good starting point when the project was first conceived of. And I think it all comes down to words.

The first years I was working in this business, I didn't see any distinction between "the user" and "the customer". Once I started seeing the distinction, I started to understand that the person who is going to use the system we're developing is not the person who defines what the system should do and neither of these is usually the person that pays me to develop the system. So I starting distinguishing between the product owner, that is, the customer and the end user. But the product owner often calls the person I call "end user" his "customer". What's going on here? Let's check the dictionary:

<blockquote>CUSTOMER
Main Entry:  cus·tom·er
Pronunciation:  \ˈkəs-tə-mər\
Function:  noun
<b>1: one that purchases a commodity or service</b>
2: an individual usually having some specified distinctive trait

CLIENT
Main Entry:  cli·ent
Pronunciation:  \ˈklī-ənt\
Function:  noun
1: one that is under the protection of another : dependent
2a: a person who engages the professional advice or services of another
2b: customer
2c: a person served by or utilizing the services of a social agency
2d: a computer in a network that uses the services (as access to files or shared peripherals) provided by a server
</blockquote>

I've seen suppliers approach their work by asking for a specification of a product to deliver and then trying to deliver something to that specification for payment. The mental model is that of a customer going to the grocery story asking for "eight pounds of CRM software". My experience with organizations with this sort of mindset has always been unsatisfactory.

On the other hand, I've seen suppliers approach their work as an agent of the organization that pays them. "Our job is to enable someone else do their job better." This totally changes the way an organization deals with this relationship. The word "customer" may not be conductive to this sort of thinking. Instead, we should think of ourselves as agents acting on behalf of a <em>client</em>. As an agent, your responsibility is to enable your client. This includes helping your client to find better means of reaching their goal.

By the way, wikipedia defines the word "agent" as "a person who is authorized to act on behalf of another (called the Principal or client) to create a legal relationship with a Third Party". If the "third party" is the computer, then a good developer is an agent acting on their clients behalf in dealings with the computer software.

Why doesn't the software industry use the word "client" instead of "customer"?]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve been thinking a lot about how easy it is to lose sight of the goal of the project and instead focus on whatever means someone first thought was a good starting point when the project was first conceived of. And I think it all comes down to words.</p>
<p>The first years I was working in this business, I didn&#8217;t see any distinction between &#8220;the user&#8221; and &#8220;the customer&#8221;. Once I started seeing the distinction, I started to understand that the person who is going to use the system we&#8217;re developing is not the person who defines what the system should do and neither of these is usually the person that pays me to develop the system. So I starting distinguishing between the product owner, that is, the customer and the end user. But the product owner often calls the person I call &#8220;end user&#8221; his &#8220;customer&#8221;. What&#8217;s going on here? Let&#8217;s check the dictionary:</p>
<blockquote><p>CUSTOMER<br />
Main Entry:  cus·tom·er<br />
Pronunciation:  \ˈkəs-tə-mər\<br />
Function:  noun<br />
<b>1: one that purchases a commodity or service</b><br />
2: an individual usually having some specified distinctive trait</p>
<p>CLIENT<br />
Main Entry:  cli·ent<br />
Pronunciation:  \ˈklī-ənt\<br />
Function:  noun<br />
1: one that is under the protection of another : dependent<br />
2a: a person who engages the professional advice or services of another<br />
2b: customer<br />
2c: a person served by or utilizing the services of a social agency<br />
2d: a computer in a network that uses the services (as access to files or shared peripherals) provided by a server
</p></blockquote>
<p>I&#8217;ve seen suppliers approach their work by asking for a specification of a product to deliver and then trying to deliver something to that specification for payment. The mental model is that of a customer going to the grocery story asking for &#8220;eight pounds of CRM software&#8221;. My experience with organizations with this sort of mindset has always been unsatisfactory.</p>
<p>On the other hand, I&#8217;ve seen suppliers approach their work as an agent of the organization that pays them. &#8220;Our job is to enable someone else do their job better.&#8221; This totally changes the way an organization deals with this relationship. The word &#8220;customer&#8221; may not be conductive to this sort of thinking. Instead, we should think of ourselves as agents acting on behalf of a <em>client</em>. As an agent, your responsibility is to enable your client. This includes helping your client to find better means of reaching their goal.</p>
<p>By the way, wikipedia defines the word &#8220;agent&#8221; as &#8220;a person who is authorized to act on behalf of another (called the Principal or client) to create a legal relationship with a Third Party&#8221;. If the &#8220;third party&#8221; is the computer, then a good developer is an agent acting on their clients behalf in dealings with the computer software.</p>
<p>Why doesn&#8217;t the software industry use the word &#8220;client&#8221; instead of &#8220;customer&#8221;?</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2009/11/15/why-dont-we-call-our-customers-clients/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>The Malmö Experiment: Estimation Techniques Shootout</title>
		<link>http://johannesbrodwall.com/2009/11/05/the-malmo-experiment-estimation-techniques-shootout/</link>
		<comments>http://johannesbrodwall.com/2009/11/05/the-malmo-experiment-estimation-techniques-shootout/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 02:48:17 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Extreme Programming]]></category>

		<guid isPermaLink="false">http://johannesbrodwall.com/?p=480</guid>
		<description><![CDATA[At ØreDev I ran into Lasse Koskela. We started talking about estimation techniques, and we both felt that the dominant estimation technique of relative estimation with planning poker has been unchallenged for a very long time. We found ourselves wondering what the next big idea about estimation will be. After throwing a couple of ideas back and forth, we decided to invite to a workshop comparing a few estimation techniques. We decided to call the workshop "The Malmö Experiment."

The results of the experiment were interesting, but far from conclusive.

During the experiment, we gave the same set of requirements to three teams, each consisting of three estimators. Each team was told to use a different technique. We decided on the following techniques:

<ul>
  <li>Planning poker: The purpose is to give all requirements a relative number (the meaning of these numbers will later be measured based on the output of the iterations). Each estimator has a deck of cards and choose a card with the number he feels is appropriate for the current requirement. Everyone reveals the numbers at the same time to avoid anchoring. The team discusses and reestimates a requirement until their estimates converge.</li>
  <li>Table spread estimation: This is one of the new techniques we proposed. Each requirement is written on a card. The estimators spread the cards along a large table according to the relative effort required per requirement. Numbers can be imposed later if desired.</li>
  <li>Goldilocks estimation: The purpose is to restructure requirements until they all have roughly equal size. Instead of assigning a number to a requirement, the estimators pick one of three options: Too big (split up and estimate the parts again), Too small (merge with other requirements), or Just right. When all requirements have been split or merged into "Just Right" size, the estimation is complete.</li>
</ul>

All teams found their estimation techniques to be motivating, but the Table Spread and Goldilocks groups managed to complete the estimation much faster. The Table Spread estimation would obviously need more space if we had a lot of requirements, while the Goldilocks estimation would generate a large number of requirements.

Based on these experiences, we propose the following experiment in a project:
<ul>
  <li>Use Table Spread Estimation for Release planning. This will encourage the team to keep the number of requirements low instead of trying to plan too detailed too far ahead. Since the table spread is quick it can be redone every iteration.</li>
  <li>Use Goldilocks Estimation for the next few upcoming iterations to split up the requirements into equal sized items. This will generate a better set of work items. The shorter planning window will ensure that we won't have an unmanageable number of requirements.</li>
</ul>

These are currently very rough ideas and we have no idea of whether it will work as we expect. Let me know if you have any relevant experience or if you want more information.]]></description>
			<content:encoded><![CDATA[<p>At ØreDev I ran into Lasse Koskela. We started talking about estimation techniques, and we both felt that the dominant estimation technique of relative estimation with planning poker has been unchallenged for a very long time. We found ourselves wondering what the next big idea about estimation will be. After throwing a couple of ideas back and forth, we decided to invite to a workshop comparing a few estimation techniques. We decided to call the workshop &#8220;The Malmö Experiment.&#8221;</p>
<p>The results of the experiment were interesting, but far from conclusive.</p>
<p>During the experiment, we gave the same set of requirements to three teams, each consisting of three estimators. Each team was told to use a different technique. We decided on the following techniques:</p>
<ul>
<li>Planning poker: The purpose is to give all requirements a relative number (the meaning of these numbers will later be measured based on the output of the iterations). Each estimator has a deck of cards and choose a card with the number he feels is appropriate for the current requirement. Everyone reveals the numbers at the same time to avoid anchoring. The team discusses and reestimates a requirement until their estimates converge.</li>
<li>Table spread estimation: This is one of the new techniques we proposed. Each requirement is written on a card. The estimators spread the cards along a large table according to the relative effort required per requirement. Numbers can be imposed later if desired.</li>
<li>Goldilocks estimation: The purpose is to restructure requirements until they all have roughly equal size. Instead of assigning a number to a requirement, the estimators pick one of three options: Too big (split up and estimate the parts again), Too small (merge with other requirements), or Just right. When all requirements have been split or merged into &#8220;Just Right&#8221; size, the estimation is complete.</li>
</ul>
<p>All teams found their estimation techniques to be motivating, but the Table Spread and Goldilocks groups managed to complete the estimation much faster. The Table Spread estimation would obviously need more space if we had a lot of requirements, while the Goldilocks estimation would generate a large number of requirements.</p>
<p>Based on these experiences, we propose the following experiment in a project:</p>
<ul>
<li>Use Table Spread Estimation for Release planning. This will encourage the team to keep the number of requirements low instead of trying to plan too detailed too far ahead. Since the table spread is quick it can be redone every iteration.</li>
<li>Use Goldilocks Estimation for the next few upcoming iterations to split up the requirements into equal sized items. This will generate a better set of work items. The shorter planning window will ensure that we won&#8217;t have an unmanageable number of requirements.</li>
</ul>
<p>These are currently very rough ideas and we have no idea of whether it will work as we expect. Let me know if you have any relevant experience or if you want more information.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2009/11/05/the-malmo-experiment-estimation-techniques-shootout/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Staggering toward the project goal</title>
		<link>http://johannesbrodwall.com/2009/10/14/staggering-toward-the-project-goa/</link>
		<comments>http://johannesbrodwall.com/2009/10/14/staggering-toward-the-project-goa/#comments</comments>
		<pubDate>Wed, 14 Oct 2009 20:38:39 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Agile Release Patterns]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[Extreme Programming]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://johannesbrodwall.com/?p=458</guid>
		<description><![CDATA[<em>I'm working on a <a href="http://wiki.cantara.no/display/ARS/Agile+Release+Strategies+Home">collection of patterns for early releases</a> with Niklas Bjørnerstedt. Here are some of my thoughts based on this work.</em>

In a few different projects, I've noticed that the idea of "where are we going" seems to go though a familiar pattern:

<ol>
  <li>"The old system is the requirement document, just make the new one do the same things". After a while, someone will realize that it's rather pointless to replace a system with a new one that does the same thing, which leads to...</li>
  <li>"Analyze the business processes and make the new system automate all decisions that a human used to make." After a while, people start realizing that business rules are interpreted slightly different by different users and finding a consensus approach is hard. Besides, some of the decisions require human judgment. On top of this, progress towards implementing the business processes is much slower than expected. As a matter of fact, people are panicking as the project gets increasingly delayed, which leads to...</li>
  <li>"Just do whatever the old system did, with whatever improvements are dead easy. Just get this damned thing out the door." Even reducing the scope to just the "bare bones of the current system with minimal improvements" doesn't seem to give sufficient progress. Or sufficient value to justify the project. So, finally, we arrive at...</li>
  <li>"Can we just add a new piece of software that makes an existing business process easier. And repeat until the budget is spent."</li>
</ol>

The sad conclusion is that the original goal of replacing the old system begins to appear further into the future. At the same time, the new system will realize some value to some stakeholder pretty soon thereafter. Maybe the first step towards a successful replacement project is giving up replacing the old system?

The good news is that with an iterative approach to the requirement process, my current project was able to go through all these steps in a couple of months. Which beats my previous record of a year of full burn rate in stage 1.]]></description>
			<content:encoded><![CDATA[<p><em>I&#8217;m working on a <a href="http://wiki.cantara.no/display/ARS/Agile+Release+Strategies+Home">collection of patterns for early releases</a> with Niklas Bjørnerstedt. Here are some of my thoughts based on this work.</em></p>
<p>In a few different projects, I&#8217;ve noticed that the idea of &#8220;where are we going&#8221; seems to go though a familiar pattern:</p>
<ol>
<li>&#8220;The old system is the requirement document, just make the new one do the same things&#8221;. After a while, someone will realize that it&#8217;s rather pointless to replace a system with a new one that does the same thing, which leads to&#8230;</li>
<li>&#8220;Analyze the business processes and make the new system automate all decisions that a human used to make.&#8221; After a while, people start realizing that business rules are interpreted slightly different by different users and finding a consensus approach is hard. Besides, some of the decisions require human judgment. On top of this, progress towards implementing the business processes is much slower than expected. As a matter of fact, people are panicking as the project gets increasingly delayed, which leads to&#8230;</li>
<li>&#8220;Just do whatever the old system did, with whatever improvements are dead easy. Just get this damned thing out the door.&#8221; Even reducing the scope to just the &#8220;bare bones of the current system with minimal improvements&#8221; doesn&#8217;t seem to give sufficient progress. Or sufficient value to justify the project. So, finally, we arrive at&#8230;</li>
<li>&#8220;Can we just add a new piece of software that makes an existing business process easier. And repeat until the budget is spent.&#8221;</li>
</ol>
<p>The sad conclusion is that the original goal of replacing the old system begins to appear further into the future. At the same time, the new system will realize some value to some stakeholder pretty soon thereafter. Maybe the first step towards a successful replacement project is giving up replacing the old system?</p>
<p>The good news is that with an iterative approach to the requirement process, my current project was able to go through all these steps in a couple of months. Which beats my previous record of a year of full burn rate in stage 1.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2009/10/14/staggering-toward-the-project-goa/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Lær Scrum på 3 minutter</title>
		<link>http://johannesbrodwall.com/2009/09/07/l%c3%a6r-scrum-pa-3-minutter/</link>
		<comments>http://johannesbrodwall.com/2009/09/07/l%c3%a6r-scrum-pa-3-minutter/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 20:31:05 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Extreme Programming]]></category>
		<category><![CDATA[Non-technical]]></category>
		<category><![CDATA[Norsk]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://johannesbrodwall.com/?p=453</guid>
		<description><![CDATA[<blockquote><em>This Norwegian language article introduces a short two-page guide I've written to explain Scrum to people who've only just heard of it.</em></blockquote>

I samarbeid med våre dyktige redaksjonelle medarbeidere på Steria, har jeg forfattet en "3 minutters guide" til Scrum. Denne tar for seg spørsmålene som "hva er egentlig Scrum".

[caption id="" align="alignnone" width="360" caption="Dette er Scrum"]<a href="http://steria.no/gloria/id/11004571/subid/0"><img alt="Hva er egentlig Scrum" src="http://steria.no/image/4954/1/4954_1.jpg" title="Hva er egentlig Scrum" width="360" height="152" /></a>[/caption]
  
3-minutterguidene kan lastes ned fra <a href="http://steria.no/gloria/id/11004571/subid/0">Sterias hjemmesider</a>.
  
Jeg planlegger å følge opp denne guiden med en guide som beskriver hva som skal til for å faktisk lykkes med Scrum. Har du noen ideer?]]></description>
			<content:encoded><![CDATA[<blockquote><p><em>This Norwegian language article introduces a short two-page guide I&#8217;ve written to explain Scrum to people who&#8217;ve only just heard of it.</em></p></blockquote>
<p>I samarbeid med våre dyktige redaksjonelle medarbeidere på Steria, har jeg forfattet en &#8220;3 minutters guide&#8221; til Scrum. Denne tar for seg spørsmålene som &#8220;hva er egentlig Scrum&#8221;.</p>
<div class="wp-caption alignnone" style="width: 370px"><a href="http://steria.no/gloria/id/11004571/subid/0"><img alt="Hva er egentlig Scrum" src="http://steria.no/image/4954/1/4954_1.jpg" title="Hva er egentlig Scrum" width="360" height="152" /></a><p class="wp-caption-text">Dette er Scrum</p></div>
<p>3-minutterguidene kan lastes ned fra <a href="http://steria.no/gloria/id/11004571/subid/0">Sterias hjemmesider</a>.</p>
<p>Jeg planlegger å følge opp denne guiden med en guide som beskriver hva som skal til for å faktisk lykkes med Scrum. Har du noen ideer?</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2009/09/07/l%c3%a6r-scrum-pa-3-minutter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
