<?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; Top 5</title>
	<atom:link href="http://johannesbrodwall.com/category/top-5/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, 19 Mar 2012 12:44:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>		<item>
		<title>Five unit testing tips #4: Don&#8217;t mock your way into accidental complexity</title>
		<link>http://johannesbrodwall.com/2009/02/24/five-unit-testing-tips-4-dont-mock-your-way-into-accidental-complexity/</link>
		<comments>http://johannesbrodwall.com/2009/02/24/five-unit-testing-tips-4-dont-mock-your-way-into-accidental-complexity/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 07:40:35 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Top 5]]></category>

		<guid isPermaLink="false">http://brodwall.com/johannes/blog/?p=324</guid>
		<description><![CDATA[I&#8217;ve all but stopped using mock objects in my tests. The reason is that mocking have had a detrimental effect on the design of my systems. I&#8217;ve often ended up having the mocks trick me into adding a needless layer of indirection that does nothing except delegate to the next layer, just to satisfy the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve all but stopped using mock objects in my tests. The reason is that mocking have had a detrimental effect on the design of my systems. I&#8217;ve often ended up having the mocks trick me into adding a needless layer of indirection that does nothing except delegate to the next layer, just to satisfy the mocks.</p>
<p>For a while, I was wondering whether I was the only one with this problem, but then I saw this tutorial on JBehave, which so perfectly illustrates the problem I saw myself doing. Now, I don&#8217;t mean to pick on JBehave, or the author of this tutorial. Furthermore, this is not a particularly extreme example of the problem. Rather, the point of this posting is to show that even expert developers run into this trap.</p>
<p>Here is the test from the JBehave tutorial:</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> shouldProvideNotesToBePlayedInOrder<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    TabParser parser <span style="color: #339933;">=</span> mock<span style="color: #009900;">&#40;</span>TabParser.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">String</span> asciiTab <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;e|--------A3-B6-&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    List<span style="color: #339933;">&lt;</span>Note<span style="color: #339933;">&gt;</span> notes <span style="color: #339933;">=</span> asList<span style="color: #009900;">&#40;</span>A<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span>, B<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">6</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    stub<span style="color: #009900;">&#40;</span>parser.<span style="color: #006633;">parse</span><span style="color: #009900;">&#40;</span>asciiTab<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toReturn</span><span style="color: #009900;">&#40;</span>notes<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    Tab tab <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Tab<span style="color: #009900;">&#40;</span>asciiTab, parser<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    List<span style="color: #339933;">&lt;</span>Note<span style="color: #339933;">&gt;</span> actualNotes <span style="color: #339933;">=</span> tab.<span style="color: #006633;">notesToBePlayed</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    ensureThat<span style="color: #009900;">&#40;</span>notes, equalTo<span style="color: #009900;">&#40;</span>actualNotes<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>In other words, the tab&#8217;s notes to be played should be equal to the parsed notes.</p>
<p>Here&#8217;s the implementation:</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: #000000; font-weight: bold;">class</span> Tab <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">final</span> List<span style="color: #339933;">&lt;</span>Note<span style="color: #339933;">&gt;</span> notes<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> Tab<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> asciiTab,
               TabParser parser<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        notes <span style="color: #339933;">=</span> parser.<span style="color: #006633;">parse</span><span style="color: #009900;">&#40;</span>asciiTab<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> List<span style="color: #339933;">&lt;</span>Note<span style="color: #339933;">&gt;</span> notesToBePlayed<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> notes<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Whoops! We just introduced a layer in the design that does nothing. As a matter of fact, removing the Tab class from the whole example leaves us with a design that&#8217;s easier to understand.</p>
<p>Mocks can be great when you really, really need them. And I&#8217;m extremely impressed by the power of <a href="http://code.google.com/p/mockito/">mockito</a>. But used inappropriately, mocking can trick you into creating accidental complexity and extra layers of code that does nothing.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2009/02/24/five-unit-testing-tips-4-dont-mock-your-way-into-accidental-complexity/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Five Unit Tests Tips #3: Parametrized test methods</title>
		<link>http://johannesbrodwall.com/2009/02/09/five-unit-tests-tips-3-parametrized-test-methods/</link>
		<comments>http://johannesbrodwall.com/2009/02/09/five-unit-tests-tips-3-parametrized-test-methods/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 20:56:39 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Top 5]]></category>

		<guid isPermaLink="false">http://brodwall.com/johannes/blog/?p=302</guid>
		<description><![CDATA[The following is a trick I don&#8217;t use very often, but when I do need it, it comes in very handy. It&#8217;s a trick that many developers aren&#8217;t aware of, even though it&#8217;s been possible to do with JUnit at least since version 3. Sometimes you want to have a lot of tests that are [...]]]></description>
			<content:encoded><![CDATA[<p>The following is a trick I don&#8217;t use very often, but when I do need it, it comes in very handy. It&#8217;s a trick that many developers aren&#8217;t aware of, even though it&#8217;s been possible to do with JUnit at least since version 3.</p>
<p>Sometimes you want to have a lot of tests that are almost the same, but that contain different arguments. For example, for a <a href="http://rubyquiz.com/quiz19.html">yahtzee calculator</a>, you might want to have the following tests:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">checkRollScoredAsCategoryGives<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">5</span>, <span style="color: #0000ff;">&quot;straight&quot;</span>, <span style="color: #cc66cc;">15</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
checkRollScoredAsCategoryGives<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #0000ff;">&quot;straight&quot;</span>, <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
checkRollScoredAsCategoryGives<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #0000ff;">&quot;full house&quot;</span>, <span style="color: #cc66cc;">17</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
checkRollScoredAsCategoryGives<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #0000ff;">&quot;full house&quot;</span>, <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
checkRollScoredAsCategoryGives<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #0000ff;">&quot;full house&quot;</span>, <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This is possible with JUnit, but a little trick. You have to construct a test suite manually and add special subclasses of TestCase to it:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">&nbsp;
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> Test suite<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    TestSuite suite <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> TestSuite<span style="color: #009900;">&#40;</span>
          YahtzeeScoreTest.<span style="color: #000000; font-weight: bold;">class</span>.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    suite.<span style="color: #006633;">addTest</span><span style="color: #009900;">&#40;</span>checkRollScoredAsCategoryGives<span style="color: #009900;">&#40;</span>
            <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">5</span>, <span style="color: #0000ff;">&quot;small straight&quot;</span>, <span style="color: #cc66cc;">15</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    suite.<span style="color: #006633;">addTest</span><span style="color: #009900;">&#40;</span>checkRollScoredAsCategoryGives<span style="color: #009900;">&#40;</span>
            <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #0000ff;">&quot;small straight&quot;</span>, <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    suite.<span style="color: #006633;">addTest</span><span style="color: #009900;">&#40;</span>checkRollScoredAsCategoryGives<span style="color: #009900;">&#40;</span>
            <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #0000ff;">&quot;full house&quot;</span>, <span style="color: #cc66cc;">17</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    suite.<span style="color: #006633;">addTest</span><span style="color: #009900;">&#40;</span>checkRollScoredAsCategoryGives<span style="color: #009900;">&#40;</span>
            <span style="color: #cc66cc;">1</span>, <span style="color: #cc66cc;">2</span>, <span style="color: #cc66cc;">3</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #0000ff;">&quot;full house&quot;</span>, <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    suite.<span style="color: #006633;">addTest</span><span style="color: #009900;">&#40;</span>checkRollScoredAsCategoryGives<span style="color: #009900;">&#40;</span>
            <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #cc66cc;">4</span>, <span style="color: #0000ff;">&quot;full house&quot;</span>, <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> suite<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> Test checkRollScoredAsCategoryGives<span style="color: #009900;">&#40;</span>
        <span style="color: #000066; font-weight: bold;">int</span> die1, <span style="color: #000066; font-weight: bold;">int</span> die2, <span style="color: #000066; font-weight: bold;">int</span> die3, <span style="color: #000066; font-weight: bold;">int</span> die4, <span style="color: #000066; font-weight: bold;">int</span> die5,
        <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> category, <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> expectedResult<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> dice <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span> die1, die2, die3, die4, die5 <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> TestCase<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Rolling for &quot;</span> <span style="color: #339933;">+</span> category<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        @Override
        <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> runTest<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;">Throwable</span> <span style="color: #009900;">&#123;</span>
            YahtzeeScoreboard board <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> YahtzeeScoreboard<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            board.<span style="color: #006633;">scoreRoll</span><span style="color: #009900;">&#40;</span>category, dice<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            assertEquals<span style="color: #009900;">&#40;</span>expectedResult, board.<span style="color: #006633;">getTotalScore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The code creates an anonymous inner subclass of TestCase that instead of calling all methods annotated with @Test just executes our specific test. These tests are collected in a normal JUnit TestSuite.</p>
<p>The test is plain JUnit and will run in Maven or your favorite IDE, just as any other tests. The fact that the suite is named after the test class will let Eclipse know where to go when you double click on the test from the test runner.</p>
<p>This trick can be very useful for tests of logic that calculates a results or validates input.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2009/02/09/five-unit-tests-tips-3-parametrized-test-methods/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Low hanging fruit for presenters</title>
		<link>http://johannesbrodwall.com/2009/02/08/low-hanging-fruit-for-presenters/</link>
		<comments>http://johannesbrodwall.com/2009/02/08/low-hanging-fruit-for-presenters/#comments</comments>
		<pubDate>Sun, 08 Feb 2009 19:38:38 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Top 5]]></category>

		<guid isPermaLink="false">http://brodwall.com/johannes/blog/2009/02/08/low-hanging-fruit-for-presenters/</guid>
		<description><![CDATA[If you ever talk to a group of people, you know that the art of presentation is one that requires a lifetime to master. But there are some dirt simple things you can do that will have a positive impact on your presentations. Here is my list of low hanging fruit for presenters: If you&#8217;re [...]]]></description>
			<content:encoded><![CDATA[<p>If you ever talk to a group of people, you know that the art of presentation is one that requires a lifetime to master. But there are some dirt simple things you can do that will have a positive impact on your presentations. Here is my list of low hanging fruit for presenters:</p>
<ul>
<li>If you&#8217;re using a computer, use a presentation remote. This is a cheap and easy way to make your presentation style look a little more professional.</li>
<li>If you&#8217;re using visuals, try and place yourself to the left of the visuals from the point of view of the audience. In the western culture, people scan scenes from left to right. By standing to the left, they will look at you first.</li>
<li>If your using visuals, place a laptop (or a monitor) between you and the audience with your slides on them. Turning to look at the slides over your shoulder seems uncertain, looking down at the monitor seems thoughtful.</li>
<li>Before you start speaking, take a few good breaths. Don&#8217;t rush. And whatever you say first, &#8220;ummm&#8230;&#8221; and &#8220;yes&#8230;.&#8221; should not be it.</li>
<li>When you&#8217;re done speaking say &#8220;thank you for your attention&#8221;. This will trigger the primate clapping response. An uncertain ending leaves the audience wondering when they should applaud.</li>
<li>Find the friendly faces. Every audience contains those few people that smile when you look at them. Use them whenever you&#8217;re uncertain an need a kick of positive energy.</li>
</ul>
<p>There are many hard and time consuming skills required to give good presentations. The list above is full of no brainers. These things you can do with no practice and no preparations.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2009/02/08/low-hanging-fruit-for-presenters/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>You might not be Agile if&#8230;</title>
		<link>http://johannesbrodwall.com/2008/12/25/you-might-not-be-agile-if/</link>
		<comments>http://johannesbrodwall.com/2008/12/25/you-might-not-be-agile-if/#comments</comments>
		<pubDate>Thu, 25 Dec 2008 21:20:09 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Extreme Programming]]></category>
		<category><![CDATA[Top 5]]></category>

		<guid isPermaLink="false">http://brodwall.com/johannes/blog/2008/12/25/you-might-not-be-agile-if/</guid>
		<description><![CDATA[Top five signs that you might not be working on an agile project: 5. Your iterations do not produce anything that could be put into production 4. You&#8217;re not testing your work 3. You tasks are called &#8220;code the UI for the foo&#8221;, &#8220;update the bar component&#8221; and &#8220;test the work done in the previous [...]]]></description>
			<content:encoded><![CDATA[<p>Top five signs that you might not be working on an agile project:</p>
<ul>
<li style="display: block">5. Your iterations do not produce anything that could be put into production</li>
<li style="display: block">4. You&#8217;re not testing your work</li>
<li style="display: block">3. You tasks are called &#8220;code the UI for the foo&#8221;, &#8220;update the bar component&#8221; and &#8220;test the work done in the previous iteration&#8221;</li>
<li style="display: block">2. Your iterations are called &#8220;specification&#8221;, &#8220;testing&#8221;, and &#8220;preproduction&#8221;</li>
<li style="display: block">1. And the top sign that you might not be working on an agile project: You might not be working on an agile project if your iterations are three months long</li>
</ul>
<p>Happy Holidays, Merry Christmas and Happy Monkey, everybody.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2008/12/25/you-might-not-be-agile-if/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Five Unit Test Tips: #2: Change your code to make testing easier</title>
		<link>http://johannesbrodwall.com/2008/10/01/five-unit-test-tips-2-change-your-code-to-make-testing-easier/</link>
		<comments>http://johannesbrodwall.com/2008/10/01/five-unit-test-tips-2-change-your-code-to-make-testing-easier/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 23:23:15 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Extreme Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Top 5]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/2008/10/01/five-unit-test-tips-2-change-your-code-to-make-testing-easier/</guid>
		<description><![CDATA[It&#8217;s been a while since I promised to write top five unit testing tips, so I guess I should better start writing #2. As with my first example this one is based on a real-life story. Your code is worth nothing if it can&#8217;t be tested. Change your code to make it more testable. In [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I promised to write top five unit testing tips, so I guess I should better start writing #2. As with my <a href="http://www.brodwall.com/johannes/blog/2008/09/08/five-unit-test-tips-1-use-the-data-store/">first example</a> this one is based on a real-life story.</p>
<p>Your code is worth nothing if it can&#8217;t be tested. Change your code to make it more testable.</p>
<p>In my last project, we used a pipes and filter architecture, with messages being passed forward through a chain of services. Most services refined the messages or broke them up in smaller services and passed them on to the next service. When they refined the message, they often stored new messages to the data layer as a side effect. To test the results, we read the generated objects back from the data layer. I had code like this:</p>
<h3>Before</h3>

<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> fileShouldCreateTransactionObject<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">Reader</span> simulatedFile <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">StringReader</span><span style="color: #009900;">&#40;</span>createFileContents<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    FileRequest file <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> FileRequest<span style="color: #009900;">&#40;</span>filename, simulatedFile<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    TransactionRepository repo <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> TestTransactionRepository<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    FileService fileService <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> FileService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    TransactionService transService <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> TransactionService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    fileService.<span style="color: #006633;">setNextStep</span><span style="color: #009900;">&#40;</span>transService<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    fileService.<span style="color: #006633;">setTransactionRepo</span><span style="color: #009900;">&#40;</span>repo<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    fileService.<span style="color: #006633;">process</span><span style="color: #009900;">&#40;</span>simulatedFile<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    Collection<span style="color: #339933;">&lt;</span>Transaction<span style="color: #339933;">&gt;</span> transactions <span style="color: #339933;">=</span> repo.<span style="color: #006633;">findAll</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, transactions.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    Transaction transaction <span style="color: #339933;">=</span> transactions.<span style="color: #006633;">iterator</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Bleh!</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Here is the real code I wanted</span>
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;foo&quot;</span>, transaction.<span style="color: #006633;">getTransactionType</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Whatever</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The solution was to change the design away from the pipes-and-filters design. Instead, the <code>process()</code> method returns the newly created <code>Transaction</code> object:</p>
<h3>After</h3>

<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> fileShouldCreateRequestObject<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">Reader</span> simulatedFile <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">StringReader</span><span style="color: #009900;">&#40;</span>createFileContents<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    FileRequest file <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> FileRequest<span style="color: #009900;">&#40;</span>filename, simulatedFile<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    FileService fileService <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> FileService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    Transaction transaction <span style="color: #339933;">=</span> fileService.<span style="color: #006633;">transform</span><span style="color: #009900;">&#40;</span>simulatedFile<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Here is the real code I wanted</span>
    assertEquals<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;foo&quot;</span>, transaction.<span style="color: #006633;">getTransactionType</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Whatever</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This new design totally violated our architecture, but it&#8217;s clearer, it keeps the infrastructure away from the code, and it&#8217;s much less brittle. Our test transaction repository used to be vulnerable to being polluted with test data from a previous run. As we no longer use this sort of infrastructure objects, we don&#8217;t have to worry about interaction between tests.</p>
<p>If you don&#8217;t know how to test your architecture, the problem is not with the testing, but with the architecture.</p>
<p>Until next time: Happy testing.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2008/10/01/five-unit-test-tips-2-change-your-code-to-make-testing-easier/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Five Unit Test Tips: #1: Use the data store</title>
		<link>http://johannesbrodwall.com/2008/09/08/five-unit-test-tips-1-use-the-data-store/</link>
		<comments>http://johannesbrodwall.com/2008/09/08/five-unit-test-tips-1-use-the-data-store/#comments</comments>
		<pubDate>Mon, 08 Sep 2008 19:43:19 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Extreme Programming]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Top 5]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/2008/09/08/five-unit-test-tips-1-use-the-data-store/</guid>
		<description><![CDATA[I&#8217;ve looked over some of my code lately, and found ways that I often improve my tests. I&#8217;m planning on writing a blog post for each of my five favorites. First out: Using the data storage. I upgraded our API for billing customers. I had a few compilation errors in my code, as the API [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve looked over some of my code lately, and found ways that I often improve my tests. I&#8217;m planning on writing a blog post for each of my five favorites.</p>
<p>First out: Using the data storage. I upgraded our API for billing customers. I had a few compilation errors in my code, as the API had changed somewhat. After fixing these errors, I was left with a test that broke mysteriously with a <code>MethodNotFoundException</code>. I located the test and found that it was close to unreadable. After examining it further, I found that it was trying to do was simple, but hidden in technical code.</p>
<p>I had the following test (the design is real, the details have been changed to protect the guilty):</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> shouldBillExtraForErrors<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   BillingService billingService <span style="color: #339933;">=</span> someService.<span style="color: #006633;">getBillingService</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   MethodCallLoggingInterceptor interceptor <span style="color: #339933;">=</span>
        MethodCallLoggingInterceptor.<span style="color: #000000; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span>billingService<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   someService.<span style="color: #006633;">setBillingService</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>BillingService<span style="color: #009900;">&#41;</span>interceptor<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #003399;">Request</span> requestWithError <span style="color: #339933;">=</span> createCustomerRequestWithError<span style="color: #009900;">&#40;</span>CUSTOMER_ID<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   someService.<span style="color: #006633;">process</span><span style="color: #009900;">&#40;</span>requestWithError<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #003399;">Method</span> method <span style="color: #339933;">=</span> BillingService.<span style="color: #000000; font-weight: bold;">class</span>.<span style="color: #006633;">getMethod</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;sendBillingEvent&quot;</span>, ....<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   MethodCall<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> callsToBilling <span style="color: #339933;">=</span> interceptor.<span style="color: #006633;">getMethodCallsFor</span><span style="color: #009900;">&#40;</span>method<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   assertEquals<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span>, callsToBilling<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   assertEquals<span style="color: #009900;">&#40;</span>CUSTOMER_ID, callsToBilling<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">getParams</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: #009900;">&#41;</span><span style="color: #339933;">;</span>
   assertEquals<span style="color: #009900;">&#40;</span>BillingCode.<span style="color: #006633;">RECEIVED_REQUEST</span>, callsToBilling<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">getParams</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   assertEquals<span style="color: #009900;">&#40;</span>CUSTOMER_ID, callsToBilling<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">getParams</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: #009900;">&#41;</span><span style="color: #339933;">;</span>
   assertEquals<span style="color: #009900;">&#40;</span>BillingCode.<span style="color: #006633;">INVALID_REQUEST</span>, callsToBilling<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">getParams</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>When the parameters to <code>sendBillingEvent</code> changed and the test started throwing <code>MethodNotFoundException</code> I changed it to the following:</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> shouldBillExtraForErrors<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #003399;">Request</span> requestWithError <span style="color: #339933;">=</span> createCustomerRequestWithError<span style="color: #009900;">&#40;</span>CUSTOMER_ID<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   someService.<span style="color: #006633;">process</span><span style="color: #009900;">&#40;</span>requestWithError<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   BillingFinder finder <span style="color: #339933;">=</span> BillingFinder.<span style="color: #006633;">forCustomer</span><span style="color: #009900;">&#40;</span>CUSTOMER_ID<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   finder.<span style="color: #006633;">setBillingCode</span><span style="color: #009900;">&#40;</span>BillingCode.<span style="color: #006633;">RECEIVED_REQUEST</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   assertEquals<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, billingRepository.<span style="color: #006633;">count</span><span style="color: #009900;">&#40;</span>finder<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   finder.<span style="color: #006633;">setBillingCode</span><span style="color: #009900;">&#40;</span>BillingCode. <span style="color: #006633;">INVALID_REQUEST</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   assertEquals<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, billingRepository.<span style="color: #006633;">count</span><span style="color: #009900;">&#40;</span>finder<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The lessons:</p>
<ul>
<li>Ask about the outcome, not about the method calls that get you there</li>
<li>Avoid reflection in tests. It&#8217;s bound to be brittle</li>
<li>Mocks and similar methods are overrated</li>
</ul>
<p>(In tip #2, I will show how I preserve the data store metaphor without giving up execution speed)</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2008/09/08/five-unit-test-tips-1-use-the-data-store/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Letters from Egypt: Top Five surprises</title>
		<link>http://johannesbrodwall.com/2006/11/02/letters-from-egypt-top-five-surprises/</link>
		<comments>http://johannesbrodwall.com/2006/11/02/letters-from-egypt-top-five-surprises/#comments</comments>
		<pubDate>Thu, 02 Nov 2006 07:06:21 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[Top 5]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/2006/11/02/letters-from-egypt-top-five-surprises/</guid>
		<description><![CDATA[Honking Cars in Egypt, especially Cairo honk all the time. Day and night. If we woke up at 4 am in the hotel room, there would be cars honking outside. The honk to wake up pedestrians or other cars, taxis honk to attract the attention of potential customers, and often, it seems like they honk [...]]]></description>
			<content:encoded><![CDATA[<h3>Honking</h3>
<p>Cars in Egypt, especially Cairo honk all the time. Day and night. If we woke up at 4 am in the hotel room, there would be cars honking outside. The honk to wake up pedestrians or other cars, taxis honk to attract the attention of potential customers, and often, it seems like they honk just for the fun of it.</p>
<h3>Security</h3>
<p>There&#8217;s a ton of policemen in Cairo, easily recognizable by their white uniforms. Most are in their early twenties. All have mustaches. Any ATM, bank or hotel will have stationed at least two policemen, usually with guns and a metal detector. Major tourist attractions will have much more (we saw a lot of policemen on the street, pluss five cars on standby by Midan Hussein). There will usually be assault shields (manned by black-uniformed police). Five-star hotels will have bomb dogs. Busy intersections have police officers directing the traffic.</p>
<p>And it does make you feel safer, I think. I was never afraid of being pickpocketed or mugged in Cairo. But I am not sure about the metal detectors. Nobody asks to to empty you pockets and try again when you beep. They just kinda glance up at you and resume their&#8230; watchfulness.</p>
<h3>Curbs</h3>
<p>The curbs to the sidewalks in Egypt are about 20 centimeters tall. I imagine this is the only reason taxi drivers don&#8217;t use sidewalks as shortcuts when the traffic is bad. The result if there are a lot of side streets is that pedestrians will constantly have to step on and off the sidewalk. Since people are lazy, most places, they walk in the street instead.</p>
<h3>Abandoned buildings</h3>
<p>All over Egypt, but especially on the Giza-side of the Nile, there are a huge number of what looks like buildings where they abandoned the construction before they were done. In many cases, this doesn&#8217;t stop people from living there. But the phenomenon is not limited to Giza. Alexandria, and even Dahab has a lot of these buildings. We tried asking a few locals what was up with these, but we didn&#8217;t manage to make anyone understand the question. I imagine this is the way it&#8217;s always been in Egypt.</p>
<h3>Pedestrians</h3>
<p>The thickness of pedestrians on streets like Sharia Talaat Harb, Corniche el-Nil (during Eid) og Sharia 26th of July was extreme. And pedestrians in Egypt are very aggressive. With the slow moving traffic of the inner city streets, they weave in and out between the honking cars without considering pedestrian crossings. Usually cars swerve organically around the flood of pedestrians if there is enough room.</p>
<p>There were also things I expected would be very different, but really didn&#8217;t live up to my fantasies:</p>
<h3>Prayers</h3>
<p>The minarets call out for prayer five times every day. You can hear the prayer calls anywhere in Cairo, and probably most other places in Egypt, too. However, I expected more people to stop up or more things to slow down during these times. In general, it seems like it&#8217;s just a backdrop for most egyptians most of the time.</p>
<h3>Women&#8217;s clothing</h3>
<p>Most women in Cairo, even in the central parts, seem to be wearing head scarfs. Beside this, however, most young women wear almost the same kind of clothes as in the west. We noticed a lot of tight-fitting clothing, for example. But most women cover up most of their skin.</p>
<p>Finally, there were a few minor surprises:</p>
<h3>Cats</h3>
<p>There are almost as many cats in Egypt as there are police officers. When we were sitting in the small outdoors lounge in our hotel, we saw five different cats within the same hour. In the breakfast balcony on our Dahab hotel, there were about ten. The cats don&#8217;t seem to belong to anyone, but people don&#8217;t mistreat them, either. They are usually tame, and will come up to you for bits of food or pets.</p>
<p>There are also many dogs that are &#8230; strays? no&#8230;. wild? .. no&#8230; independent, maybe. Most of these seem to be pretty healthy and wholesome, and they seem to like to stick around people.</p>
<h3>Taxis</h3>
<p>Taxis proved very useful for both long and short trips in Egypt. Usually, if you&#8217;re a westerner and you walk along a street, taxis will honk at you, slow down and say &#8220;taxi?&#8221; If you need a taxi, you just pop you head in the window and state you destination: &#8220;Midan Ramsees&#8221;. We have found it most useful to negotiate the fare before we get in. And whatever you do: You should always state the price first. So he nods and I say: &#8220;ten?&#8221; If the driver doesn&#8217;t agree, just say &#8220;maalesh&#8221; (never mind) and walk away. If your initial price was right, this often will have the driver change his price.</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2006/11/02/letters-from-egypt-top-five-surprises/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some words</title>
		<link>http://johannesbrodwall.com/2006/09/09/some-words/</link>
		<comments>http://johannesbrodwall.com/2006/09/09/some-words/#comments</comments>
		<pubDate>Sat, 09 Sep 2006 12:11:29 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Top 5]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/?p=113</guid>
		<description><![CDATA[Here are some of my favorite words. Signs of danger &#8216;Just&#8217;: bad word, as in &#8220;can&#8217;t we just develop the greatest application ever&#8221;, &#8220;can&#8217;t we just replace the database with JavaSpaces&#8221;, &#8220;can&#8217;t we just expose the functionality to the world as a web service&#8221;. &#8216;Should&#8217;: bad word, as in &#8220;it shouldn&#8217;t take more than a [...]]]></description>
			<content:encoded><![CDATA[<p>Here are some of my favorite words.</p>
<h2>Signs of danger</h2>
<ul>
<li><i>&#8216;Just&#8217;:</i> bad word, as in &#8220;can&#8217;t we <i>just</i> develop the greatest application ever&#8221;, &#8220;can&#8217;t we <i>just</i> replace the database with JavaSpaces&#8221;, &#8220;can&#8217;t we <i>just</i> expose the functionality to the world as a web service&#8221;.</li>
<li><i>&#8216;Should&#8217;:</i> bad word, as in &#8220;it <i>should</i>n&#8217;t take more than a few days to do that, should it,&#8221; &#8220;integrating two systems <i>should</i> be easy.&#8221; Listen for use of this word from people who &#8230; should know better.</li>
</ul>
<h2>Signs of thought</h2>
<ul>
<li><i>&#8216;Awkward&#8217;:</i> <a href="http://sethgodin.typepad.com/seths_blog/2006/08/awkward.html">good word</a> as in &#8220;It&#8217;s awkward to talk to your boss (who has way more experience than you do) about teaching her agile programming.&#8221;</li>
<li><i>&#8216;Why&#8217;:</i> good word, as in &#8220;why do you need to pass two parameters to this function?&#8221;, &#8220;why are we developing a login screen&#8221;, or &#8220;why did my change cause troubles for my colleague?&#8221;</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2006/09/09/some-words/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Tips for Developers</title>
		<link>http://johannesbrodwall.com/2006/08/28/tips-for-developers/</link>
		<comments>http://johannesbrodwall.com/2006/08/28/tips-for-developers/#comments</comments>
		<pubDate>Mon, 28 Aug 2006 17:34:07 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Top 5]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/?p=112</guid>
		<description><![CDATA[Update: Rewrote several sections &#8220;Fools ignore complexity; pragmatists suffer it; experts avoid it; geniuses remove it.&#8221; &#8211; Alan Perlis This article contains some things I have learned that has made me into a better developer than I was before I learned them. There are nine tips. These are not necessarily the only, or the best [...]]]></description>
			<content:encoded><![CDATA[<p><small><i><b>Update:</b> Rewrote several sections</i></small></p>
<blockquote><p>
<i>&#8220;Fools ignore complexity; pragmatists suffer it; experts avoid it; geniuses remove it.&#8221;</i> &#8211; Alan Perlis
</p></blockquote>
<p>This article contains some things I have learned that has made me into a better developer than I was before I learned them. There are nine tips. These are not necessarily the only, or the best things I have learned, but I like the number nine.</p>
<p>Becoming a better developer is a complex path. What I have found to be the most important attitude is to be versatile. Digging yourself down in one kind of activity, one &#8220;phase&#8221; of a project, one technology is a sure way to stagnate. I try to balance technical knowledge with &#8220;softer&#8221; skills. Developing software is about communicating, thinking, and programming. In order to be effective, you have to master all of these areas.</p>
<h2>1. Accept Failure (but only settle for perfection)</h2>
<blockquote><p><i>&#8220;Knowing the path is not the same as walking the path&#8221;</i> &#8211; Tao te Ching</p></blockquote>
<p>Sometimes, you know you could do better. But time, skill or luck may have it otherwise. The most important thing to learn to be good at anything is that <i>you will fail</i>. But failure is okay. Life goes on. By accepting failure, you should also realize that you can always improve. Be sure that you understand <i>why</i> you fail and how to improve. It is better to fail fast than to kinda success very slowly &#8211; failing allows for feedback &#8211; feedback allows for improvement.</p>
<p>A tip to help improve: Ask a friend &#8220;what would it take to get a 10/10?&#8221;</p>
<h2>2. Be brief</h2>
<blockquote><p><i>&#8220;Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.&#8221;</i> &#8211; Antoine de Saint-Exupery</p></blockquote>
<blockquote><p><i>&#8220;No code is better than no code.&#8221;</i> &#8211; Unattributed</p></blockquote>
<p>When you communicate, whether through code, documents, or emails, the more the information, the harder it is for the recipient to find what he need to know. Remove everything that is not needed: Comments that explain what the code does, sentence that don&#8217;t add to your email, code that is no longer needed, default values in code.</p>
<p>Besides, if you write the code, somebody will have to maintain the code as well.</p>
<p>A tip to help improve: &#8220;What <span style='text-decoration: line-through'>sentence</span> can I remove?&#8221;</p>
<h2>3. Develop in-depth knowledge of your field</h2>
<p>Understand which parts of your code are needed and which parts are not. What is the difference in behaviour between catching an exception in the main block, like this:</p>
<pre>
public class Foo {
    public static void main(String[] args) {
        try {
            doSomething();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
</pre>
<p>&#8230; and letting the main method throw the exception, like this?</p>
<pre>
public class Foo {
    public static void main(String[] args) throws Exception {
        doSomething();
    }
}
</pre>
<p>Exceptions are interesting creatures in Java-code. Understanding <a href="http://www.brodwall.com/johannes/blog/?p=110">what causes exceptions and what you can do about it</a> is very important. For those in a hurry, I give you Johannes&#8217; first rule of exceptions:</p>
<blockquote><p><i>&#8220;There&#8217;s usually nothing you can do about it&#8221;</i> &#8211; Johannes Brodwall</p></blockquote>
<p>Lastly, there are some basic skills that every developer should master: How to use source control, how to write unit tests and how to use continuous integration. If you don&#8217;t know how to do the first two of these, you&#8217;re not doing your job!</p>
<p>All tools also have default values for configuration. Recently, people have started talking about &#8220;<i>convention over configuration</i>&#8221; as a design principle. This basically means: Use smart defaults. Remember that configuration is also code, and that no code is better than no code.</p>
<p>A tip to help you improve: When you make something configurable in your program, consider adding a smart default value.</p>
<h2>4. Don&#8217;t overspecialize</h2>
<blockquote><p><i>&#8220;<a href="http://c2.com/cgi/wiki?SpecializationIsForInsects">Specialization is for insects</a></i> &#8211; Robert Heinlein</p></blockquote>
<p>There are many ways of overspecializing. Learning only one programming language is one of them.</p>
<p>Languages are the tools we use to think. Different languages will make you think differently. If you&#8217;re bilingual, you will probably notice that when you speak a different language, you have a different personality. I, for example, master both English and Norwegian well. (I am speaking in English now, right?) And I am much wittier when I speak Norwegian.</p>
<p>The same thing holds for computer languages. The language you use shapes the way you think. You will benefit enormously from learning a language that is radically different from what you use daily.</p>
<p>Choose a language that uses dynamic typing and that contain lambda expressions, or code blocks.</p>
<p>This code implements a very complex concept. See if you can understand what it does.</p>
<pre>
function getById(parentId) {
  var rs = ....;
  var parent = transformFromRs(rs);
  parent.kids = lazyLoad(
    function() {
      return kidsByParent(parentId);
    });
  return parent;
}
</pre>
<blockquote><p><i>&#8220;A programmer should be able to find a bug, market an application, refactor a spike, lead a team, architect an application, hack a kernel, schedule a project, build a database, route a network, give a reference, implement UserStories, analyze UserStories, work in a team, work alone, use patterns, innovate, write documentation, have a RealLife, create a cool website, email efficiently, resign gracefully, AdmitIgnorance, and keep on learning. Specialization is for recruiters&#8221;</i>  &#8212; with large apology to RAH and his estate, Peter Merel</p></blockquote>
<h2>5. See the bigger box</h2>
<blockquote><p><i>&#8220;The easiest way to build something simpler is to not build things you don&#8217;t need.  64% of our software is barely used&#8221;</i> &#8211; Alan Shalloway</p></blockquote>
<p>Your problem always exists in a context. If you understand the context, you might realise that there is another, much simpler solution to your problem.</p>
<p>A hypothetical example: Your task is to implement a mechanism for prioritizing jobs. This is to make sure that our real important jobs complete within a minute. (The &#8220;why&#8221;) Maybe you find out that by optimizing an algorithm, everything runs fast enough, and you don&#8217;t have to prioritize. Or maybe you just buy a faster machine and you end up not even having to optimize.</p>
<p>Even when you cannot thing of a way to simplify, understanding why can help you create a better system, or understand your role in the organization. Why are we implementing the payment function? To make our users pay for the online ticket system. Why do we create an online ticket system? Because our relationships with xxx gives us a unique chance to offer a better service.</p>
<p>Look up from your computer, look around. Why is the world around you doing what it is?</p>
<h2>6. There is only one rule of design</h2>
<p>Get the right coupling between the parts. Two things are coupled if change to one requires change to the other. If this change seems inappropriate or clumsy, that means that the parts are too closely coupled. Overly close coupling is cause by: Duplication, faulty abstractions, inappropriate intimacy, poorly design system boundaries.</p>
<p>When you remove coupling, be sure you remove it, not that you just hide it. Using string (for example XML) as a communication format instead of rich objects can often hide the coupling without removing it.</p>
<p>Design is about coupling. The rest are details.</p>
<p>A tip to help you improve: &#8220;When I change this decision, what else in my system will need to change? Why? How can I avoid that?&#8221;</p>
<h2>7. Understand the difference between haste and productivity</h2>
<blockquote><p><i>&#8220;Don&#8217;t just do something, stand there!&#8221;</i> &#8211; Unattributed</p></blockquote>
<p>The most common problem I see when something goes wrong is that people panic. Take a deep breath. <b>Don&#8217;t</b> panic. This is especially true for those who feel responsible, but have nothing they can do to help, like project managers.</p>
<p>Productivity is a matter of managing and completing tasks. Productivity guru <a href="http://www.davidco.com/">Dave Allen</a> outlines a method in &#8220;Getting things done&#8221; a method that I find helpful:</p>
<ol>
<li>First, make sure that all that you have to do to complete your goal is <i>written down</i> and organized, so you can see what you have to do. For work email, I use the &#8220;flag&#8221; functionality in Outlook. For private emails, I use the gmail inbox. You goal is to get everything done. To empty your inbox. Use lists, failing tests cases, reminders, sticky notes as well, but be sure that you know the totality of your work. Whatever you do: Don&#8217;t waste brainpower remembering what you need to do.</li>
<li>When you get an item, decide whether to Do it now (if it takes less than 2 minutes, do it right away), Delegate it (but remember to follow up!), Defer it to a specific date, Do it later or Drop it</li>
</ol>
<p>Two tips to help you improve: Make sure everything is written down and nothing falls between the cracks, and master the art of the two-minute email to keep your backlog short.</p>
<h2>8. Implement for today</h2>
<p>The most common root cause of problems that I see is insufficient myopia. People see too far ahead and think too far ahead. This leads to code that: Tries to optimize things that turn out not to be important, tries to generalize things that will never vary, tries to expose interfaces that will never be reused (with web services! whee!) or try to handle situations error situations in clever ways.</p>
<p>The problem is that code that tries to solve a more complicated problem is usually more verbose, which means that it is less robust. And functionality that has never been tested properly (for example: error handling routines) never work.</p>
<p>At the same time, don&#8217;t be restricted by what is there today. Delete code that is no longer needed, comments that make no sense. Learn how to discover whether code is dead or not.</p>
<h2>9. Leave proud</h2>
<p>You cannot always solve the problem you&#8217;re working on in a perfect way, but you should leave your code, your document or whatever you&#8217;re working on in such a state that you could be satisfied never touching it again.</p>
<p>Don&#8217;t leave needless boilerplate comments, name your classes, methods and variables well. Indent your code properly. Fix typos.</p>
<p>You could be hit by a truck tonight. What will those who come after you think of your legacy?</p>
<h2>Finally: A word in parting:</h2>
<blockquote><p><i>&#8220;It is better to be clearly wrong than obscurely right&#8221;</i> &#8211; Ken Orr <a href="http://weblogs.java.net/blog/johnreynolds/archive/2006/03/ken_orrs_advice_1.html">[1]</a></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2006/08/28/tips-for-developers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why I Hate SOA: Bad Ideas that Just won&#8217;t Die</title>
		<link>http://johannesbrodwall.com/2006/07/01/why-i-hate-soa-bad-ideas-that-just-wont-die/</link>
		<comments>http://johannesbrodwall.com/2006/07/01/why-i-hate-soa-bad-ideas-that-just-wont-die/#comments</comments>
		<pubDate>Sat, 01 Jul 2006 12:47:07 +0000</pubDate>
		<dc:creator>Johannes Brodwall</dc:creator>
				<category><![CDATA[SOA]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Top 5]]></category>

		<guid isPermaLink="false">http://www.brodwall.com/johannes/blog/?p=100</guid>
		<description><![CDATA[When I see people after they have read about SOA or attended a conference with SOA, there are a few ideas that seem to pop up repeatedly. I have even been guilty of using these ideas myself. These ideas were proven to be bad before SOA came around, and (some) SOA evangelists seem to think [...]]]></description>
			<content:encoded><![CDATA[<p>When I see people after they have read about SOA or attended a conference with SOA, there are a few ideas that seem to pop up repeatedly. I have even been guilty of using these ideas myself. These ideas were proven to be bad before SOA came around, and (some) SOA evangelists seem to think that SOA solved these problems. It did not. It just refused to learn from history. Some of these ideas work under some circumstances, but recent SOA-itis has caused them to be used in inappropriate contexts.</p>
<h3>1. SOA DAO tier</h3>
<p>Distributing a program at the DAO level is someting that comes back to haunt us every few years. The DAO level is a particularly bad place to try and divide and conquer: It is a very wide interface, as it will depend on your whole domain model. While projects are in active development, the domain model will have a lot of forces on it to change. Projects are better off resolving with these forces, but having a contractual interface will make this harder. The second reason the DAO is a bad candidate for distribution is that the database already does this! In many situations, putting a DAO in a separate physical tier gives no benefit over using the database directly.</p>
<p>Using the database directly is supposed to be bad. SOA does not take away any of the reasons why this is bad.</p>
<p><em>Appropriate use</em>: A SOA DAO tier is appropriate if you would want users outside your organization to have direct access to your database, but the only thing preventing you is the firewall and authorization concerns. In this case, be aware that there are forces to change domain model exposed by the DAO. These forces should be dealt with responsibly. But if you wanted to give people access to your database, you already knew this, right?<br />
<em>Antidote:</em> Use SOA to integrate with other applications, not with other tiers of the same application.</p>
<h3>2. Visual programming</h3>
<p>Visual programming has been a recurring bad idea for over 20 years. SOA has resurrected it, but only in zombie form. The ugly truth is that the examples people use to demonstrate &#8220;the power&#8221; of BPMN are examples that turn out to be pretty simple in good Java-code, too! When you get to try and solve the hard and interesting problems, the workflows are no longer very understandable. And they will depend on code which will be harder to write, because the logic (in a programming language) is detached from it context (the workflow). Personally, I think it was the same kind of detachment that made EJBs fail.</p>
<p>Visual programming is a powerful image, even though it is fundamentally flawed. I am sure we will see it come back to haunt us many times again.</p>
<h3>3. Component Specialization</h3>
<p>&#8220;<em>You work with that bit, and I&#8217;ll just sit over here and work with this bit</em>&#8220;. These are the saddest words I hear on a software project. The strategy of dividing a system into components and having the developers specialize in each of their component would be a good idea if integration was easy and if component design was easy. However, the non-technical challenges of integration (&#8220;<em>What? The &#8216;email&#8217; field is the senders email, not the receipients email? But I don&#8217;t have that information here!</em>&#8220;) will not go away by using SOA. And splitting a system into components has always been difficult to do well. The only solution I have found is the let the interface be maleable long enough that we can correct the inevitable initial mistakes. SOA projects that define a component structure and divide the team according to this structure are on the fast-track to wrapper-land.</p>
<p>The antidote is strangely enough related to a strong point of SOA: Organize your problems by perceivable functionality to the users (that is, services). These services cut through your application, from UI to database. A developer should be able to understand the flow through all the layers.</p>
<h3>4. Interface with the World Early</h3>
<p>&#8220;<em>We develop with Web Services, so other systems can connect to us without more work.</em>&#8221; If you haven&#8217;t designed a protocol with external use in mind (and that costs a lot more!), your interface is likely to be bad for your new users, whether it is written in Web Services, CORBA, or RPC. By opening your system for integration with other systems, you freeze the interface, which also has a huge cost, especially with an immature interface. The reason databases are the choke point for change in many organizations is because it has a potentially unknown number of systems integrating with it. SOA does not solve this issue.</p>
<p>If you need an interface that the world can use, you should expect this to cost time and planning. SOA gives a few tools to help you along the way, but opening yourself to the world is still something you want to consider very carefully before you do. And it will always be. Don&#8217;t expose yourself to the world unless you get paid for it. (Is that the porn star principle?)</p>
<h3>5. The cost of technology integration</h3>
<p>&#8220;<em>.NET is good for user interfaces, EJBs are good for business logic [sic!]. Why don&#8217;t we use them both and just integrate via Web Services</em>?&#8221; There are many reasons why developing a system with a large set of technologies is a bad thing. Most of them have nothing to do with technical integration.</p>
<p>By all means, if you have large, heterogenous systems that need to be integrated, SOA technologies will probably help you. But don&#8217;t design your system as several large, heterogenous systems yourself!</p>
<h3>6. DIY protocol</h3>
<p>&#8220;<em>We have rewritten our CORBA service to only take strings as input and output, so now it is SOA</em>&#8220;. I think I will leave that one as an exercise to the reader.</p>
<p>In truth, SOA has helped preventing people from creating their own protocols. There is still work to be done, though.</p>
<h3>Conclusion</h3>
<p>SOA doesn&#8217;t fix the underlying problems with visual programming, exposing your domain model to the world, the costs of published interfaces, or the cost of developing a system with several dissimilar technologies. It makes some of these problems more managable, but when you are designing a single system (or Service), these things are still very expensive and problematic. The focus on SOA seems to have made a lot of people forget that it will always be cheaper to develop one system than to develop several systems and glue them together. Use these technologies when there is a real, business problem to be solved by them. In most cases, my guiding principle continues to be &#8220;Don&#8217;t use it unless you really need it.&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://johannesbrodwall.com/2006/07/01/why-i-hate-soa-bad-ideas-that-just-wont-die/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

