<?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>henko.net</title>
	<atom:link href="http://henko.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://henko.net</link>
	<description>Home of a human being and software developer</description>
	<lastBuildDate>Wed, 21 Dec 2011 11:12:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Separate class for each id type</title>
		<link>http://henko.net/imperfection/separate-class-for-each-id-type/</link>
		<comments>http://henko.net/imperfection/separate-class-for-each-id-type/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 11:12:15 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Implementation]]></category>

		<guid isPermaLink="false">http://henko.net/?p=1007</guid>
		<description><![CDATA[The code I&#8217;ve been looking at recently has quite some problems with managing various ids. The ids in the system are confusing on many levels, both syntactically and semantically. To begin with, there are a lot of them. They are represented using a mix of ints, longs and strings. Even the same id may be [...]]]></description>
			<content:encoded><![CDATA[<p>The code I&#8217;ve been looking at recently has quite some problems with managing various ids. The ids in the system are confusing on many levels, both syntactically and semantically.</p>

<ul>
<li>To begin with, there are a lot of them.</li>
<li>They are represented using a mix of ints, longs and strings. Even the same id may be represented using different data types in different places.</li>
<li>We&#8217;ve had bugs where an object with multiple ids has been put into a map using one of its ids as key and someone else tries to get it out using another id as key.</li>
<li>Their names are sometimes confusingly similar.</li>
<li>The same id may have multiple names, used intermixed.</li>
</ul>

<p>Therefore, we&#8217;ve discussed various ways of getting a grip on the situation. One of the alternatives, which I think sounds rather good, is to use a separate class to represent each type of id.</p>

<p>For example, a <code>User</code> class doesn&#8217;t have a <code>int userId</code> field, but a <code>UserId userId</code> field. How <code>UserId</code> internally represents the id (perhaps as a long or string), is up to that class.</p>

<p>Some of the pros of this solution, from a Java perspective, are:</p>

<ul>
<li>When the id is used &#8220;out of context&#8221;, you don&#8217;t have to rely on variable naming to convey its meaning, you will get static type checking to help you.</li>
<li>If you want to change the internal representation (int, long, etc), you only need to change a rather limited number of places instead of all over the system.</li>
<li>You get an opportunity to create a suitable <code>toString()</code>, <code>hashCode()</code>, and or <code>equals()</code> implementation.</li>
<li>You get a natural place for common convenience methods regarding the id, reducing the need for various &#8220;util classes&#8221; (which really are <a href="/imperfection/private-static-methods-might-be-a-smell/" title="more procedural than object oriented">more procedural than object oriented</a>).</li>
</ul>

<p>The primary drawback that I can think of is that it generates a lot more small objects which may increase memory usage. But until it has been proven to be an actual problem in a specific case, I think that is a reasonable cost for the benefits above.</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/separate-class-for-each-id-type/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Two types of design</title>
		<link>http://henko.net/imperfection/two-types-of-design/</link>
		<comments>http://henko.net/imperfection/two-types-of-design/#comments</comments>
		<pubDate>Wed, 02 Nov 2011 21:09:18 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Imperfection]]></category>

		<guid isPermaLink="false">http://henko.net/?p=997</guid>
		<description><![CDATA[Lately, I&#8217;ve been thinking about two ways to design a system. I&#8217;m having trouble with figuring out which one I actually prefer. I&#8217;ll try to describe them below. If you would like to read through the description and leave a comment or two I would be very grateful! Feel free to just add a comment [...]]]></description>
			<content:encoded><![CDATA[<p>Lately, I&#8217;ve been thinking about two ways to design a system. I&#8217;m having trouble with figuring out which one I actually prefer. I&#8217;ll try to describe them below.</p>

<p>If you would like to read through the description and leave a comment or two I would be very grateful! Feel free to just add a comment or two in this document.</p>

<p>I’m using a fictional weather service as example. It does something along the lines of fetching the current weather data from a web service, parse it and extract relevant data, fetch some information about the current geographical location, and finally analyze them to provide the user with some interesting information about the weather.</p>

<h3>Design A</h3>

<p>The system is designed with the majority of the code as a set of completely independent modules which are joined together with a small amount of glue code.</p>

<p style="text-align: center"><a href="/wp-content/uploads/2011/11/design-a.png"><img src="http://henko.net/wp-content/uploads/2011/11/design-a-300x196.png" alt="Example of Design A" title="Example of Design A" width="300" height="196" class="aligncenter size-medium wp-image-999" /></a></p>

<p>Classes and modules tend to send primitive data or value objects to each other rather than intelligent classes. Modules tend to have none or very few dependencies. Re-use of modules is simplified because they can be used independently of each other.</p>

<p>Modules tend to be stateless with any state kept in the caller/glue code. External dependencies are kept as shallow as possible in the call/dependency tree.</p>

<p>The sequence of calls needed to perform something is encoded in the glue code rather than spread out in the system. It is up to the caller needs to know in which order to call modules. It delegates the execution of each step to the modules, but keeps control. The call stack will always remain rather short.</p>

<p>Each module can be unit tested in isolation and internal classes inside the modules do not have separate tests. The glue code is tested through integration tests that run end-to-end to verify that the system works. Unit tests often become easier to write because there is no need for mocking dependencies.</p>

<p>This approach is more &#8220;functional&#8221; in nature as modules tend to be stateless, get all required data as input and return the result as output.</p>

<h3>Design B</h3>

<p>The system is designed as a set of interacting, often stateful, modules which are joined together in a graph of dependencies.</p>

<p style="text-align: center"><a href="http://henko.net/wp-content/uploads/2011/11/design-b.png"><img src="http://henko.net/wp-content/uploads/2011/11/design-b.png" alt="Example of Design B" title="Example of Design B" width="420" class="aligncenter size-medium wp-image-1000" /></a></p>

<p>One module often calls another module without providing all information necessary to complete a task, secure in the knowledge that the other module can obtain it. This is typically performed through injection of dependencies. Modules therefore often have multiple dependencies.</p>

<p>Modules are often stateful or depends on objects which are. External dependencies are often pushed as deep down the dependency tree as possible.</p>

<p>The sequence of calls needed to perform something is often spread out over a set of modules and partially encoded in the dependency setup. The caller can often call one or a few modules knowing they will in turn call others. The caller delegates not only the execution of tasks but also control to a large degree. The call stack will in the middle of execution be rather deep.</p>

<p>Each module is unit tested, typically with any dependencies replaced with stub/mock/fake instances. Integration tests ensure that the wiring of the modules is correct and that the system works together. There is little fundamental difference between tests on different levels.</p>

<p>This approach is perhaps more &#8220;object oriented&#8221; in nature where the system is divided into a set of stateful, intelligent objects that cooperate in generating the output.</p>

<h3>Questions</h3>

<p>I would appreciate any comments or input, such as your thoughts about:</p>

<ul>
<li>Which alternative you prefer? Which one do you most often use? Perhaps a hybrid?</li>
<li>Under which circumstances is one better than the other?</li>
<li>Are they good at different levels? E.g. method, class, component, or system level.</li>
<li>Is there a &#8220;OO vs functional&#8221; difference, as I suggest?</li>
<li>Is either of them easier to maintain than the other?</li>
<li>Can they be described more clearly? What are they called?</li>
<li>Have I gotten anything or everything completely wrong?</li>
</ul>

<p>Feel free to enter any feedback or comments below.</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/two-types-of-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Name classes for content, not usage</title>
		<link>http://henko.net/imperfection/name-classes-for-content-not-usage/</link>
		<comments>http://henko.net/imperfection/name-classes-for-content-not-usage/#comments</comments>
		<pubDate>Wed, 26 Oct 2011 06:51:30 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Implementation]]></category>

		<guid isPermaLink="false">http://henko.net/?p=988</guid>
		<description><![CDATA[To make a class as universally usable as possible, name it after its content, not its intended usage. After all, the usage might change, and you may find a new area of use for the class which you didn&#8217;t foresee. Example In the project I&#8217;m working on, I had a class called SelectedInstalledBase which represented [...]]]></description>
			<content:encoded><![CDATA[<p>To make a class as universally usable as possible, name it after its content, not its intended usage. After all, the usage might change, and you may find a new area of use for the class which you didn&#8217;t foresee.</p>

<h3>Example</h3>

<p>In the project I&#8217;m working on, I had a class called <code>SelectedInstalledBase</code> which represented the subset of products in a customer&#8217;s &#8220;installed base&#8221; selected by the user. (An &#8220;installed base&#8221; is this domain is all the products a customer has bought.)</p>

<p>That was fine until I wanted an inverted version of the selection, i.e. the installed base not selected (the &#8220;remaining installed base&#8221;). Then, it suddenly didn&#8217;t make much sense to create a <em>remaining</em> installed base of type <code>SelectedInstalledBase</code>. It also didn&#8217;t make sense to create a clone of <code>SelectedInstalledBase</code> named <code>RemainingInstalledBase</code> as they would be identical apart from the name.</p>

<p>The solution the problem was renaming <code>SelectedInstalledBase</code> to <code>InstalledBaseIdentifier</code> (because it represented the ids of the selection made by the user) and naming the variables to reflect the different cases, such as <code>InstalledBaseIdentifier selectedInstalledBase</code> and <code>InstalledBaseIdentifier remainingInstalledBase</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/name-classes-for-content-not-usage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What I learned from Kent Beck</title>
		<link>http://henko.net/imperfection/what-i-learned-from-kent-beck/</link>
		<comments>http://henko.net/imperfection/what-i-learned-from-kent-beck/#comments</comments>
		<pubDate>Thu, 08 Sep 2011 18:16:20 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Implementation]]></category>

		<guid isPermaLink="false">http://henko.net/?p=976</guid>
		<description><![CDATA[This is a summary of what learned from a &#8220;Mastering TDD&#8221; course with Kent Beck. Given he is the creator of JUnit, I guess his thoughts on unit testing are worth considering. In some cases I might have rewritten, changed, extended or simply misunderstood what he was saying, but these were my notes from the [...]]]></description>
			<content:encoded><![CDATA[<p>This is a summary of what learned from a &#8220;Mastering TDD&#8221; course with Kent Beck. Given he is the creator of JUnit, I guess his thoughts on unit testing are worth considering. <img src='http://henko.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>

<p>In some cases I might have rewritten, changed, extended or simply misunderstood what he was saying, but these were my notes from the course, nevertheless.</p>

<ul>
<li>Doing TDD is like losing weight. You like having lost some weight, but not actually losing it.</li>
<li>Taking really, really small TDD steps is useful when you&#8217;re unsure/confused about the code you are writing. That way you are at least moving forward.</li>
<li>What kills productivity isn&#8217;t doing something slowly, but not doing it. I.e. when you switch to reading email, surfing the web, etc instead of working.</li>
<li>Implementing a piece of code <em>inside</em> a test keeps your options open if you&#8217;re not sure about the future interface.</li>
<li>Start writing the test which you expect to learn the most from.</li>
<li>Most important, according to Kent: Writing a test is really telling a story about the code. Having that mindset helps you work out many other problems with testing.</li>
<li>Deleting tests comes down to story telling &#8211; which tests do we need to tell the story about this code. (There is also a technical/coverage aspect, but it is of lower importance).</li>
<li>When unsure about whether to clean something up or not &#8211; think about the amount of leverage it will give you. Worth it?</li>
<li>When coding exploratory (without TDD), start TDD:ing when/if you don&#8217;t expect the code to die anymore, or when you think you&#8217;ve learned the most important lessons.</li>
<li>In many cases: The more discussion, the less important the decision. Everyone agrees about the really important ones.</li>
<li>Write code in a functional style, as it is more suitable for testing.</li>
<li>Consider not using dependency injection as it makes TDD harder by encouraging a design where dependencies are spread out over the system. Instead, design many stand-alone modules which are unit tested individually without the need for mocked dependencies, then join them together in other classes which are tested through integration tests.</li>
<li>Avoid abstact superclasses for unit test classes as they make the individual test classes harder to read.</li>
<li>Duplication is often more okay in tests than in the production code because readability of tests is so important.</li>
<li>For infrastructure-related setup code, @Rule can be used instead of inheritance in many cases.</li>
<li>Write tests on the high and low level, but be weary of too many tests on the mid level. They tend to be more of a problem than help when refactoring.</li>
<li>Kent: &#8220;I try not to have more tests than I need&#8221;</li>
<li>Use one test class per fixture (i.e. set of test data). Name the classes after the fixture. That is how JUnit is designed and intended to be used.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/what-i-learned-from-kent-beck/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Private static methods might be a smell</title>
		<link>http://henko.net/imperfection/private-static-methods-might-be-a-smell/</link>
		<comments>http://henko.net/imperfection/private-static-methods-might-be-a-smell/#comments</comments>
		<pubDate>Wed, 04 May 2011 12:46:00 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Implementation]]></category>

		<guid isPermaLink="false">http://henko.net/?p=955</guid>
		<description><![CDATA[I was extracting smaller methods out of existing big ones, in a class I was working on. Some of these extracted methods became &#8220;utility methods&#8221;: they would perform some operation on the parameters given to it, but not use any of the fields in the class. These methods could just as well have been static. [...]]]></description>
			<content:encoded><![CDATA[<p>I was extracting smaller methods out of existing big ones, in a class I was working on. Some of these extracted methods became &#8220;utility methods&#8221;: they would perform some operation on the parameters given to it, but not use any of the fields in the class. These methods could just as well have been static.</p>

<p>I ended up with a set of these methods, most of them accepting the same parameter. In this case, the common object was a Set<Product>. Seeing the pattern emerge, I created a new object called ProductSet and moved all the private static methods there. In this class, they would instead become public non-static methods. The code immediately felt better. As I continued working, I found even more code that really belonged on this ProductSet object and it became one of the main abstractions in the code.</p>

<p>So, to summarize, my insight of the day:</p>

<blockquote>
  <p>A sign that the Move Method refactoring might be appropriate is that you have private static methods in a class (or private methods that could as well be static). If it doesn&#8217;t use any of the class&#8217; fields, then maybe it belongs elsewhere.</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/private-static-methods-might-be-a-smell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fire protection</title>
		<link>http://henko.net/imperfection/fire-protection/</link>
		<comments>http://henko.net/imperfection/fire-protection/#comments</comments>
		<pubDate>Thu, 24 Mar 2011 21:32:47 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Process]]></category>

		<guid isPermaLink="false">http://henko.net/?p=949</guid>
		<description><![CDATA[When you build a house you have to think about fire safety. For a small cottage it might be enough with simple smoke detector. For a large building must also have fire alarms, extinguishers, sprinklers, emergency stairways, signs of evacuation routes and much more. Exactly what is needed is adapted to house size. All this [...]]]></description>
			<content:encoded><![CDATA[<p>When you build a house you have to think about fire safety. For a small cottage it might be enough with simple smoke detector. For a large building must also have fire alarms, extinguishers, sprinklers, emergency stairways, signs of evacuation routes and much more. Exactly what is needed is adapted to house size. All this is regulated by law, as we through dearly bought experience know that the consequences could otherwise be very dire. Would it not be a legal requirement, many houses would be built without; perhaps because of an ignorant customer or contractor who underestimate the risk, or perhaps as a result of a tight budget or schedule.</p>

<p><img src="http://henko.net/wp-content/uploads/2011/03/LEFTfireextinguisher1-e1301002271395.jpg" alt="Fire Extinguisher" title="Fire Extinguisher" width="199" height="252" class="alignright size-full wp-image-951" />Today in the programming industry we have a similar problem, where developers and others involved in software development often underestimate the risks resulting from the absence of an automated test suite. Alternatively, they feel that the pressure to deliver quickly is too large. As a result many projects, even very large and complex ones, have no automated tests that can provide a warning signal when serious errors are introduced.</p>

<p>Maybe we simply need to demand that basic automated tests should be available to all code that is written. The larger and more complex the system, the higher the demands, in the same way that fire safety requirements of a skyscraper is several magnitudes higher than those for a cottage. Maybe it would be a bit overkill to write these requirements into a country&#8217;s laws. It might be a better idea to have them be built into the culture of our industry. That companies who does not follow the rules get a bad reputation that clients would not want to do business with, just as you wouldn&#8217;t want to use a contractor who ignores fire safety.</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/fire-protection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Solution: &#8220;Temporary ID hasn&#8217;t been replaced on commit&#8221; when using Cayenne</title>
		<link>http://henko.net/imperfection/solution-temporary-id-hasnt-been-replaced-on-commit-when-using-cayenne/</link>
		<comments>http://henko.net/imperfection/solution-temporary-id-hasnt-been-replaced-on-commit-when-using-cayenne/#comments</comments>
		<pubDate>Mon, 24 Jan 2011 17:07:00 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Solution]]></category>

		<guid isPermaLink="false">http://henko.net/?p=945</guid>
		<description><![CDATA[Problem When committing changes to a Cayenne context, you get an exception like the following. org.apache.cayenne.CayenneRuntimeException: (v.3.0.1 Sep 06 2010 15:09:38) Temporary ID hasn't been replaced on commit Cause You are trying to commit an object for which Cayenne does not know how to generate a permanent id. This in turn typically happens when the [...]]]></description>
			<content:encoded><![CDATA[<h3>Problem</h3>

<p>When committing changes to a <a href="http://cayenne.apache.org/" title="Cayenne">Cayenne</a> context, you get an exception like the following.</p>

<pre><code>org.apache.cayenne.CayenneRuntimeException:
(v.3.0.1 Sep 06 2010 15:09:38)
Temporary ID hasn't been replaced on commit
</code></pre>

<h3>Cause</h3>

<p>You are trying to commit an object for which Cayenne does not know how to generate a permanent id. This in turn typically happens when the underlying table has no primary key defined.</p>

<h3>Solution</h3>

<p>To solve the problem, do one of the following.</p>

<ul>
<li>Add a primary key to the underlying table, either a surrogate key (new generated id column) or a natural key (combination of existing columns).</li>
<li>Set your own <code>ObjectID</code> on the object(s) in question using the <code>PersistentObject.setObjectID()</code> method.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/solution-temporary-id-hasnt-been-replaced-on-commit-when-using-cayenne/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Solution: &#8220;Error generating PK : entity not supported&#8221; when using Cayenne</title>
		<link>http://henko.net/imperfection/solution-error-generating-pk-entity-not-supported-when-using-cayenne/</link>
		<comments>http://henko.net/imperfection/solution-error-generating-pk-entity-not-supported-when-using-cayenne/#comments</comments>
		<pubDate>Thu, 13 Jan 2011 16:34:34 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Solution]]></category>

		<guid isPermaLink="false">http://henko.net/?p=925</guid>
		<description><![CDATA[Problem When committing changes to a Cayenne context, you get an exception like the following. org.apache.cayenne.CayenneRuntimeException: (v.3.0.1 Sep 06 2010 15:09:38) Error generating PK : entity not supported: SOME_TABLE Cause A column that is part of the primary key of SOME_TABLE has no value. Therefore Cayenne tries to generate one, but does not know how [...]]]></description>
			<content:encoded><![CDATA[<h3>Problem</h3>

<p>When committing changes to a <a href="http://cayenne.apache.org/" title="Cayenne">Cayenne</a> context, you get an exception like the following.</p>

<pre><code>org.apache.cayenne.CayenneRuntimeException:
(v.3.0.1 Sep 06 2010 15:09:38)
Error generating PK : entity not supported: SOME_TABLE
</code></pre>

<h3>Cause</h3>

<p>A column that is part of the primary key of <code>SOME_TABLE</code> has no value. Therefore Cayenne tries to generate one, but does not know how to.</p>

<h3>Solution</h3>

<p>To solve the problem, do one of the following.</p>

<ul>
<li>If the value is supposed to be auto-generated, tell Cayenne how to generate the value.</li>
<li>If it is not supposed to be generated, provide a value before committing changes in the context.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/solution-error-generating-pk-entity-not-supported-when-using-cayenne/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Two kinds of interfaces</title>
		<link>http://henko.net/imperfection/two-kinds-of-interfaces/</link>
		<comments>http://henko.net/imperfection/two-kinds-of-interfaces/#comments</comments>
		<pubDate>Tue, 23 Nov 2010 08:00:35 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Implementation]]></category>

		<guid isPermaLink="false">http://henko.net/?p=910</guid>
		<description><![CDATA[An interface is a point of interaction between two systems and they are used extensively within the Java world. While the mechanics of interfaces always are the same, the semantics may differ. There are (at least) two rather distinct types of uses for interfaces in Java. One type of interface, which we might call separation [...]]]></description>
			<content:encoded><![CDATA[<p>An interface is a point of interaction between two systems and they are used extensively within the Java world. While the mechanics of interfaces always are the same, the semantics may differ. There are (at least) two rather distinct types of uses for interfaces in Java.</p>

<p>One type of interface, which we might call <em>separation interface</em>, aims to separate different components. In this case, a component only exposes interfaces for its functionality but not the actual classes to make sure that clients aren&#8217;t too tightly coupled with the implementation. In this scenario, there is typically ever only a single implementation of the interface and both the interface and the implementation have the same author(s). Whenever you see a <code>Interface</code>/<code>InterfaceImpl</code> pair, you are most likely looking a this kind of interface use. This pattern is considered a best practice between components and systems, but rarely useful inside cohesive modules where classes naturally are more tightly coupled.</p>

<p>The other type of interface, let&#8217;s call it <em>extension interface</em>, is intended to represent an <em>ability</em> than an object can have. Here, multiple implementations of the interface exists and the client can choose the implementation that best suites his or her needs. A component often defines an interface on which it depends in order to allow implementations to be added at a later time. Often, the author of the interface is not even the same as the ones who create the implementations. This type of interfaces (together with regular inheritance) are the foundation of polymorphism. <code>Iterable</code> or <code>Comparator</code> are typical examples.</p>

<p>Quite possibly, there are other types of interfaces as well. Feel free to comment on the issue. <img src='http://henko.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/two-kinds-of-interfaces/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Real world refactoring</title>
		<link>http://henko.net/imperfection/real-world-refactoring/</link>
		<comments>http://henko.net/imperfection/real-world-refactoring/#comments</comments>
		<pubDate>Wed, 16 Jun 2010 20:32:13 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Principles]]></category>

		<guid isPermaLink="false">http://henko.net/?p=897</guid>
		<description><![CDATA[The tram stop next to my apartment has been completely rebuilt during the last few weeks. They removed every part of the old one, including the actual little shelter, the fence, the curb, the pavement &#8212; everything. A pretty major change as far as tram stop remakes go. It could be seen as a clear [...]]]></description>
			<content:encoded><![CDATA[<p>The tram stop next to my apartment has been completely rebuilt during the last few weeks. They removed every part of the old one, including the actual little shelter, the fence, the curb, the pavement &#8212; everything. A pretty major change as far as tram stop remakes go. It could be seen as a clear improvement. Tram Stop 2.0, if you wish.</p>

<p><img src="http://henko.net/wp-content/uploads/2010/06/crossing-300x225.jpg" alt="Rebuilding a crossing" title="Rebuilding a crossing" width="300" height="225" class="alignright size-medium wp-image-899" /></p>

<p>They also created a new pedestrian crossing next to the tram stop. And there was one thing about it that I noticed. One side of the crossing was connected to the tram stop and the curb there was just rebuilt. The other side of the street had a perfectly fine curb, and it would have been no problems to just paint lines on the street and be done with the crossing. But they didn&#8217;t.</p>

<p>Instead, they ripped up the street, curb and part of the sidewalk on that side too. Why? The reason is that they wanted to improve that side of the crossing too. They&#8217;re making the sidewalk about half a meter wider and thereby narrowing the street. That makes it a little bit clearer that it is a crossing and therefore makes the crossing safer. They&#8217;ll lower the curb for a meter or so which makes crossing by bike or wheel-chair easier. That&#8217;s about it, as far as I know.</p>

<p>While arguably better, it didn&#8217;t really enable anything that wasn&#8217;t possible before. And it did cost money. Money that could have been spent elsewhere. And they had already spent a lot of money on rebuilding the tram stop. So why did they do it? I&#8217;m not sure, but I think whatever the reasons were, the same reasons could be used to motivate refactoring of software.</p>

<p>(Alright, that was possibly a crappy metaphor&#8230; but it&#8217;s my blog, and I&#8217;ll post what I want. <img src='http://henko.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> )</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/real-world-refactoring/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Freakoversion</title>
		<link>http://henko.net/imperfection/freakoversion/</link>
		<comments>http://henko.net/imperfection/freakoversion/#comments</comments>
		<pubDate>Sun, 23 May 2010 20:42:26 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Learning]]></category>

		<guid isPermaLink="false">http://henko.net/?p=885</guid>
		<description><![CDATA[In order to become better at selling &#8220;doing the right thing&#8221; to management, I think we need hard evidence. Therefore, I&#8217;m very curious what would happen if you put a really good researcher on digging through the version control system for your product. Combined with bug trackers, continuous integration systems, and other related systems, I [...]]]></description>
			<content:encoded><![CDATA[<p>In order to become <a href="http://henko.net/imperfection/to-become-better-salesmen/" title="To become better salesmen">better at selling</a> &#8220;doing the right thing&#8221; to management, I think we need hard evidence. Therefore, I&#8217;m very curious what would happen if you put a really good researcher on digging through the version control system for your product. Combined with bug trackers, continuous integration systems, and other related systems, I think it is a virtual goldmine.</p>

<p>You can finally get number of how much that &#8220;technical debt&#8221; really is. How much an average bug cost? How long does it on average take until a bug is discovered? Until it is fixed? How much did that quick and dirty patch a year ago really cost? Add to that all the technical value you could get out of such an analysis. What modules/classes have had the most bugs, historically? What classes are unstable and has to be changed all the time?</p>

<p>Think of it as a <a href="http://www.amazon.com/gp/product/0061234001?ie=UTF8&amp;tag=henkonet-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0061234001" title="Freakonomics">Freakonomics</a> of version control.</p>

<div style="text-align: center"><img src="http://henko.net/wp-content/uploads/2010/05/freakoversion.jpg" alt="Freakonomics + Subversion  = ?" title="Freakoversion" width="409" height="100" class="aligncenter size-full wp-image-886" /></div>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/freakoversion/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Multitasking doesn&#8217;t work, but&#8230;</title>
		<link>http://henko.net/imperfection/multitasking-doesnt-work-but/</link>
		<comments>http://henko.net/imperfection/multitasking-doesnt-work-but/#comments</comments>
		<pubDate>Thu, 13 May 2010 08:15:51 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Principles]]></category>

		<guid isPermaLink="false">http://henko.net/?p=866</guid>
		<description><![CDATA[Great quote from Kent Beck at SDC2010. Multitasking doesn&#8217;t work, but it would be so nice if it did that we try anyway. That&#8217;s about the best summary of (human) multitasking I&#8217;ve heard. This picture is pretty good too, though.]]></description>
			<content:encoded><![CDATA[<p>Great quote from Kent Beck at <a href="http://www.scandevconf.se/2010/" title="SDC2010">SDC2010</a>.</p>

<blockquote>
  <p>Multitasking doesn&#8217;t work,<br />
  but it would be so nice if it did<br />
  that we try anyway.</p>
</blockquote>

<p>That&#8217;s about the best summary of (human) multitasking I&#8217;ve heard.</p>

<p>This picture is pretty good too, though.</p>

<div style="text-align: center"><a href="http://henko.net/wp-content/uploads/2010/05/62139938_94b4e251cd1.jpg"><img src="http://henko.net/wp-content/uploads/2010/05/62139938_94b4e251cd1-300x225.jpg" alt="The Myth of Multitasking, by Tim Morgan" title="The Myth of Multitasking, by Tim Morgan" width="300" height="225" /></a></div>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/multitasking-doesnt-work-but/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Delegate or fire</title>
		<link>http://henko.net/imperfection/delegate-or-fire/</link>
		<comments>http://henko.net/imperfection/delegate-or-fire/#comments</comments>
		<pubDate>Mon, 10 May 2010 17:35:59 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Management]]></category>

		<guid isPermaLink="false">http://henko.net/?p=863</guid>
		<description><![CDATA[You can&#8217;t lead a big company at a detailed level. You simply don&#8217;t have enough time to grasp all details. You are just human, and your brain cannot handle the complex lives of all people in your organization. But if you&#8217;re the CEO, you still have the responsibility for all of these people. &#8220;With great [...]]]></description>
			<content:encoded><![CDATA[<p>You can&#8217;t lead a big company at a detailed level. You simply don&#8217;t have enough time to grasp all details. You are just human, and your brain cannot handle the complex lives of all people in your organization. But if you&#8217;re the CEO, you still have the responsibility for all of these people.</p>

<div style="text-align: center"><img src="http://henko.net/wp-content/uploads/2010/05/spiderman1.jpg" alt="Spider-Man" title="Spider-Man" width="300" height="411" class="size-full wp-image-870" /><br/>
<em>&#8220;With great power comes great responsibility&#8221;</em></div>

<p>So, if you can&#8217;t do it all yourself, you&#8217;re forced to either:</p>

<ol>
<li>generalize and set broad rules, or</li>
<li>delegate control and responsibility.</li>
</ol>

<p>The first one is tempting, as you can control people and ensure that they don&#8217;t do anything which they should not. The problem is, if you do this, you lower the &#8220;consciousness&#8221; of yourself and your organization. According to the Dreyfus model of skill acquisition, not taking context into consideration is one of the traits of the novice. And that is just what&#8217;s happening here.</p>

<p>On the other hand, if you delegate control to the people who actually deal with the everyday problems, each person can adjust their decisions to the situation at hand. If you don&#8217;t trust the people to handle that situation, either learn to trust them or don&#8217;t hire them in the first place!</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/delegate-or-fire/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Local rules give global results</title>
		<link>http://henko.net/imperfection/local-rules-give-global-results/</link>
		<comments>http://henko.net/imperfection/local-rules-give-global-results/#comments</comments>
		<pubDate>Thu, 06 May 2010 13:53:47 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Principles]]></category>
		<category><![CDATA[Process]]></category>

		<guid isPermaLink="false">http://henko.net/?p=856</guid>
		<description><![CDATA[Reading Richard Dawkins&#8217; book The Greatest Show on Earth, I got inspired by his description about genes. He talks about how genes are not the blueprints of the body, but rather a recipe for the body. In other words, the genes do not contain a complete (or even partial) description of the final result, but [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://henko.net/wp-content/uploads/2010/05/2576765496_18e063d8411.jpg"><img src="http://henko.net/wp-content/uploads/2010/05/2576765496_18e063d8411-204x300.jpg" alt="DNA and twisty green things" title="DNA and twisty green things, by Ethan Hein" width="204" height="300" class="alignright size-medium wp-image-860" /></a>Reading Richard Dawkins&#8217; book <a href="http://www.amazon.com/gp/product/1416594787?ie=UTF8&amp;tag=henkonet-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1416594787" title="The Greatest Show on Earth">The Greatest Show on Earth</a>, I got inspired by his description about genes. He talks about how genes are not the blueprints of the body, but rather a recipe for the body. In other words, the genes do not contain a complete (or even partial) description of the final result, but rather contain various instructions for how to create the body. Each gene contributes only with extremely low level instructions, but these instructions combine in almost incomprehensible ways to form our enormously complex bodies.</p>

<p>I very much liked the idea, that a set of very low level instructions, carefully chosen and carefully followed, could create something so complex and beautiful. Jurgen Appelo has expressed similar ideas regarding <a href="http://www.noop.nl/complexity/" title="complexity theory">complexity theory</a>, and how ant hills or bee hives are complex structures created without a master plan through individual bees&#8217; actions. Yet another connection would be local search algorithms, which find maxima in a landscape through looking only at their immediate surroundings.</p>

<p>Next, my brain started linking these ideas to software development. For example, Test-Driven Development. It is in its essence, a set of very simple rules. Write a test, write needed implementation, refactor. These three simple (at least in theory) steps is all that there is to it, when properly adhered to, it can give great results. Designs tend to be much more easy to use, contain less bloat, be more testable (duh!), and so on. Refactorings are another great example. A set of rules or recipes for how to transform a code base into a better code base.</p>

<p>Obviously, choosing the right set of rules to follow is the important part, as a bad set of rules will lead to crappy code just as an unwanted mutation in a human body may lead to e.g. cancer. But I guess the point I was trying to make is that there is immense power in follow simple rules.</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/local-rules-give-global-results/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>To become better salesmen</title>
		<link>http://henko.net/imperfection/to-become-better-salesmen/</link>
		<comments>http://henko.net/imperfection/to-become-better-salesmen/#comments</comments>
		<pubDate>Wed, 28 Apr 2010 16:59:57 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Management]]></category>

		<guid isPermaLink="false">http://henko.net/?p=836</guid>
		<description><![CDATA[At a lunch recently, I talked with some architects/developers who were a bit concerned about a decision made by the managers and (powerpoint-)architects at their company. The company had decided to go with a middle-ware/database solution from a vendor which I will allow to remain anonymous (let&#8217;s just say it&#8217;s a very large company who [...]]]></description>
			<content:encoded><![CDATA[<p>At a lunch recently, I talked with some architects/developers who were a bit concerned about a decision made by the managers and (powerpoint-)architects at their company. The company had decided to go with a middle-ware/database solution from a vendor which I will allow to remain anonymous (let&#8217;s just say it&#8217;s a very large company who recently acquired another company which develops a very common programming language).</p>

<p><a href="http://www.flickr.com/photos/amagill/3367543296/"><img src="http://henko.net/wp-content/uploads/2010/04/3367543296_1470ef5247_b1-e1272473369540.jpg" alt="A roll of bills." title="Money, by AMagill" width="249" height="242" class="alignright size-full wp-image-838" /></a>My lunch mates felt that the decision to go with this vendor was not necessarily in the best interest of their company and the technical platform they were developing. Instead, they felt that there were other ways forward which would be better. Some of these ideas included common-sense things such as choosing quality over quantity, working on getting the current code into decent shape, and so on. They also felt that they had been trying to get this message across to management.</p>

<p>Why then did these suggestions not catch on with management, and why did the vendor&#8217;s salesmen manage to convince company management to choose them? I don&#8217;t have the answers, but I will not let that stop me from sharing my thoughts. <img src='http://henko.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  I also don&#8217;t have all the details on this specific case, so I&#8217;ll be a bit more general.</p>

<p>I think that developers and architects have many good ideas on how to build systems, but that we don&#8217;t always do a great job of describing these ideas to business people. I think we also sometimes adopt ideas on the basis of liking them, rather than because the idea has been proven over and over again.</p>

<div style="margin-left: 2em;">

<p>All in all, I think we need to become better salesmen &#8212; to find better ways to sell our ideas to management. We need to start using the arguments that appeal to them, getting case studies which &#8220;prove&#8221; our ideas, and creating relevant numbers and charts. We need to tell the business people how much money they can actually save by doing whatever-it-is-we-want-them-to-do. Make it the &#8220;safe alternative&#8221; to choose our idea. I can only imagine that is what the vendor&#8217;s salesmen in the example above did.</p>

</div>

<p>Failing that, we need to get a very well-paid management consultant to tell them the same thing. Because in the world of business, the greatness of an idea is proportional to the hourly rate of the person presenting it. <img src='http://henko.net/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/to-become-better-salesmen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t peek</title>
		<link>http://henko.net/imperfection/dont-peek/</link>
		<comments>http://henko.net/imperfection/dont-peek/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 08:00:29 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Imperfection]]></category>

		<guid isPermaLink="false">http://henko.net/?p=815</guid>
		<description><![CDATA[When I talked to Michael Feathers about why constraints are good, he also mentioned an example of where he thought things were going wrong. Some people who use test-driven development, also use tools that allow the to peek into classes and read private variables. That is an efficient way to ensure that some method altered [...]]]></description>
			<content:encoded><![CDATA[<p>When I talked to Michael Feathers about why <a href="http://henko.net/imperfection/constraints-are-good/" title="Constraints are good">constraints are good</a>, he also mentioned an example of where he thought things were going wrong.</p>

<p>Some people who use test-driven development, also use tools that allow the to peek into classes and read private variables. That is an efficient way to ensure that some method altered the state of the object in the expected way.</p>

<p>However, as Michael pointed out, by doing so they miss the point of test-driven development. Test-driven development adds constraints. It does that in order to force developers to design their code better. (TDD is about design, not testing &#8212; remember?) By peeking into classes, one effectively removes one constraint added by TDD, and thereby removing much of the benefit of TDD.</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/dont-peek/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Consider yourself warned, bloggers</title>
		<link>http://henko.net/imperfection/consider-yourself-warned-bloggers/</link>
		<comments>http://henko.net/imperfection/consider-yourself-warned-bloggers/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 06:04:54 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>

		<guid isPermaLink="false">http://henko.net/?p=828</guid>
		<description><![CDATA[This started out as a comment on a Michael Hyatt blog post on the use of social media for marketing vs relationship building. Michael responded to my comment saying, Wow. That a blog post in itself—and a great warning to all us who are tempted to “go pro.” So, consider yourselves warned, everyone. (Now, that [...]]]></description>
			<content:encoded><![CDATA[<p>This started out as a comment on a Michael Hyatt blog post on the use of <a href="http://michaelhyatt.com/2010/04/the-20-to-1-rule.html" title="social media for marketing vs relationship building">social media for marketing vs relationship building</a>. Michael responded to my comment saying,</p>

<blockquote>
  <p>Wow. That a blog post in itself—and a great warning to all us who are tempted to “go pro.”</p>
</blockquote>

<p>So, consider yourselves warned, everyone. (Now, that would have worked way better if I actually had a lot of subscribers&#8230;)</p>

<p>His post made me think of how many bloggers that become popular behave. At first, they write good high-quality material, the kind of material that people want to read, and they get a lot of subscribers. As they become famous, they start doing talking engagements, they write books, they quit their jobs and starts making a livings as bloggers. And before you know it, most of what they post are “spam” such as info about their upcoming talk, book or business deal. And the posts which made me interested in the first place become rarer.</p>

<p>Now, that is only logical. They wrote about the subject in the first place because they were interested and worked with it everyday. When their life situation changes, and they become pro-bloggers, naturally their interests and day-to-day activities change as well (to some degree, at least). So they still write about what they are interested in and work with everyday. Same, same, but different.</p>

<p>Another commenter mentioned that he only followed people on Twitter with a moderate amount of followers and not the ones with millions, because the latter typically just sent broadcast-style marketing messages. Maybe that’s an expression of the same thing?</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/consider-yourself-warned-bloggers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Constraints are good</title>
		<link>http://henko.net/imperfection/constraints-are-good/</link>
		<comments>http://henko.net/imperfection/constraints-are-good/#comments</comments>
		<pubDate>Mon, 19 Apr 2010 20:05:48 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Principles]]></category>
		<category><![CDATA[Process]]></category>

		<guid isPermaLink="false">http://henko.net/?p=814</guid>
		<description><![CDATA[In a conversation with Michael Feathers at SDC2010, he mentioned something which I found very interesting. It was a very simple statement. Constraints are good. To me, that statement sounded rather odd. Constraints is a negative word to me, so intuitively I want to remove constraints. Thus, I asked him to clarify. And here&#8217;s what [...]]]></description>
			<content:encoded><![CDATA[<p>In a conversation with <a href="http://www.michaelfeathers.com/" title="Michael Feathers">Michael Feathers</a> at <a href="http://www.scandevconf.se/" title="SDC2010">SDC2010</a>, he mentioned something which I found very interesting. It was a very simple statement.</p>

<blockquote>
  <p>Constraints are good.</p>
</blockquote>

<p>To me, that statement sounded rather odd. Constraints is a negative word to me, so intuitively I want to remove constraints. Thus, I asked him to clarify. And here&#8217;s what he said (or rather, my interpretation of it).</p>

<p><a href="http://henko.net/wp-content/uploads/2010/04/3135942946_6013353f46_b1.jpg"><img src="http://henko.net/wp-content/uploads/2010/04/3135942946_6013353f46_b1-200x300.jpg" alt="A night shot of a high way." title="The first trail and star, by jonmartin" width="200" height="300" class="alignright size-medium wp-image-820" /></a>A big advantage of software development is that we can build virtually anything. However, that same fact also represents one of the biggest problems. &#8220;Anything&#8221; includes all the great things that we envision, but also all the crappy things which we typically produce. <img src='http://henko.net/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </p>

<p>Since the possibilities are endless, in theory nothing prevents us from creating something truly great. But &#8212; and here&#8217;s the thing &#8212; by adding wisely chosen constraints, we can eliminate some of the undesirable outcomes. That means, that even if we screw up a bit, we&#8217;re more likely to create something which is at least not half-bad because we&#8217;ve eliminated the really bad outcomes. If we stay within the constraints, that is&#8230;</p>

<p>Another way to see it is that just as any society needs some laws and rules in order to function smoothly, a software development team does too. Whereas an example in the first case may be &#8220;do not kill&#8221;, an example in the second could be &#8220;do not commit code which breaks the build&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/constraints-are-good/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Estimation Rule of Thumb</title>
		<link>http://henko.net/imperfection/estimation-rule-of-thumb/</link>
		<comments>http://henko.net/imperfection/estimation-rule-of-thumb/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 07:00:57 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Planning]]></category>
		<category><![CDATA[Process]]></category>

		<guid isPermaLink="false">http://henko.net/?p=652</guid>
		<description><![CDATA[An time estimation rule of thumb for software development in startups. (Somewhat tongue-in-cheek.) The rule Make a good estimate of the work (in any time unit). Multiply that number by itself in months plus one. What you get is a reasonable estimate for release date (in the original time unit). Examples Some examples: Work estimated [...]]]></description>
			<content:encoded><![CDATA[<p>An time estimation rule of thumb for software development in startups. (Somewhat tongue-in-cheek.)</p>

<h3>The rule</h3>

<ul>
<li>Make a good estimate of the work (in any time unit).</li>
<li>Multiply that number by itself in months plus one.</li>
<li>What you get is a reasonable estimate for release date (in the original time unit).</li>
</ul>

<h3>Examples</h3>

<p>Some examples:</p>

<ul>
<li>Work estimated to one week will take one week.</li>
<li>Work estimated to two weeks you can expect to be ready in close to a month.</li>
<li>Work expected to take two months weeks will take about six months.</li>
<li>Anything estimated to half a year or more won&#8217;t be finished. The scope will be changed too much before the project is finished.</li>
</ul>

<p>While not perfectly scientific, it is actually more or less empirically derived from my own company&#8217;s history.</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/estimation-rule-of-thumb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Bus Factor</title>
		<link>http://henko.net/imperfection/the-bus-factor/</link>
		<comments>http://henko.net/imperfection/the-bus-factor/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 07:00:54 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Process]]></category>

		<guid isPermaLink="false">http://henko.net/?p=731</guid>
		<description><![CDATA[The Bus Factor, as defined by Wikipedia: A software project&#8217;s bus factor is a measurement of concentration of information in a single person, or very few people. The bus factor is the total number of key developers who would if incapacitated, as by getting hit by a bus, send the project into such disarray that [...]]]></description>
			<content:encoded><![CDATA[<p>The <em>Bus Factor</em>, as defined by Wikipedia:</p>

<blockquote>
  <p>A software project&#8217;s bus factor is a measurement of concentration of information in a single person, or very few people. The bus factor is the total number of key developers who would if incapacitated, as by getting hit by a bus, send the project into such disarray that it would not be able to proceed.</p>
</blockquote>

<p>How would your company do without you if you became sick for a month? Six months? Quit completely?
Or put the other way, if you want to quit, can you get out without leaving a complete mess behind you?</p>

<p>If you&#8217;re an entrepreneur, this is even more important. Especially if you&#8217;re looking into one day selling your company. Nobody wants to buy a company which is worthless without the seller.</p>

<p>What is the bus factor on your project or company?</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/the-bus-factor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exception Handling Policy &#8211; Logging Exceptions</title>
		<link>http://henko.net/imperfection/exception-handling-policy-logging-exceptions/</link>
		<comments>http://henko.net/imperfection/exception-handling-policy-logging-exceptions/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 06:00:32 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Implementation]]></category>

		<guid isPermaLink="false">http://henko.net/?p=667</guid>
		<description><![CDATA[This is the last part of my series on exception handling which will deal with logging exceptions and other noteworthy events. A summary of the series: Throwing Exceptions Using Assertions Catching Exceptions Logging Exceptions (this one) General guidelines We&#8217;ll start off with a few general guidelines for logging. Always include the exception message in the [...]]]></description>
			<content:encoded><![CDATA[<p>This is the last part of my series on exception handling which will deal with logging exceptions and other noteworthy events.</p>

<p>A summary of the series:</p>

<ol>
<li><a href="http://henko.net/imperfection/exception-handling-policy-throwing-exception/" title="Exception Handling Policy - Throwing Exceptions">Throwing Exceptions</a></li>
<li><a href="http://henko.net/imperfection/exception-handling-policy-using-assertions/" title="Exception Handling Policy - Using Assertions">Using Assertions</a></li>
<li><a href="http://henko.net/imperfection/exception-handling-policy-catching-exceptions/" title="Exception Handling Policy - Catching Exceptions">Catching Exceptions</a></li>
<li><strong>Logging Exceptions</strong> (this one)</li>
</ol>

<h3>General guidelines</h3>

<p>We&#8217;ll start off with a few general guidelines for logging.</p>

<h4>Always include the exception message in the log</h4>

<div style="margin-left: 2em;">

<p>Make sure you know what actually went wrong, not just that something went wrong.</p>

</div>

<h4>Never lose a stack trace!</h4>

<div style="margin-left: 2em;">

<p>And not only do you want to know what went wrong, you want to know where! An exception without a stack trace is like a person with no memory.</p>

</div>

<h3>Debug levels</h3>

<p>A summary of the typical severity levels used when logging and guidelines on when to use them.</p>

<h4>Info, Debug, or Trace</h4>

<div style="margin-left: 2em;">

<p>Informational messages that highlight the progress of the application at various levels of granularity.</p>

<p>Use logging levels <code>INFO</code>, <code>DEBUG</code>, <code>TRACE</code>.</p>

</div>

<h4>Warnings</h4>

<div style="margin-left: 2em;">

<p>Potentially harmful situations, such as invalid requests which could be some form of attack. It could also be a client (developer) in need of help.</p>

<p>Use logging level <code>WARN</code>.</p>

</div>

<h4>Errors</h4>

<div style="margin-left: 2em;">

<p>Error events that might still allow the application to continue running. For example, uncaught exceptions in your &#8220;catch all&#8221; exception handler.</p>

<p>Use logging level <code>ERROR</code>.</p>

</div>

<h4>Fatal errors</h4>

<div style="margin-left: 2em;">

<p>Very severe error events that will presumably lead the application to abort. Examples include <a href="http://henko.net/imperfection/exception-handling-policy-using-assertions/" title="Exception Handling Policy - Using Assertions">all fired assertions</a>. They should not happen &#8212; they are bugs! Also, all &#8220;errors&#8221; in the Java sense (out of memory etc).</p>

<p>Use logging level <code>FATAL</code>.</p>

</div>

<p>I hope this quick four part series on sensible exception handling has been interesting. Be sure to read the previous installments (see summary at top) and please feel free to add your comments below! Any and all comments are very welcome!</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/exception-handling-policy-logging-exceptions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exception Handling Policy &#8211; Catching Exceptions</title>
		<link>http://henko.net/imperfection/exception-handling-policy-catching-exceptions/</link>
		<comments>http://henko.net/imperfection/exception-handling-policy-catching-exceptions/#comments</comments>
		<pubDate>Mon, 06 Jul 2009 20:17:06 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Implementation]]></category>

		<guid isPermaLink="false">http://henko.net/?p=666</guid>
		<description><![CDATA[This is the third installment in my series on sensible exception handling and will cover when and how to catch exceptions. To quickly summarize, the series looks as follows: Throwing Exceptions Using Assertions Catching Exceptions (this one) Logging Exceptions The information in this post is divided into two parts: when to catch, and how to [...]]]></description>
			<content:encoded><![CDATA[<p>This is the third installment in my series on sensible exception handling and will cover when and how to catch exceptions.</p>

<p>To quickly summarize, the series looks as follows:</p>

<ol>
<li><a href="http://henko.net/imperfection/exception-handling-policy-throwing-exception/" title="Exception Handling Policy - Throwing Exceptions">Throwing Exceptions</a></li>
<li><a href="http://henko.net/imperfection/exception-handling-policy-using-assertions/" title="Exception Handling Policy - Using Assertions">Using Assertions</a></li>
<li><strong>Catching Exceptions</strong> (this one)</li>
<li><a href="http://henko.net/imperfection/exception-handling-policy-logging-exceptions/" title="Exception Handling Policy - Logging Exceptions">Logging Exceptions</a></li>
</ol>

<p>The information in this post is divided into two parts: when to catch, and how to catch.</p>

<h3>When to catch</h3>

<p>Here are some guidelines on when to catch exceptions and when to let them propagate up through the call stack.</p>

<h4>Catch only exceptions you know how to handle, and be specific</h4>

<div style="margin-left: 2em;">

<p>If you don&#8217;t know ahead of time what the exception is going to be, you don&#8217;t know how to handle it, and you should send it up the stack.</p>

<p>Catching top-level exception means trying to deal with the really exceptional case, which by definition you can&#8217;t plan for.</p>

</div>

<h4>Provide a general catch-all</h4>

<div style="margin-left: 2em;">

<p>Ensure that all exceptions are caught and reported at some point
This is especially important in a multi-threaded environment, where a thread&#8217;s death may otherwise go unnoticed.</p>

<p>In languages which also have other error mechanisms, such as PHP, make sure that warnings, errors, fatals etc don&#8217;t go unnoticed.</p>

</div>

<h3>How to catch</h3>

<p>When you catch an exception, make sure to do it the right way.</p>

<h4>Do not suppress or ignore exceptions</h4>

<div style="margin-left: 2em;">

<p>NEVER! EVER! Don&#8217;t even while testing. It is not only undisciplined, but you <em>will</em> forget to &#8220;deal with it later&#8221;.</p>

</div>

<h4>Always clean up after yourself</h4>

<div style="margin-left: 2em;">

<p>Finally is usually recommended to guarantee resource cleanup, however you should yourself guarantee that finally never fails. In general, ensure finally never eats up your original exception.</p>

</div>

<h4>Declarative exception handling</h4>

<div style="margin-left: 2em;">

<p>Handling exceptions is an dynamic concern, the right way to handle an exception can easily change. Therefore, use a flexible framework to manage this.</p>

<p>For example Struts allows user defined <code>ExceptionHandlers</code> to be associated on a local or global scope using configuration instead of code. In other words, responses to exceptions should not only based on type but also on context in where they are called.</p>

</div>

<p>Next week, the final episode of the series will be published, so be sure to check back. If you have any comments, please provide them below!</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/exception-handling-policy-catching-exceptions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exception Handling Policy &#8211; Using Assertions</title>
		<link>http://henko.net/imperfection/exception-handling-policy-using-assertions/</link>
		<comments>http://henko.net/imperfection/exception-handling-policy-using-assertions/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 06:00:18 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Implementation]]></category>

		<guid isPermaLink="false">http://henko.net/?p=700</guid>
		<description><![CDATA[This is the second part in a series of four on exception handling and it focuses on an area related to exceptions &#8212; assertions. A quick summary of posts in this series: Throwing Exceptions Using Assertions (this one) Catching Exceptions Logging Exceptions Guidelines for assertions An assertion is code that&#8217;s used during development that allows [...]]]></description>
			<content:encoded><![CDATA[<p>This is the second part in a series of four on exception handling and it focuses on an area related to exceptions &#8212; assertions.</p>

<p>A quick summary of posts in this series:</p>

<ol>
<li><a href="http://henko.net/imperfection/exception-handling-policy-throwing-exception/" title="Exception Handling Policy - Throwing Exceptions">Throwing Exceptions</a></li>
<li><strong>Using Assertions</strong> (this one)</li>
<li><a href="http://henko.net/imperfection/exception-handling-policy-catching-exceptions/" title="Exception Handling Policy - Catching Exceptions">Catching Exceptions</a></li>
<li><a href="http://henko.net/imperfection/exception-handling-policy-logging-exceptions/" title="Exception Handling Policy - Logging Exceptions">Logging Exceptions</a></li>
</ol>

<h3>Guidelines for assertions</h3>

<p>An <a href="http://en.wikipedia.org/wiki/Assertion_(computing)" title="assertion">assertion</a> is code that&#8217;s used during development that allows a program to check itself as it runs. They are used much in the same spirit as unit tests, but spread out in the actual program code. It is a statement placed to indicate that the developer thinks that some predicate is always true at that place.</p>

<h4>Use assertions for conditions that should never occur</h4>

<div style="margin-left: 2em;">

<p>If an assertion is fired for an anomalous condition, the corrective action is not merely to handle an error gracefully — the corrective action is to change the program&#8217;s source code, recompile, and release a new version of the software.</p>

<p>Use assertions to document and verify preconditions and postconditions.</p>

</div>

<h4>Use a barricades to distinguish between assertions and exceptions</h4>

<div style="margin-left: 2em;">

<p>Routines that are outside the barricade should use error handling because it isn&#8217;t safe to make any assumptions about the data. Routines inside the barricade should use assertions, because the data passed to them is supposed to be sanitized before it&#8217;s passed across the barricade. If one of the routines inside the barricade detects bad data, that&#8217;s an error in the program rather than an error in the data.</p>

</div>

<h4>Don&#8217;t put executable code into assertions.</h4>

<div style="margin-left: 2em;">

<p>Doing so raises the possibility that the compiler will eliminate the code when you turn off the assertions. Instead, only put boolean conditions with no side effects in your assertions.</p>

</div>

<h4>For highly robust code, assert and then handle the error any way</h4>

<div style="margin-left: 2em;">

<p>Better safe than sorry, they say.</p>

</div>

<h3>Assertions in Java</h3>

<p>For those unfamiliar with assertions, I&#8217;ll give a quick summary. Java provides the keyword <code><a href="http://java.sun.com/j2se/1.4.2/docs/guide/lang/assert.html" title="assert">assert</a></code> since version 1.4. It throws a <code>java.lang.AssertionError</code> when it fails, and has the following syntax:</p>

<pre><code>assert expression : "error message shown if expression is false";
</code></pre>

<p>Where <code>expression</code> is any boolean expression which should always be true at the point of the assertion. For example, this variable should always be greater than 0, or that collection should always be empty.</p>

<p>To enable assertions when running a program, use the Java VM <code>-ea</code> (or <code>-enableassertions</code>) switch. Assertions are always compiled in, but without this switch, the assertions are ignored by the virtual machine.</p>

<p>Tune in next week for guidelines for catching exceptions! And please do write any comments or questions you might have below.</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/exception-handling-policy-using-assertions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exception Handling Policy &#8211; Throwing Exceptions</title>
		<link>http://henko.net/imperfection/exception-handling-policy-throwing-exception/</link>
		<comments>http://henko.net/imperfection/exception-handling-policy-throwing-exception/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 12:06:23 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Implementation]]></category>

		<guid isPermaLink="false">http://henko.net/?p=662</guid>
		<description><![CDATA[This is the first post in a series of four on exception handling. The series will cover what I think is a good and sound strategy for handling exceptions and errors in your application. It is written with Java in mind, but is applicable to most languages which feature exceptions. This first issue will go through the art of throwing exceptions.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flickr.com/photos/mbiskoping/510673513/"><img src="http://henko.net/wp-content/uploads/2009/06/exception.jpg" alt="An exception" title="An exception (Copyright by [martin])" width="240" height="234" class="alignright size-full wp-image-695" /></a>This is the first post in a series of four on exception handling.</p>

<p>The series will cover what I think is a good and sound strategy for handling exceptions and errors in your application.</p>

<p>It is written with Java in mind, but is applicable to most languages which feature exceptions.</p>

<p>A quick summary of the coming posts:</p>

<ol>
<li><strong>Throwing Exceptions</strong> (this one)</li>
<li><a href="http://henko.net/imperfection/exception-handling-policy-using-assertions/" title="Exception Handling Policy - Using Assertions">Using Assertions</a></li>
<li><a href="http://henko.net/imperfection/exception-handling-policy-catching-exceptions/" title="Exception Handling Policy - Catching Exceptions">Catching Exceptions</a></li>
<li><a href="http://henko.net/imperfection/exception-handling-policy-logging-exceptions/" title="Exception Handling Policy - Logging Exceptions">Logging Exceptions</a></li>
</ol>

<p>Let&#8217;s get started!</p>

<h3>General</h3>

<p>First, we&#8217;ll go through some things which apply to all types of exceptions.</p>

<h4>Always preserve the stack trace</h4>

<div style="margin-left: 2em;">

<p>Make sure that the stack trace of a wrapped exception is captured and preserved. The single worse thing one can do after eating your exceptions is to to capture it but throw away all the essential details.</p>

<p>Be careful with distributed systems, as simplistic use of Java serialization requires the Exception classes be available in all tiers.</p>

<p>Also, pre JDK 1.4 Exceptions do not preserve the stacktrace.</p>

</div>

<h4>Never use exceptions for flow control</h4>

<div style="margin-left: 2em;">

<p>Exceptions are meant for exceptional events &#8211; when things go wrong. Don&#8217;t build your system based on that something goes wrong.</p>

<p>Also, exceptions are slow, so heavy use of them might lead to performance problems.</p>

</div>

<h4>Provide enough context</h4>

<div style="margin-left: 2em;">

<p>Include information and methods in the exception which help the client deal with the exception.</p>

<p>When defining a new exception don&#8217;t just add a new error message, provide enough context for a catcher to gracefully handle the exception. If an existing exception class doesn&#8217;t have essential context, create a custom one.</p>

</div>

<p>Next, we&#8217;ll discuss checked and unchecked exceptions, and when to use them.</p>

<h3>Checked exceptions</h3>

<p>A checked exception is a Java concept which means an exception which is specified in a method&#8217;s signature. It is a way for the designer to tell the client of a method what might go wrong, so that the client can prepare accordingly.</p>

<h4>Throw a checked exception if a method can&#8217;t fulfill it&#8217;s contract</h4>

<div style="margin-left: 2em;">

<p>Either that, or don&#8217;t promise things you cannot keep.</p>

</div>

<h4>Make your exceptions part of your contract</h4>

<div style="margin-left: 2em;">

<p>Throw an exception which is meaningful in terms of the method&#8217;s contract.</p>

<p>Declare unchecked exceptions in the throws clause &#8211; make it easy for programmers and the IDE to discover the RuntimeExceptions that may be thrown by your method.</p>

<p>Document exceptions in Javadoc.</p>

</div>

<h4>Never let implementation-specific exceptions escalate to the higher layers</h4>

<div style="margin-left: 2em;">

<p>If the client code cannot do anything about a implementation-specific checked exception, convert it to a unchecked exception.</p>

<p>If you are confident that the business layer can take some recovery action when the implementation-specific exception occurs, convert it into a more meaningful checked exception.</p>

</div>

<h3>Unchecked exceptions</h3>

<p>Unchecked exceptions are all other exceptions, which are &#8220;unforeseen&#8221;.</p>

<h4>Prefer unchecked exceptions for all programming errors</h4>

<div style="margin-left: 2em;">

<p>If method parameters are invalid or preconditions not met, throw a unchecked exception. A client shouldn&#8217;t add exception handling code for providing invalid parameters, it should provide valid parameters!</p>

<p>Unchecked exceptions have the benefit of not forcing the client API to explicitly deal with them. They propagate to where you want to catch them, or they go all the way out and get reported.</p>

</div>

<h4>If the client cannot do anything useful, then make the exception unchecked</h4>

<div style="margin-left: 2em;">

<p>No sense in forcing the client to handle an exception it does not know how to deal with.</p>

</div>

<p>Feel free to provide any comments or thoughts below, and check back in a week for the next episode!</p>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/exception-handling-policy-throwing-exception/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Yes, Programmers Should Be &#8220;Mathematically Inclined&#8221;</title>
		<link>http://henko.net/imperfection/yes-programmers-should-be-mathematically-inclined/</link>
		<comments>http://henko.net/imperfection/yes-programmers-should-be-mathematically-inclined/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 16:41:48 +0000</pubDate>
		<dc:creator>Henrik Jernevad</dc:creator>
				<category><![CDATA[Imperfection]]></category>
		<category><![CDATA[Learning]]></category>

		<guid isPermaLink="false">http://henko.net/?p=646</guid>
		<description><![CDATA[This post is a response to Jeff Atwood&#8217;s post/question on Should Competent Programmers be "Mathematically Inclined"?. I originally intended to just comment that piece, but the sheer amount of comments made me realize that no-one would actually read it anyway. So I might as well write a response in my own blog which about as [...]]]></description>
			<content:encoded><![CDATA[<p>This post is a response to Jeff Atwood&#8217;s post/question on <a href="http://www.codinghorror.com/blog/archives/001249.html" title="Should Competent Programmers be "Mathematically Inclined"?">Should Competent Programmers be "Mathematically Inclined"?</a>.</p>

<p>I originally intended to just comment that piece, but the sheer amount of comments made me realize that no-one would actually read it anyway. So I might as well write a response in my own blog which about as many will read but which makes me feel better. <img src='http://henko.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>

<p><a href="http://www.flickr.com/photos/origomi/58198837/"><img alt="" src="http://farm1.static.flickr.com/25/58198837_a18b8c23e7_m.jpg" title="Mathematically Inclined (Copyright 2005 by EricGjerde.)" class="alignright" width="240" height="230" /></a>I believe the answer is &#8220;yes&#8221;. I think that a competent programmer needs to be &#8220;mathematically inclined&#8221;. Not because the average programmer&#8217;s typical work includes much math such as applications in 3D, compression, and image manipulation. In those cases it is fairly obvious that a firm grasp of math is required. I believe the answer is &#8220;yes&#8221; because in my mind &#8220;mathematically inclined&#8221; also means &#8220;good at seeing patterns&#8221;, &#8220;good at identifying duplication&#8221;, &#8220;understands basic complexity theory&#8221;, or simply &#8220;good at groking thinks&#8221;. And while a good understanding of math in general is valuable, I think a solid understanding of discrete math and logic is invaluable.</p>

<p>Finally, I liked what the unnamed author mentioned in Jeff&#8217;s post wrote enough to reprint it here.</p>

<blockquote>
  <p>I run a small (4 people) web dev shop and I&#8217;m finding that younger coders haven&#8217;t had the pleasure of writing assembler or managing without library functions. I&#8217;ve always found strong math skills to be one of the most useful skills for coding, and when one has Google and a massive library of functions, one doesn&#8217;t have to be good at math to get things working, until it either breaks, has edge cases, or brings out OS or library bugs.</p>
  
  <p>Some quick examples: simplifying tricky equations to determine array indicies or memory offsets; trigonometry to help with physical calculations; mental hex/bin/dec conversion; logic equalities such as DeMorgan&#8217;s theorem.</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://henko.net/imperfection/yes-programmers-should-be-mathematically-inclined/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.946 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-04 14:08:08 -->

