<?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/"
	>

<channel>
	<title>Transient Technology &#187; maven</title>
	<atom:link href="http://martinaharris.com/tag/maven/feed/" rel="self" type="application/rss+xml" />
	<link>http://martinaharris.com</link>
	<description>Next time you look it might be gone</description>
	<lastBuildDate>Tue, 24 Jan 2012 18:14:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Update on building .NET</title>
		<link>http://martinaharris.com/2011/10/update-on-building-net/</link>
		<comments>http://martinaharris.com/2011/10/update-on-building-net/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 20:34:31 +0000</pubDate>
		<dc:creator>Martin Harris</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[dependency]]></category>
		<category><![CDATA[dll]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[silverlite]]></category>
		<category><![CDATA[sonar]]></category>

		<guid isPermaLink="false">http://martinaharris.com/?p=1085</guid>
		<description><![CDATA[Sometime back now I posted an article on building .NET and dependency management. I have come to learn that there are several ways. Here are my favorites. Build your own maven plugin to build .NET projects. Package 3rd party products &#8230; <a href="http://martinaharris.com/2011/10/update-on-building-net/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Sometime back now I posted an article on <a title="Building software with .NET dependencies in 2010" href="http://martinaharris.com/2010/06/building-software-with-net-dependencies-in-2010/" target="_blank">building .NET and dependency management</a>.</p>
<p>I have come to learn that there are several ways. Here are my favorites.</p>
<ol>
<li>Build your own <a href="http://maven.apache.org/guides/introduction/introduction-to-plugins.html" target="_blank">maven plugin</a> to build .NET projects. Package 3rd party products as zips and put them in maven. Write a plugin that reads solution and project files and calls MSBuild with the appropriate flags.  <strong>Advantage</strong>, maximum flexibility.  <strong>Disadvantage</strong>, lots of effort.</li>
<li>Use the existing <a href="http://maven-dotnet-plugin.appspot.com/" target="_blank">maven-dotnet-plugin</a>.  <strong>Advantage</strong>, does a lot for you including various types of test and coverage systems, plus it can run <a href="http://www.sonarsource.org/" target="_blank">sonar</a>.  <strong>Disadvantage</strong>, Hard to get it to work on complex silverlight projects. In fact hard full stop.  The docs are not great.</li>
<li>Use <a href="http://nuget.codeplex.com/" target="_blank">NuGet</a>.  <strong>Advantages</strong>, it has .NET pedigree and Microsoft Backing.  Adoption amongst .net developers is probably an easier sell than a java utility.  <strong>Disadvantages</strong>, Very early days for the project, as yet unproven.</li>
<li>Finally <a href="http://npanday.codeplex.com/" target="_blank">npanday</a>.  <strong>Advantages</strong>, nice integration with Visual Studio.  <strong>Disadvantages</strong>, very hard to get it to work with silverlight.  Impossible in fact as MS have kindly removed the command line baml compile utility.</li>
</ol>
<div>So in summary.  There are ways to do this now.  There is hope for .NET dependency management!</div>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2011%2F10%2Fupdate-on-building-net%2F&amp;title=Update+on+building+.NET" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2011%2F10%2Fupdate-on-building-net%2F&amp;title=Update+on+building+.NET" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2011%2F10%2Fupdate-on-building-net%2F&amp;title=Update+on+building+.NET" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fmartinaharris.com%2F2011%2F10%2Fupdate-on-building-net%2F&amp;headline=Update+on+building+.NET" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Update+on+building+.NET&amp;url=http%3A%2F%2Fmartinaharris.com%2F2011%2F10%2Fupdate-on-building-net%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Update+on+building+.NET&amp;u=http%3A%2F%2Fmartinaharris.com%2F2011%2F10%2Fupdate-on-building-net%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Update+on+building+.NET&amp;url=http%3A%2F%2Fmartinaharris.com%2F2011%2F10%2Fupdate-on-building-net%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Update+on+building+.NET&amp;url=http%3A%2F%2Fmartinaharris.com%2F2011%2F10%2Fupdate-on-building-net%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Update+on+building+.NET&amp;url=http%3A%2F%2Fmartinaharris.com%2F2011%2F10%2Fupdate-on-building-net%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fmartinaharris.com%2F2011%2F10%2Fupdate-on-building-net%2F&amp;title=Update+on+building+.NET&amp;summary=&amp;source=" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fmartinaharris.com%2F2011%2F10%2Fupdate-on-building-net%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fmartinaharris.com%2F2011%2F10%2Fupdate-on-building-net%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fmartinaharris.com%2F2011%2F10%2Fupdate-on-building-net%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div><div class="dzone_button" style="float: right; margin-left: 5px;">
<script type="text/javascript">
var dzone_url = 'http://martinaharris.com/2011/10/update-on-building-net/';
var dzone_title = 'Update on building .NET';
var dzone_blurb = '';
var dzone_style = '2';
</script>
<script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script>
</div>]]></content:encoded>
			<wfw:commentRss>http://martinaharris.com/2011/10/update-on-building-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Test anti-patterns project, contributors wanted!</title>
		<link>http://martinaharris.com/2009/11/anti-patterns-testing/</link>
		<comments>http://martinaharris.com/2009/11/anti-patterns-testing/#comments</comments>
		<pubDate>Mon, 16 Nov 2009 05:00:28 +0000</pubDate>
		<dc:creator>Martin Harris</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[software quality]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[junit]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[quality]]></category>
		<category><![CDATA[re-factor]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://martinaharris.com/?p=236</guid>
		<description><![CDATA[I deliberately wrote a poor quality test, so that I could show how easy it is to re-factor it to a better one.  I was driven by having seen lots of such poor tests and to be honest I don't want to see another of its ilk again.  I might write a test like this myself, but I would <strong>never</strong> leave it like this.  Its part finished, littered with cut and paste, poorly named methods and hard coded values.

I show how to re-factor the test using several patterns for test fixtures.  The setup stage is often the worst bit of a bad test.  If you want to contribute some of your own bad tests and example improvements, <strong>read the blog, download the project and contribute!</strong> <a href="http://martinaharris.com/2009/11/anti-patterns-testing/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Take a look at the following test class.  I deliberately wrote this poor quality test, so that I could show how easy it is to re-factor it to a better one.  I was driven by having seen lots of such poor tests and to be honest I don&#8217;t want to see another of its ilk again.  I might write a test like this myself, but I would <strong>never</strong> leave it like this.  Its part finished.  Its littered with cut and paste, poorly named methods and hard coded values.  It&#8217;s a bit like a surgeon performing an operation and not sewing up the hole!  I would go as far as to say that leaving tests in this state is unprofessional.  There is no excuse as most of the lessons of good naming and code re-use have been written down a long time back.  More lately in <a href="http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882">Clean Code by Robert C. Martin</a>.  I just don&#8217;t understand why people still write rubbish like this!  Possibly because they are allowed to get away with it!  Note that the test provides 100% coverage of the implementation class, but its not enough to stop there.</p>
<p>Have a read over the class, and then move on to read the steps to re-factor to better patterns.  I have several designs here that focus on the setup stage of a test.  As your tests get more complex you will find the patterns here support ever increasing complexity.  In an Agile project you might move from one system to the next as the requirements ramp up.  Then once you see where I am heading, I lay down a challenge.</p>
<h2>Test anti-patterns project, contributors wanted!</h2>
<p>If you have a Test Anti-Pattern that you would like to showcase.  Check out my code from gitHub, add the new example and examples of how to re-factor the code.  Blog it to your own blog with a reference to this page, or drop a comment.  If we get enough I will setup a page with an index to all the blogs.</p>
<p>The code can be<a href="http://help.github.com/forking/"> forked out with git</a> from gitHub <a href="http://github.com/mhgit/TerribleJavaTestingMadeGood">http://github.com/mhgit/TerribleJavaTestingMadeGood</a>.  It should be an easy start.  Its a full maven project with a small dependency set and maven site reports already built in for test coverage.  Its fully open source with the Apache 2.0 license.  Once you have your new example, tell me about it by adding a comment to this page, and following the git forking instructions for making a git pull available.</p>
<p><span id="more-236"></span></p>
<h2>I hope I never see another badly written test like this:</h2>
<p><cite>&#8230;but unfortunately I probably will&#8230; <img src='http://martinaharris.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> <cite></p>
<pre class="brush: java; gutter: false; wrap-lines: false">package org.testpatterns.dupcodeexample.lineutil.unit;

  import org.testpatterns.dupcodeexample.lineutil.SimplePage;
  import java.util.HashMap;
  import java.util.Map;
  import java.util.Set;
  import org.junit.Test;
  import static org.junit.Assert.*;

  /**
  * Terrible Test SimplePage Function.
  *
  * @author martinh
  */
  public class TerribleSimplePageTest {

    @Test
    public void testPageAssembley() {

        String item = "-23456789-";

        Map&lt;Integer, String&gt; expectedLines = new HashMap&lt;Integer, String&gt;();

        expectedLines.put(1, item + item + item + item + item);
        expectedLines.put(2, item + item + item + item + item);
        expectedLines.put(3, item + item + item + item + item);
        expectedLines.put(4, item + item + item + item + item);

        SimplePage page = SimplePage.newInstance(item, 20);
        Map&lt;Integer, String&gt; actualMap = page.getMap();

        assertEquals(expectedLines, actualMap);

    }

    @Test
    public void testPageKeySet() {

        String item = "-23456789-";

        Map&lt;Integer, String&gt; expectedLines = new HashMap&lt;Integer, String&gt;();

        expectedLines.put(1, item + item + item + item + item);
        expectedLines.put(2, item + item + item + item + item);
        expectedLines.put(3, item + item + item + item + item);
        expectedLines.put(4, item + item + item + item + item);

        SimplePage page = SimplePage.newInstance(item, 20);
        Set&lt;Integer&gt; actualKeySet = page.getKeySet();

        assertEquals(expectedLines.keySet(), actualKeySet);

    }

    @Test
    public void testAddLines() {

        String item = "-23456789-";

        SimplePage page = SimplePage.newInstance(item, 20);

        Map&lt;Integer, String&gt; additionalLines = new HashMap&lt;Integer, String&gt;();

        additionalLines.put(1, item + item + item + item + item);
        additionalLines.put(2, item + item + item + item + item);
        additionalLines.put(3, item + item + item + item + item);
        additionalLines.put(4, item + item + item + item + item);

        page.appendLines(item, 20);

        Map&lt;Integer, String&gt; actualMap = page.getMap();

        Map&lt;Integer, String&gt; expectedLines = new HashMap&lt;Integer, String&gt;();

        expectedLines.put(1, item + item + item + item + item);
        expectedLines.put(2, item + item + item + item + item);
        expectedLines.put(3, item + item + item + item + item);
        expectedLines.put(4, item + item + item + item + item);
        expectedLines.put(5, item + item + item + item + item);
        expectedLines.put(6, item + item + item + item + item);
        expectedLines.put(7, item + item + item + item + item);
        expectedLines.put(8, item + item + item + item + item);
        assertEquals(expectedLines, actualMap);

    }
}</pre>
<h2>Fixture as a normal method: ImprovedSimplePageTest</h2>
<p>I am not going to post up code for all the classes.  Check it out from gitHub for that.  So I just highlight the main steps and show the final full class.</p>
<p>The basis of the first pattern is simple.  Most small tests like this just need one method for setup, this eliminates all the cut and paste.  This might be run from an @Before, or @BeforeClass annotation, as part of the constructor or perhaps just from the test itself.  These techniques will have to be applied depending on what you need to achieve.  For instance if your setup is inserting into a database, you have to make sure your data does not violate db constraints.  So the annotations might not help, plus you have the added complexity of getting hold of your database.  A good pattern is to use an in memory db, but some of the annotations will cause the setup to get run before each test.  So in a nutshell attempt to have one setup, and its not that important which system you use to run it, that will depend on what your doing.</p>
<h3>Refactoring steps:</h3>
<ul>
<li>Rename methods.</li>
<p>Have a good strategy for your test names if they are good enough you will not need to comment the methods.  The pattern I use here is: [What is being tested]_[What is expected].  If you can&#8217;t fit it all into the name, the test is probably too big and needs breaking down.  A test should be concise.</p>
<li>Remove duplication.</li>
<ol>
There were two steps to this:</p>
<li>I Added this method: createLineExpectations to create expectations.</li>
<p>This allowed me to remove all the duplicated test setup that had been cut and pasted all through the class.  I wrote this bad test, using TDD to come up with the supporting implementation, so even as I wrote it the test went through several iterations.  During that process I left a chunk of unused map behind.  Which just goes to prove that if your test is messy, its difficult to spot problems.<br />
<strong>An unused chunk of code that hid in the duplications</strong></p>
<pre class="brush: java; light: true">  Map&lt;Integer, String&gt; additionalLines = new HashMap&lt;Integer, String&gt;();

  additionalLines.put(1, item + item + item + item + item);
  additionalLines.put(2, item + item + item + item + item);
  additionalLines.put(3, item + item + item + item + item);
  additionalLines.put(4, item + item + item + item + item);</pre>
<li>Added constants and moved all the hard coded value out.</li>
</ol>
</ul>
<h2>Collecting setup into an inner fixture class: LocalFixtureBasedPageTest</h2>
<p>Its not long before the technique starts to breakdown.  As you add more supporting methods it gets harder to see what is test, and what is setup.  So the next stage is to move the setup into an inner class.  This way, most ide&#8217;s will allow you to collapse the fixture hiding it away.  When I read a test, I am mostly interested in the expectations, not the setup.  Note that the constants have been moved into the fixture.  So the fixture becomes an inner class that supplies everything to do with setup for the test.</p>
<pre class="brush: java; light: true">    private class DataFixture {

        private final String ITEM = "-23456789-";
        private final int LINES_8 = 8;
        private final int LINES_4 = 4;

        Map&lt;Integer, String&gt; createLineExpectations(String item,
                int numLinesToCreate) {
            Map&lt;Integer, String&gt; expectedLines = Maps.newHashMap();

            StringBuilder sb = new StringBuilder();
            sb.append(item).append(item).append(item).append(item).append(item);
            String line = sb.toString();
            for (int i = 0; i &lt; numLinesToCreate; i++) {
                    expectedLines.put(i + 1, line);
            }

            return expectedLines;
        }
    }</pre>
<h2>Fixture as a spring injected component: SpringWiredSimplePageTest</h2>
<p>When a test gets more complex you sometimes end up with masses of complexity building up in inner classes.  I sometimes use inner classes to build complex data requirements using the <a href="http://www.factorypattern.com/method-chaining/">setter method chaining pattern</a> for instance.  Each inner class becoming a container for parameterized setup.  The next level of complexity is needing to share the setup over many test classes.</p>
<p><strong>These are your options.</strong></p>
<ol>
<li>Create a static helper class</li>
<p>Not a bad solution, but I hate having to access the methods via the class name.  Static classes often collect unrelated methods too.  Also, its often not possible to work with the restriction of being static.</p>
<li>Abstractions and class hierarchy.</li>
<p>This is often posed as a solution when you need to share the setup over many classes.  In this case its a terrible solution. The abstraction gets further complicated because your using the wrong OO mechanism.  It also means your test has to extend a class, in some situations, you are already extending to get at the internals of the object under test.</p>
<li>Use method injection to supply a fixture component.</li>
<p>If you break the fixture out to a component its easier to manage the complexity of the fixture away from the test with composition.  You can have many components each doing something specific for a set of tests.  You could even inject more than one component.  The design of the fixture can use other OO patterns to keep it neat.  For instance I once built a set of fixtures to supply ready made folder and file structures.  They all extended an abstract and implemented an interface.  The @Qualifier annotation was used to inject the correct implementation into the test.  On occasion a test used two of the component implementations.</ol>
<h3>Refactoring steps:</h3>
<ul>
<li>Move the Fixture inner class to its own component class.  If you get many of these its worth putting them in a separate project.</li>
<li>Add the @Component annotation from the spring project.</li>
<li>Change the type giving a more descriptive name.</li>
<li>Make the methods in the fixture public.</li>
<li>Better names for methods and types now that the fixture is not near the code that uses it.</li>
<li>Java doc for important methods.</li>
<li>Addition of getters for fields instead of direct access.</li>
<li>Improved createLineExpectations(int numLinesToCreate) by removing the dataItem, the fixture knows this data so no need to supply via method.</li>
<li>Convert to spring test. This means its possible to load in the spring configuration and autowire the test</li>
</ul>
<p>The test class markup to convert it into a spring test, and provide amongst other things auto wiring:</p>
<pre class="brush: java; light: true">
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:springAppConfig.xml")
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
public class SpringWiredSimplePageTest {
</pre>
<p>Autowire the fixture, and spring will inject it:</p>
<pre class="brush: java; light: true">
@Autowired
    private PageDataFixture dataFixture;
</pre>
<p>Your test setup is then just called like this:</p>
<pre class="brush: java; light: true">
Map&lt;Integer, String&gt; expectedLines = dataFixture.createPageExpectation(NUMBER_LINES_ON_PAGE_4, NUMBER_DATA_ITEMS_IN_LINE_5);
</pre>
<h2>Conclusions</h2>
<p>Once you have a test that gives 100% coverage, there is usually some more time that needs to be spent on cleaning the code.  There are some easy patterns that can help, there is nothing in this article that is complex or difficult to understand so there is no excuse for leaving it messy.  Bugs hide in messy code and I think you would agree, the final result is very easy to read:<a href="http://github.com/mhgit/TerribleJavaTestingMadeGood/blob/master/testing-made-good/src/test/java/org/testpatterns/dupcodeexample/lineutil/unit/SpringWiredSimplePageTest.java" TARGET="_blank">SpringWiredSimplePageTest</a></p>
<h3>Thanks to&#8230;</h3>
<p>All the people I have worked with over the years, who have shown me better ways to write and test code.  You know who you are.  Many thanks.</p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F11%2Fanti-patterns-testing%2F&amp;title=Test+anti-patterns+project%2C+contributors+wanted%21" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F11%2Fanti-patterns-testing%2F&amp;title=Test+anti-patterns+project%2C+contributors+wanted%21" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F11%2Fanti-patterns-testing%2F&amp;title=Test+anti-patterns+project%2C+contributors+wanted%21" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fmartinaharris.com%2F2009%2F11%2Fanti-patterns-testing%2F&amp;headline=Test+anti-patterns+project%2C+contributors+wanted%21" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Test+anti-patterns+project%2C+contributors+wanted%21&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F11%2Fanti-patterns-testing%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Test+anti-patterns+project%2C+contributors+wanted%21&amp;u=http%3A%2F%2Fmartinaharris.com%2F2009%2F11%2Fanti-patterns-testing%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Test+anti-patterns+project%2C+contributors+wanted%21&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F11%2Fanti-patterns-testing%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Test+anti-patterns+project%2C+contributors+wanted%21&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F11%2Fanti-patterns-testing%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Test+anti-patterns+project%2C+contributors+wanted%21&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F11%2Fanti-patterns-testing%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F11%2Fanti-patterns-testing%2F&amp;title=Test+anti-patterns+project%2C+contributors+wanted%21&amp;summary=&amp;source=" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fmartinaharris.com%2F2009%2F11%2Fanti-patterns-testing%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fmartinaharris.com%2F2009%2F11%2Fanti-patterns-testing%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F11%2Fanti-patterns-testing%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div><div class="dzone_button" style="float: right; margin-left: 5px;">
<script type="text/javascript">
var dzone_url = 'http://martinaharris.com/2009/11/anti-patterns-testing/';
var dzone_title = 'Test anti-patterns project, contributors wanted!';
var dzone_blurb = '';
var dzone_style = '2';
</script>
<script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script>
</div>]]></content:encoded>
			<wfw:commentRss>http://martinaharris.com/2009/11/anti-patterns-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Refactoring to Google Collections &#8211; ImmutableList  for simple code</title>
		<link>http://martinaharris.com/2009/10/google-collection-refactor-simplifies-implementation/</link>
		<comments>http://martinaharris.com/2009/10/google-collection-refactor-simplifies-implementation/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 14:37:13 +0000</pubDate>
		<dc:creator>Martin Harris</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[collections]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[immutable]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[thread]]></category>

		<guid isPermaLink="false">http://martinaharris.com/?p=54</guid>
		<description><![CDATA[Google collections are excellent in multi-threaded applications, so I thought I would re-factor some code to use them. <a href="http://martinaharris.com/2009/10/google-collection-refactor-simplifies-implementation/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was reading this excellent post on <a href="http://blog.jayway.com/2009/10/22/google-collections/" target="_blank">google collections by Sune Simonsen</a> and decided to re-factor some code of mine.  I have an immutable results object used in a multi-threaded application.  I wanted to feel the difference using the google ImmutableList.  My existing class provides immutability in a very similar way to the google classes.  Static methods are used to instantiate the object.  An array is used to back a list collection.  Defensive copies are made to protect the immutability of the object.  Moving to <a href="http://code.google.com/p/google-collections/" target="_blank">google collections</a> is easy and makes my implementation simple whilst reducing test overhead.</p>
<p><span id="more-54"></span></p>
<h3>Steps taken to refactor</h3>
<p>There was actually very little to do.</p>
<p><strong>Step 1, add a maven dependency</strong></p>
<pre class="brush: xml; gutter: false">
<dependency>
            <groupId>com.google.collections</groupId>
            <artifactId>google-collections</artifactId>
            <version>1.0-rc3</version>
            <type>jar</type>
</dependency>
</pre>
<p><strong>Step 2, replace the array with an ImmutableList</strong></p>
<pre class="brush: java; light: true">
private static final LineResult[] EMPTY_LINERESULT_ARRAY = new LineResult[0];
private LineResult[] lineResults = EMPTY_LINERESULT_ARRAY;
</pre>
<p>could become:</p>
<pre class="brush: java; light: true">
private List&lt;LineResult&gt;  lineResults = ImmutableList.of();
</pre>
<p>In the end I used ImmutableList to clearly my intent.  The usage is internal to the class so there is no advantage in using the List interface.</p>
<pre class="brush: java; light: true">
private ImmutableListst&lt;LineResult&gt;  lineResults = ImmutableList.of();
</pre>
<p><strong>Step 3, The constructor and static factory methods are simplified</strong><br />
We are no longer using an array to back the list, so the protective copy can be moved from the constructor into the static method.  This reduces the window of vulnerability you are exposed to before capturing the data held in the list.  This is a direct result of the google class providing a static factory method.  Nb.  Its a shame that the standard collections don&#8217;t provide static factory methods.</p>
<p>Prior to the changes the protective copy was done in construction like this.</p>
<pre class="brush: java; light: true">
 this.lineResults = lineResults.toArray(EMPTY_LINERESULT_ARRAY);
</pre>
<p>This result is a much simpler constructor.</p>
<pre class="brush: java; light: true; highlight: 3">
private ResultsFileSearch(File fileFound, ImmutableList&lt;LineResult&gt; lineResults) {
        this(fileFound);
        this.lineResults = lineResults;
}
</pre>
<p>My newInstance method makes use of the ImmutableList.copyOf static factory method resulting in a very clean conversion of List into Immutable list.  Note that generics is inferring the type.</p>
<pre class="brush: java; light: true; highlight: 4">
public static ResultsFileSearch newInstance(File fileFound
                 , List&lt;LineResult&gt; lineResults) {
        return new ResultsFileSearch(fileFound
                        ,ImmutableList.copyOf(lineResults));
}
</pre>
<p><strong>Step 4, the getLineResults method no longer has to deal with the array or conversion.</strong><br />
The original array backed object had to deal with returning either an empty list or conversion to an unmodifiable list.  There are two things I did not like about this when I wrote the original.</p>
<ul>
<li>The code has to check the array resulting in some conditional logic.  This increases the test overhead slightly.</li>
<li>The use of Collections.unmodifiableList(Arrays.asList(lineResults)); is very ugly and slow.</li>
</ul>
<p>This was the original, <em>note the subtle bug when returning an empty list</em>.</p>
<pre class="brush: java; light: true">
 public List&lt;LineResult&gt; getLineResults() {

        if ((this.lineResults.length == 0)) {
            return Collections.emptyList();
        } else {
            return Collections.unmodifiableList(Arrays.asList(lineResults));
        }
        return this.lineResults;
}
</pre>
<p>I hope you agree its a much simpler version using the google code.  As we are now using the Immutable implementation, we don&#8217;t have to worry about exposing the reference.</p>
<pre class="brush: java; light: true">
public List&lt;LineResult&gt; getLineResults() {
        return this.lineResults;
}
</pre>
<h3>Conclusions</h3>
<p>Using the google collections makes my implementation much cleaner.  Several complexities are given over to the google collections classes.  Moreover testing of my class is simpler.  The changes are contained within the class.  None of the method signatures change, which has two consequences.  On the plus side the re-factor is contained within this class.  On the negative side, any code modifying the list will raise an UnsupportedOperationException which was no different to my original version.  The construction of my class might be slightly slower, the memory overhead slightly bigger now that we are not using the array.  Counter to this, the getLineResults method is quicker as it now only returns a reference.  In my program this is more important as architecturally it uses bounded queues to hold these objects for processing by threads.  So although its using a little extra memory, its constrained.  The performance gain is worth it.</p>
<p>I recommend using the com.google.common.collect package but adhere to the <a href="http://code.google.com/p/google-collections/wiki/Faq" target="_blank">caveats</a> i.e don&#8217;t expose the types in an API etc.</p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fgoogle-collection-refactor-simplifies-implementation%2F&amp;title=Refactoring+to+Google+Collections+-+ImmutableList++for+simple+code" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fgoogle-collection-refactor-simplifies-implementation%2F&amp;title=Refactoring+to+Google+Collections+-+ImmutableList++for+simple+code" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fgoogle-collection-refactor-simplifies-implementation%2F&amp;title=Refactoring+to+Google+Collections+-+ImmutableList++for+simple+code" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fgoogle-collection-refactor-simplifies-implementation%2F&amp;headline=Refactoring+to+Google+Collections+-+ImmutableList++for+simple+code" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Refactoring+to+Google+Collections+-+ImmutableList++for+simple+code&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fgoogle-collection-refactor-simplifies-implementation%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Refactoring+to+Google+Collections+-+ImmutableList++for+simple+code&amp;u=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fgoogle-collection-refactor-simplifies-implementation%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Refactoring+to+Google+Collections+-+ImmutableList++for+simple+code&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fgoogle-collection-refactor-simplifies-implementation%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Refactoring+to+Google+Collections+-+ImmutableList++for+simple+code&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fgoogle-collection-refactor-simplifies-implementation%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Refactoring+to+Google+Collections+-+ImmutableList++for+simple+code&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fgoogle-collection-refactor-simplifies-implementation%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fgoogle-collection-refactor-simplifies-implementation%2F&amp;title=Refactoring+to+Google+Collections+-+ImmutableList++for+simple+code&amp;summary=&amp;source=" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fgoogle-collection-refactor-simplifies-implementation%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fgoogle-collection-refactor-simplifies-implementation%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fmartinaharris.com%2F2009%2F10%2Fgoogle-collection-refactor-simplifies-implementation%2F" target="_blank"><img class="lightsocial_img" src="http://martinaharris.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div><div class="dzone_button" style="float: right; margin-left: 5px;">
<script type="text/javascript">
var dzone_url = 'http://martinaharris.com/2009/10/google-collection-refactor-simplifies-implementation/';
var dzone_title = 'Refactoring to Google Collections &#8211; ImmutableList  for simple code';
var dzone_blurb = '';
var dzone_style = '2';
</script>
<script language="javascript" src="http://widgets.dzone.com/links/widgets/zoneit.js"></script>
</div>]]></content:encoded>
			<wfw:commentRss>http://martinaharris.com/2009/10/google-collection-refactor-simplifies-implementation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

