<?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>Just wondering.... &#187; code review</title>
	<atom:link href="http://sworddance.com/blog/category/technical/code-review/feed/" rel="self" type="application/rss+xml" />
	<link>http://sworddance.com/blog</link>
	<description></description>
	<lastBuildDate>Tue, 17 Jan 2012 05:07:09 +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>Use Subclasses and alternative interface implementations to reduce &#8220;future&#8221; bugs</title>
		<link>http://sworddance.com/blog/2011/04/07/use-subclasses-and-alternative-interface-implementations-to-reduce-future-bugs/#utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=use-subclasses-and-alternative-interface-implementations-to-reduce-future-bugs</link>
		<comments>http://sworddance.com/blog/2011/04/07/use-subclasses-and-alternative-interface-implementations-to-reduce-future-bugs/#comments</comments>
		<pubDate>Thu, 07 Apr 2011 19:28:45 +0000</pubDate>
		<dc:creator>patrick</dc:creator>
				<category><![CDATA[code review]]></category>

		<guid isPermaLink="false">http://sworddance.com/blog/?p=939</guid>
		<description><![CDATA[One of the little-appreciated consequences of subclassing or alternative implementations of Java interfaces is to reduce or eliminate &#8220;future bugs&#8221;. &#8220;Future bugs&#8221; are bugs that are currently not wrong, but will cause problems in the future. Every conditional ( if, &#8230; <a href="http://sworddance.com/blog/2011/04/07/use-subclasses-and-alternative-interface-implementations-to-reduce-future-bugs/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One of the little-appreciated consequences of subclassing or alternative implementations of Java interfaces is to reduce or eliminate &#8220;future bugs&#8221;.</p>
<p>&#8220;Future bugs&#8221; are bugs that are currently not wrong, but will cause problems in the future. Every conditional ( <code>if</code>, <code>? :</code>, or <code>switch</code> ) is a &#8220;future bug&#8221;.</p>
<p>For example, in this simplistic example code, there are multiple checks for <code>this.enableLogging</code>. If new code is added then the developer has to constantly remember to check for the <code>this.enableLogging</code>.</p>
<p><code>
<pre>public class Foo {
    private final boolean enableLogging;
    public Foo(boolean enableLogging) {
        this.enableLogging = boolean enableLogging; }

    public void stuff1() {
         .....
         if ( this.enableLogging ) {
             Log.warning("here in stuff1");
         }

         .....
         if ( this.enableLogging ) {
             Log.debug("still here in stuff1");
         }
    }
    public void stuff2() {
         .....
         if ( this.enableLogging ) {
             Log.info("here in stuff2");
         }

         .....
         if ( this.enableLogging ) {
             Log.debug("still here in stuff2");
         }
    }
}</pre>
<p></code></p>
<p>Of course sane developers will say that this is silly code, follow the <a href="http://en.wikipedia.org/wiki/Don&apos;t_repeat_yourself" rel="nofollow">DRY principle</a> and have something like this:</p>
<p><code>
<pre>public class Foo {
    private final boolean enableLogging;
    public Foo(boolean enableLogging) { this.enableLogging = boolean enableLogging; }

    public void stuff1() {
         .....
        warning("here in stuff1");
        .....
        debug("still here in stuff1");
        ....
    }
    public void stuff2() {
         .....
         info("here in stuff2");
         .....
         debug("still here in stuff2");
    }
    private void warning(String message) {
        if (this.enableLogging) {
            Log.warning(message);
        }
    }
    private void info(String message) {
        if (this.enableLogging) {
            Log.info(message);
        }
    }
    private void debug(String message) {
        if (this.enableLogging) {
            Log.debug(message);
        }
    }
}</pre>
<p></code></p>
<p>This is good enough for this simplistic example. However, consider a more realistic case with complex conditionals:</p>
<p><code>
<pre>public class Foo {
    private final boolean enableCall;
    private final boolean enableEmail;
    public Foo(boolean enableCall, boolean enableEmail) {
        this.enableCall =  enableCall;
        this.enableEmail =  enableEmail; }

    public void stuff1() {
         .....
         if ( this.enableCall ||  this.enableEmail) {
             doThing1();
         } else if (this.enableEmail || this.bigCheck() ) {
             ... lots of stuff1 lines  .....
        } else {
             .. some different things here....
         }
    }
    public void stuff2() {
         .....
         if ( this.enableCall ||  !this.enableEmail ) {
             doThing1();
         } else if (this.enableEmail || this.bigCheck() ) {
             ... lots of stuff2 lines .....
        } else {
             .. some different things for stuff2() here....
         }
    }
    private void doThing1() { ... }
    private boolean bigCheck() { .... }
}
...
public class Bar() {
    ....
    Foo foo = new Foo(true, false);
    ....
    Foo foo1 = new Foo(false, true);
}
</pre>
<p></code></p>
<p>Do you see the bugs?</p>
<ol>
<li>Notice that in stuff2() the first conditional is different than the first conditional in stuff1(). Is this a bug? Who knows? ( Lets assume it is )</li>
<li>Because the only users of Foo set either enableCall or enableEmail, the only actual code paths through Foo.stuff1() and Foo.stuff2() result in calls to doThing1()</li>
</ol>
<p>A developer just inspecting Foo can find neither issue easily. </p>
<p>Subclassing/alternative interface implementations solve this problem. <em>The subclass created decides, at object creation, all the conditionals</em>.</p>
<p>So the above code becomes:<br />
<code>
<pre>public interface Foo {
    void stuff1();
    void stuff2();
}

//  this.enableCall ||  this.enableEmail case ( The original stuff2() check was wrong )
public class Foo1Impl() implements Foo {
    public void stuff1() { doThing1(); }
    public void stuff2() { doThing1(); }
    private void doThing1() { .... }
}

// !this.enableCall &#038;&#038; this.enableEmail case
public class Foo2Impl() implements Foo {
    public void stuff1() { if (bigCheck() ) { ... lots of stuff1 lines  ..... } }
    public void stuff2() { if (bigCheck() ) { ... lots of stuff2 lines  ..... } }
    private boolean bigCheck() { .... }
}
public class Foo3Impl() implements Foo {
    public void stuff1() {
          .. some different things for stuff1() here.... }
    public void stuff2() {
         .. some different things for stuff2() here.... }
}

public class Bar() {
    ....
    Foo foo = new Foo1Impl();
    ....
    Foo foo1 = new Foo1Impl();
}
</pre>
<p></code></p>
<p>Note the consequences of this division, </p>
<ol>
<li>doThing1() can only be called by a Foo1Impl.</li>
<li>bigCheck() is isolated to Foo2Impl</li>
<li>depending on bigCheck()&#8217;s implementation, bigCheck() may be could be called once to determine if Foo2Impl or Foo3Impl is created.</li>
<li>There is no question about the stuff2() check being correct or incorrect. ( the conditional no longer exists! )</li>
<li>And it is now obvious that only Foo1Impl&#8217;s code path is used. If this is a bug, the bug is now obvious. If not then the Foo2Impl and Foo3Impl code can be eliminated.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://sworddance.com/blog/2011/04/07/use-subclasses-and-alternative-interface-implementations-to-reduce-future-bugs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to do a redirect after POST</title>
		<link>http://sworddance.com/blog/2011/01/25/how-to-do-a-redirect-after-post/#utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-do-a-redirect-after-post</link>
		<comments>http://sworddance.com/blog/2011/01/25/how-to-do-a-redirect-after-post/#comments</comments>
		<pubDate>Tue, 25 Jan 2011 21:45:50 +0000</pubDate>
		<dc:creator>patrick</dc:creator>
				<category><![CDATA[code review]]></category>
		<category><![CDATA[technical]]></category>

		<guid isPermaLink="false">http://sworddance.com/blog/?p=817</guid>
		<description><![CDATA[Continuing an StackOverflow answer: Its a little non-obvious but: create a keyed-object in the user session. the value is a Request + java Future for the result return immediately with a client-side redirect. while the client-side redirect is being handled, &#8230; <a href="http://sworddance.com/blog/2011/01/25/how-to-do-a-redirect-after-post/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://stackoverflow.com/questions/1083357/do-you-always-redirect-after-post-if-yes-how-do-you-manage-it/1083645#1083645">Continuing an StackOverflow answer</a>:</p>
<p>Its a little non-obvious but:</p>
<ol>
<li>create a keyed-object in the user session.</li>
<li>the value is a Request + java Future for the result</li>
<li>return immediately with a client-side redirect.</li>
<li>while the client-side redirect is being handled, have a worker thread work on producing the answer.</li>
</ol>
<p>By the time the client browser completes the redirect, getting the new page&#8217;s images, etc&#8230; the results are waiting for the user.</p>
<p>The alternative is to make the user painfully aware of how long the database is taking.</p>
<p>*Security Update (2011 Jan 24 ) :*</p>
<p>The key is vulnerable to attack since it is part of the response to the client, so</p>
<ol>
<li>Generate a random key </li>
<li>Use user&#8217;s session id as a salt to create a SHA-1</li>
<li>Store both the random key and the SHA-1 in the database with (<RANDOMKEY>, <SHA-1>) as the primary key. (no separate indexing on just the RANDOMKEY.)</li>
<li>Use both RANDOMKEY and the SHA-1 as the db lookup.</li>
<li>Do not store the Session Id (avoid privacy issues with being able to corollate many entries to the same user)</li>
<li>Expire the results after 2-3 days. ( Allows a daily batch job to do the clean up and avoids creating problems for user sessions that are semi-long lasting )</li>
</ol>
<p>This method requires any hacker to know both the session id and the random key. </p>
<p>This approach may seem overkill, but a redirect-hardened mechanism can be used for situations like password resets.</p>
<p>A purely random result key is highly problematic because of the high (and untested) impact of any collisions.  I pick so strongly on this point because:</p>
<ol>
<li>the developer is lulled into complacency about the actual collision rate</li>
<li>the impact of a collisions is unknown and probably untested</li>
<li>when/if a problem shows up:
<ol>
<li>it will be in production</li>
<li>the problem will be intermittent</li>
<li>difficult to reproduce</li>
<li>be disguised as another issue</li>
<li>possibly cause data corruption</li>
<li>possibly result in private user data being exposed</li>
<li>difficult to retroactively correct.</li>
</ol>
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://sworddance.com/blog/2011/01/25/how-to-do-a-redirect-after-post/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code Review #8: When to comment</title>
		<link>http://sworddance.com/blog/2009/03/16/when-to-comment/#utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=when-to-comment</link>
		<comments>http://sworddance.com/blog/2009/03/16/when-to-comment/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 18:10:10 +0000</pubDate>
		<dc:creator>patrick</dc:creator>
				<category><![CDATA[code review]]></category>
		<category><![CDATA[management]]></category>

		<guid isPermaLink="false">http://www.sworddance.com/blog/?p=357</guid>
		<description><![CDATA[The last ? in a series of posts about commenting. See &#8220;the why&#8221;. See &#8220;not commenting is career threatening&#8221;. And the comment that started this off! This post should have really been the second one I wrote. The first post &#8230; <a href="http://sworddance.com/blog/2009/03/16/when-to-comment/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The last ? in a series of posts about commenting. See <a href="http://www.sworddance.com/blog/2009/03/04/code-review-7-comment-the-why-not-the-what/">&#8220;the why&#8221;</a>. See <a href="http://www.sworddance.com/blog/2009/03/04/not-commenting-code-is-dangerous-to-your-career/">&#8220;not commenting is career threatening&#8221;</a>. And <a href="http://www.sworddance.com/blog/2007/05/29/thoughts-on-how-to-evaluate-code/#comment-16341">the comment that started this off</a>!</p>
<p>This post should have really been the second one I wrote. The <a href="http://www.sworddance.com/blog/2007/05/29/thoughts-on-how-to-evaluate-code">first post was about who a developer needs to keep happy</a> &#8211; the client or <a href="http://www.sworddance.com/blog/2009/03/04/not-commenting-code-is-dangerous-to-your-career/">the manager</a>.</p>
<p>But commenting everything is both hard, excessive, and wasteful of time. In &#8220;the why&#8221; post, I cover what should be in the comments &#8211; implicitly I was limiting comments to just the places where knowing &#8220;the why&#8221; is important.</p>
<p>However, still the question is &#8220;when&#8221; should a developer comment?</p>
<p>Here is my rule of thumb:</p>
<ul>
<li>Any developer had to spend time figuring out what the code did. Refactor it and if still not clear comment the code with questions and assumptions. (Just in case the refactoring introduced a bug or caused an existing bug to appear.)</li>
<li>Another developer asks the implementing developer (or the current &#8220;owner&#8221;/responsible developer) about the code, interfaces, package. The developer asking the question copy the explanation into the code, cleaning up the chat log/email response and adding further edits and explanation as needed.</li>
<li>The code is not going to have further development for a while. Comment the code enough so that when development is resumed, the restart is faster.</li>
<li>The code is being handed off from one developer to another.</li>
<li>Key interfaces that are used by multiple groups.</li>
</ul>
<p>And managers give developers time to wrap up and add these comments.</p>
<p>Conversely, what is not worth commenting:</p>
<ul>
<li>Code that is actively, daily, being changed rearchitected. Every developer already knows what the comments would say and the structure is changing fast enough that the comments would become outdated.</li>
<li>Code that does not impact data integrity and end-user experience in a horrid way.</li>
<li>Utility classes/ methods.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://sworddance.com/blog/2009/03/16/when-to-comment/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why and when to wrap external library classes</title>
		<link>http://sworddance.com/blog/2009/03/16/why-and-when-to-wrap-external-library-classes/#utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=why-and-when-to-wrap-external-library-classes</link>
		<comments>http://sworddance.com/blog/2009/03/16/why-and-when-to-wrap-external-library-classes/#comments</comments>
		<pubDate>Mon, 16 Mar 2009 17:47:09 +0000</pubDate>
		<dc:creator>patrick</dc:creator>
				<category><![CDATA[code review]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[technical]]></category>

		<guid isPermaLink="false">http://www.sworddance.com/blog/?p=315</guid>
		<description><![CDATA[At some point, every developer starts using an external library. They then have to decide if that external library should be wrapped in their own custom interfaces and classes. If the external library would be pervasively imported in throughout the &#8230; <a href="http://sworddance.com/blog/2009/03/16/why-and-when-to-wrap-external-library-classes/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>At some point, every developer starts using an external library. They then have to decide if that external library should be wrapped in their own custom interfaces and classes. </p>
<p>If the external library would be pervasively imported in throughout the code then the answer is empathically YES &#8212; the external library should be wrapped.</p>
<p>At Amplafi, <a href="http://hibernate.org" target="_blank">hibernate</a> is just such a library. Without wrapping every time the hibernate library changed its structure or behavior, the change would have a large impact. However, by wrapping the libraries hibernate became loosely coupled.</p>
<p>This also enabled us to solve other more major issues with Hibernate Query and Session.</p>
<p>Specifically:</p>
<ul>
<li>control when a transaction could be committed. We wanted to count how many times a tx was &#8220;started&#8221; and only commit when the tx was &#8220;ended&#8221; the same number of times it was started. Useful for code that doesn&#8217;t know if it needs to start a transaction. Now any code that needs a tx just &#8220;starts&#8221; one and ends it when done.</li>
<li>Performance metrics gathering.</li>
<li>Delaying starting the transaction until it is known that something will actually be done.<br />
More gentle behavior for query.uniqueResult() ( default Hibernate behavior is to throw an exception if there is more than one row returned. Amplafi&#8217;s wrapper logs the non-uniqueness + ids of the extra rows. ) </li>
</ul>
<p>How we did this:</p>
<ol>
<li>Create an interface (AmplafiQuery) that extends Query</li>
<li>Create a class (AmplafiQueryImpl) that extends AmplafiQuery and wraps a org.hibernate.Query</li>
<li>Create a Txmanager that returns a Tx.</li>
<li>Tx has the various createQuery methods and returns AmplafiQuery</li>
</ol>
<p>We also took the opportunity to add to AmplafiQuery:</p>
<ul>
<li>a &#8220;asList()&#8221; that is a generic enabled version of Query.list()</li>
<li>a &#8220;unique()&#8221; that is a generic enabled version of Query.uniqueResult()</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://sworddance.com/blog/2009/03/16/why-and-when-to-wrap-external-library-classes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interfaces vs. abstract classes</title>
		<link>http://sworddance.com/blog/2009/03/14/interfaces-vs-abstract-classes/#utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=interfaces-vs-abstract-classes</link>
		<comments>http://sworddance.com/blog/2009/03/14/interfaces-vs-abstract-classes/#comments</comments>
		<pubDate>Sun, 15 Mar 2009 07:39:45 +0000</pubDate>
		<dc:creator>patrick</dc:creator>
				<category><![CDATA[code review]]></category>
		<category><![CDATA[technical]]></category>

		<guid isPermaLink="false">http://www.sworddance.com/blog/?p=351</guid>
		<description><![CDATA[Sigh &#8230; some people just don&#8217;t get it&#8230;. Interfaces rock! Below is my comment from stackoverflow.com, a question about how to handle the &#8220;interfaces v. abstract classes&#8221; interview question in an interview. First, the &#8220;only one super class&#8221; answer is &#8230; <a href="http://sworddance.com/blog/2009/03/14/interfaces-vs-abstract-classes/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Sigh &#8230; some people just don&#8217;t get it&#8230;. <img src='http://sworddance.com/blog/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </p>
<p>Interfaces rock!  Below is my comment from <a href="http://stackoverflow.com/questions/639592/why-are-interfaces-preferred-to-abstract-classes/647446#647446">stackoverflow.com</a>, a question about how to handle the &#8220;interfaces v. abstract classes&#8221; interview question in an interview. </p>
<ol>
<li>
First, the &#8220;only one super class&#8221; answer is lame. Anyone who gave me that answer in an interview would be quickly countered with &#8220;C++ existed before Java and C++ had multiple super classes. Why do you think James Gosling only allowed one superclass for Java?&#8221;</p>
<p>Understand the philosophy behind your answer otherwise you are toast (at least if I interview you.)</li>
<li>Second, interfaces have multiple advantages over abstract classes, especially when designing interaction points between modules (i.e. the <a href="http://en.wikipedia.org/wiki/Facade_pattern" rel="nofollow">Facade pattern</a>). The biggest one is not having a particular class structure imposed on the caller of a method. There is nothing worse than trying to use a method call that demands a particular class structure. It is painful and awkward. Using an interface *anything* can be passed to the method with a minimum of expectations.
<p>Example:<br />
<code><br />
    public void foo(java.util.Hashtable bar); // Hashtable is concrete class</code></p>
<p>vs.<br />
<code><br />
    public void foo(java.util.Map bar); // Map is an interface</code></p>
<p>For the former, the caller will always be taking their existing data structure and slamming it into a new Hashtable.
</li>
<li>Third, interfaces allow public methods in the concrete class implementers to be &#8220;private&#8221;. If the method is not declared in the interface then the method cannot be used (or misused) by classes that have no business using the method. Which brings me to point 4&#8230;.</li>
<li>
<p>Fourth, Interfaces represent a minimal contract between the implementing class and the caller. This minimal contract specifies exactly *how* the concrete implementer expects to be used and no more. The calling class is not allowed to use any other method not specified by the <em>contract</em> specified by interface. The interface name also flavors the developer&#8217;s expectation of how they should be using the interface implementor in the current context. If a developer is passed a<br />
<code><br />
    public interface FragmentVisitor {<br />
        public void visit(Node node);<br />
    }</code></p>
<p>The developer knows that the only method available is the visit method. They don&#8217;t get distracted by the bright shiny methods in the actual implementor&#8217;s concrete class.</li>
<li>Lastly, abstract classes have many methods that are really only present for the subclasses to be using. Abstract classes tend to look a little like a mess to the outside developer, there is no guidance on which methods are intended to be used by outside code.
<p>Yes of course some such methods can be made protected. However, protected methods are also visible to other classes in the same package. And if the concrete class implements other interfaces, those methods must be public &#8211; even if those methods should not be called in the current method. This problem goes away with a narrowly defined interface that hides all implementation details and only exposes the allowed methods defined in the interface. </li>
</ol>
<p>If the developer uses some &#8220;special&#8221; knowledge to cast an object to another broader interface or the concrete class itself, such a cast violates the expected contract, and the developer should be slapped with a salmon.</p>
]]></content:encoded>
			<wfw:commentRss>http://sworddance.com/blog/2009/03/14/interfaces-vs-abstract-classes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code Review #7 &#8211; Comment the &#8220;why&#8221; not the &#8220;what&#8221;</title>
		<link>http://sworddance.com/blog/2009/03/04/code-review-7-comment-the-why-not-the-what/#utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=code-review-7-comment-the-why-not-the-what</link>
		<comments>http://sworddance.com/blog/2009/03/04/code-review-7-comment-the-why-not-the-what/#comments</comments>
		<pubDate>Wed, 04 Mar 2009 22:48:38 +0000</pubDate>
		<dc:creator>patrick</dc:creator>
				<category><![CDATA[code review]]></category>
		<category><![CDATA[management]]></category>
		<category><![CDATA[technical]]></category>

		<guid isPermaLink="false">http://www.sworddance.com/blog/?p=338</guid>
		<description><![CDATA[[This post continues the response to Mike.] Clean &#8220;good&#8221; code is good but not enough. Code needs comments &#8212; but the right kind of comments. &#8220;What&#8221; comments are useless and the most quickly out-dated. An example of a what comment &#8230; <a href="http://sworddance.com/blog/2009/03/04/code-review-7-comment-the-why-not-the-what/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>[This post <a href="http://www.sworddance.com/blog/2009/03/04/not-commenting-code-is-dangerous-to-your-career/">continues the response</a> to <a href="http://www.sworddance.com/blog/2007/05/29/thoughts-on-how-to-evaluate-code/#comment-16341">Mike.</a>]</p>
<p>Clean &#8220;good&#8221; code is good but not enough. Code needs comments &#8212; but the right kind of comments.</p>
<p>&#8220;What&#8221; comments are useless and the most quickly out-dated. An example of a what comment is: &#8220;add the suffix path to the end&#8221;. </p>
<p>However, <a href="http://www.sworddance.com/blog/2007/05/29/thoughts-on-how-to-evaluate-code/">the post &#8220;Thoughts on how to evaluate code&#8221;</a> was very specific referring to &#8220;why&#8221; comments. </p>
<p>Code no matter how &#8220;clean&#8221; can not self-document. Excellent comments are &#8220;why&#8221; comments. &#8220;Why&#8221; comments talk about :</p>
<ol>
<li>the assumptions / program state the code is expecting. (For example, the user is logged in, premium membership, or admin privileges )</li>
<li>other code affected if this code is changed (For example, setting up a language default for the session, a default that another piece of code is expecting to be set.)</li>
<li>if something is being done in a non-standard way &#8211; why it is being done that way (for example, iterating through a loop from high index to low-index rather than the standard low to high)</li>
<li>should the code in question be used as an example pattern of how to do similar operations elsewhere in the code &#8211; or should a developer instead use a different pattern elsewhere.</li>
<li>list the assumptions or conditions that require this implementation (with timestamp) so that it is easy to spot code that is present to handle conditions that no longer exist. For example, a comment like this: &#8220;12/20/2007 &#8211; yahoo&#8217;s open id implementation is using the openid 0.8-proposedspec.&#8221; Its pretty likely that the the spec has changed as has yahoo&#8217;s implementation. This wasn&#8217;t a HACK but knowing that reason behind the code is invaluable.</li>
<li>Future work planned.</li>
<li>Alternative solutions that were rejected (and why).</li>
<li>Performance considerations &#8211; this code might be special because it executes millions of times a second. So there is good reasons for some &#8220;ugliness&#8221;.</li>
<li>Update: Why the code was NOT done in a certain way.maybe the usual way to do a certain operation has resulted in a bug (reference the bug number in the comment! )</li>
<li>Update: You, as a developer, are confused by the code. Document your confusion! You may have just discovered a bug.</li>
<li>Update: Document other code looks related for a possible later refactoring.</li>
<li>Update: Document code that should be removed ( Java&#8217;s @Deprecated is very useful in this regards because IDEs can mark references to the deprecated code )</li>
</ol>
<p>The developer,  at the moment they are writing the code, must be able to explain <em>why</em> they are writing the code a certain way. It is a red flag to any developer if they cannot explain the why. They should double-check to make sure they understand the requirements. Chances are they don&#8217;t and they are doing the wrong thing. </p>
<p>I started requiring developers to clearly document the &#8220;why&#8221; in their code. I discovered developers that were doing things &#8220;wrong&#8221; because they were unaware of the correct solution. I discovered that I was not as clear in conveying the requirements  as I really thought. Without the developer&#8217;s &#8220;why&#8221; comment, it is easy to get frustrated with developers for the wrong reasons.</p>
<h4>Parting thought</h4>
<p>Why should the developers that come after the original developer have to spend any time ( and money! ) figuring out the previous work? </p>
<p>You may be the next developer.</p>
]]></content:encoded>
			<wfw:commentRss>http://sworddance.com/blog/2009/03/04/code-review-7-comment-the-why-not-the-what/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Not commenting code is dangerous to your career</title>
		<link>http://sworddance.com/blog/2009/03/04/not-commenting-code-is-dangerous-to-your-career/#utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=not-commenting-code-is-dangerous-to-your-career</link>
		<comments>http://sworddance.com/blog/2009/03/04/not-commenting-code-is-dangerous-to-your-career/#comments</comments>
		<pubDate>Wed, 04 Mar 2009 22:08:48 +0000</pubDate>
		<dc:creator>patrick</dc:creator>
				<category><![CDATA[code review]]></category>
		<category><![CDATA[management]]></category>

		<guid isPermaLink="false">http://www.sworddance.com/blog/?p=323</guid>
		<description><![CDATA[There is this myth that code can be self-documenting and that comments are not necessary in good code. Michael recently comment on an earlier blog post advocating the idea of self-documenting code. &#8220;Self-documenting&#8221; code is a career-damaging concept, because: Your &#8230; <a href="http://sworddance.com/blog/2009/03/04/not-commenting-code-is-dangerous-to-your-career/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>There is this myth that code can be self-documenting and that comments are not necessary in good code. <a href="http://www.sworddance.com/blog/2007/05/29/thoughts-on-how-to-evaluate-code/#comment-16341">Michael recently comment on an earlier blog post advocating the idea of self-documenting code</a>. </p>
<p>&#8220;Self-documenting&#8221; code is a career-damaging concept, because:</p>
<ul>
<li>Your &#8220;manager&#8221; (person who decides you stay employed) is an &#8220;idiot&#8221;,</li>
<li>Your co-workers are &#8220;idiots&#8221;,</li>
<li>You are an &#8220;idiot&#8221;</li>
<li>The product manager is an &#8220;idiot&#8221;</li>
<li>Your client is an &#8220;idiot&#8221;</li>
</ul>
<h3>Your &#8220;manager&#8221; (person who decides you stay employed) is an &#8220;idiot&#8221;</h3>
<p>That&#8217;s me. The guy who has 6+ people to manage has to figure out business plans and a much of non-technical stuff that has no doubt resulted in permanent brain damage. </p>
<p>Your manager is code reviewing all the changes by his direct reports. A task that takes a few minutes every day&#8230; unless there are no comments. I know that your manager should be able to immediately see what the code does. But remember your manager is an &#8220;idiot&#8221;. Unfortunately for you, he signs your paycheck.</p>
<p>Also unfortunately for you, if your manager doesn&#8217;t immediately understand your change &#8212; you are an &#8220;idiot&#8221; in his eyes. </p>
<p>You have also just turned a 15-minute task into a 2-hour task. He didn&#8217;t really want to be home with his family.</p>
<h3>Your co-workers are idiots</h3>
<p>Lets agree, your code was stellar but then your co-workers came in and mucked it up. They did a stupid refactoring and broke everything.</p>
<p>The code was &#8220;obvious&#8221; but not to them.</p>
<h3>You are an idiot</h3>
<p>Your manager returns from a two-week vacation and is code reviewing 2 weeks of changes. Your manager is asking about a &#8220;odd&#8221; change that you did 14 days ago.</p>
<ul>
<li>Can you explain it clearly?</li>
<li>Do you remember your thinking at the time?</li>
<li>Alternative solutions that you tried and failed?</li>
</ul>
<h3>The product manager is an &#8220;idiot&#8221;</h3>
<ol>
<li>Your stellar (comment-free) code is deployed into production.</li>
<li>The product manager changes the product definition and a new feature is born.</li>
<li>One of your (&#8220;idiot&#8221;) co-workers makes a change (but not to your code).</li>
<li>The tests pass and 2am this Friday, the code is to be deployed</li>
<li>You go out drinking.</li>
<li>Your (&#8220;idiot&#8221;) manager deploys the code to production and it breaks.</li>
<li>Unfortunately, it breaks in your code.</li>
<li>Your manager looks at your code and can&#8217;t figure out <em>why</em> you wrote the code a certain way.</li>
<li>Its 3am now. He calls you up. Are you going to remember why and are you going to be able to help him?</li>
</ol>
<p>Lets pretend that the test coverage is better and the problem is discovered before deployment. But your change was made 3 months ago, are you going to be able to explain the thought process for the change?</p>
<h3>Your client is an &#8220;idiot&#8221;</h3>
<p>You are independent and you take on clients. Your new client is a non-technical person who needs your awesome coding skills. Now you are in trouble. A non-technical product manager and a non-technical manager (they are paying you!).</p>
<p>But your code is self-documenting right?</p>
<p>Not to them. The product is late. The doubts grow in their head. They ask a friend to look at your code. Their friend (&#8220;another idiot!&#8221;) says the code looks like garbage and he cannot tell <em>why</em> you wrote the code a certain way. The client starts to push back on paying your invoices. Things get ugly.</p>
]]></content:encoded>
			<wfw:commentRss>http://sworddance.com/blog/2009/03/04/not-commenting-code-is-dangerous-to-your-career/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Code Review #6 &#8211; &#8216;Too smart&#8217; aka scared of being dumb</title>
		<link>http://sworddance.com/blog/2008/05/06/code-review-6-too-smart-aka-scared-of-being-dumb/#utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=code-review-6-too-smart-aka-scared-of-being-dumb</link>
		<comments>http://sworddance.com/blog/2008/05/06/code-review-6-too-smart-aka-scared-of-being-dumb/#comments</comments>
		<pubDate>Tue, 06 May 2008 20:05:48 +0000</pubDate>
		<dc:creator>patrick</dc:creator>
				<category><![CDATA[code review]]></category>
		<category><![CDATA[management]]></category>
		<category><![CDATA[technical]]></category>

		<guid isPermaLink="false">http://www.sworddance.com/blog/?p=137</guid>
		<description><![CDATA[One of the biggest failing junior developers have is that they are too &#8216;smart&#8217;. &#8216;Too smart&#8217;??? How can someone be &#8216;too smart&#8217;? Actually pretty easily. &#8216;Too smart&#8217; is when the person spent hours looking at a problem. And the next &#8230; <a href="http://sworddance.com/blog/2008/05/06/code-review-6-too-smart-aka-scared-of-being-dumb/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One of the biggest failing junior developers have is that they are too &#8216;smart&#8217;. &#8216;Too smart&#8217;??? How can someone be &#8216;too smart&#8217;? Actually pretty easily.</p>
<p>&#8216;Too smart&#8217; is when the person spent hours looking at a problem. And the next day she/he </p>
<ul>
<li>realizes the specs would require violating the speed-of-light;</li>
<li>or has the product manager come up to them and say, &#8220;Oh yeah, there was a typo in the spec and it should have said &#8216;&#8230; NOT &#8230;&#8217;&#8221;;</li>
<li>or the product manager/tech lead (when asked) says, &#8220;that&#8217;s not what I meant&#8221;;</li>
<li>or the product manager/tech lead (when asked) says, &#8220;I didn&#8217;t consider that case&#8221; (or don&#8217;t worry about that case now);</li>
<li>or is told by a fellow developer, &#8220;oh I ran into that problem last week and on the 3rd page of the documentation, a workaround solution to that problem is described.&#8221;;</li>
<li>or discovers they were working on an old version of the code and upgrading to the latest version of code or libraries, solves the problem;
<li>or finally another developer looks at the problem and points out a simple condition that has been reversed;</li>
<li>or&#8230;</li>
</ul>
<p>In all cases, the person (doesn&#8217;t have to be a developer) violated the 20-minute rule. Quite simply the 20-minute rule says</p>
<blockquote><p>&#8220;If you are stuck for more than 20 minutes, and you are no closer to understanding the source of the problem &#8211; then ask for help&#8221;
</p></blockquote>
<p>Yes, it could be something &#8216;stupid&#8217; but it could also be something else. Sometimes you will be told to keep on looking because the person in question wants you to learn something. But sometimes there is a fundamental misunderstanding.</p>
<p>So to make sure that you are not asking for help too easily there is the corollary to the 20-minute rule,  the 10-minute review rule.</p>
<blockquote><p>Spend 10 minutes reviewing, how you got to this situation.</p>
<ul>
<li>Describe why the previous code is written the way it was. Notice this is not a &#8216;what&#8217; question. So do <em>not</em> answer &#8216;what the previous code was doing?&#8217; Answer <em>why</em> did the previous developer did the code this way &#8211; do you know how the code is being used? Are you breaking those assumptions?</li>
<li>Describe why the previous code is now incorrect. List the changed assumptions or requirements.</li>
<li>Describe what your solution is going to accomplish.</li>
<li>Describe why your solution is the minimal solution.</li>
<li>Describe why your solution is the correct choice.</li>
<li>Describe the single problem that if solved would make your solution work correctly.</li>
</ul>
</blockquote>
<p>At this point, one of these choices is the path that needs to be taken:</p>
<ul>
<li><em>Fundamental misunderstanding about existing code.</em> You realized your initial assumptions were wrong and that your solution is the wrong path. Solution: STOP and look at reevaluate problem discarding old assumptions.</li>
<li><em>Missing information.</em> The problem was not specified clearly enough. There are multiple possible problems that are being asked to be solved. Solution: get clarification. Do not proceed until the problem has been clarified.</li>
<li><em>Reinventing wheel.</em> Has this problem already been solved somewhere else in the code? If so, refactor so the already created/tested solution can be used.</li>
<li><em>Rathole.</em> A simple problem is becoming more and more complex. Are you fixing the problem of the problem of the problem that you started off solving? Are you making changes all over the place? If you are in a rathole, this is a sure sign of Doing-the-wrong-thing. Solution: STOP!</li>
<li><em>I don&#8217;t know</em> If you don&#8217;t know, then you need to ask for help. Solution: Swallow pride and ask for help.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://sworddance.com/blog/2008/05/06/code-review-6-too-smart-aka-scared-of-being-dumb/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Code Review #5 &#8211; splurge on reporting configuration errors</title>
		<link>http://sworddance.com/blog/2007/10/30/code-review-5-splurge-on-reporting-configuration-errors/#utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=code-review-5-splurge-on-reporting-configuration-errors</link>
		<comments>http://sworddance.com/blog/2007/10/30/code-review-5-splurge-on-reporting-configuration-errors/#comments</comments>
		<pubDate>Tue, 30 Oct 2007 19:30:09 +0000</pubDate>
		<dc:creator>patrick</dc:creator>
				<category><![CDATA[code review]]></category>
		<category><![CDATA[technical]]></category>

		<guid isPermaLink="false">http://www.sworddance.com/blog/2007/10/30/code-review-5-splurge-on-reporting-configuration-errors/</guid>
		<description><![CDATA[Configuration problems when deploying a new build are high on the &#8220;high anxiety&#8221; list. The pressure is high to hurry up and get the build deployed. Often times, the deploy happens late at night when the deployer really just wants &#8230; <a href="http://sworddance.com/blog/2007/10/30/code-review-5-splurge-on-reporting-configuration-errors/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Configuration problems when deploying a new build are high on the &#8220;high anxiety&#8221; list. The pressure is high to hurry up and get the build deployed. Often times, the deploy happens late at night when the deployer really just wants to go to bed.</p>
<p>The number one way a developer can help out in this situation is very good error messages. If an exception occurs as a result of a misconfiguration: be verbose. Be overly verbose. The sanity you save may be your own.</p>
<p>This error message does not cut it:</p>
<blockquote><p>Caused by: java.io.IOException: Couldn&#8217;t initialize working directory.<br />
        at com.amplafi.core.iomanagement.FtpManagerImpl.initializeWorkingDirectory(FtpManagerImpl.java:83)<br />
        at com.amplafi.core.iomanagement.FtpManagerImpl.initializeService(FtpManagerImpl.java:50)<br />
        &#8230; 16 more<br />
Caused by: java.io.IOException: Couldn&#8217;t create directory: ftp-working<br />
        at com.amplafi.core.iomanagement.FtpManagerImpl.initializeDirectory(FtpManagerImpl.java:61)<br />
        at com.amplafi.core.iomanagement.FtpManagerImpl.initializeWorkingDirectory(FtpManagerImpl.java:81)
</p></blockquote>
<p>The error message should have at the minimum contained the following pieces of information:</p>
<ul>
<li>The directory name as supplied in the configuration</li>
<li>The full absolute path to that directory (<em>not</em> the same thing as the configuration name if the name is a relative, not absolute path)</li>
<li>The reason for the problem (was the parent directory not writable, something already there, disk full, etc.)</li>
<li>A suggestion on how to correct the problem</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://sworddance.com/blog/2007/10/30/code-review-5-splurge-on-reporting-configuration-errors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code Review #4: Always read the documentation/code &#8211; a.k.a. java.net.URL  is evil</title>
		<link>http://sworddance.com/blog/2007/09/09/code-review-4-always-read-the-documentationcode-aka-javaneturl-is-evil/#utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=code-review-4-always-read-the-documentationcode-aka-javaneturl-is-evil</link>
		<comments>http://sworddance.com/blog/2007/09/09/code-review-4-always-read-the-documentationcode-aka-javaneturl-is-evil/#comments</comments>
		<pubDate>Sun, 09 Sep 2007 10:49:04 +0000</pubDate>
		<dc:creator>patrick</dc:creator>
				<category><![CDATA[code review]]></category>
		<category><![CDATA[technical]]></category>

		<guid isPermaLink="false">http://www.sworddance.com/blog/2007/09/09/code-review-4-always-read-the-documentationcode-aka-javaneturl-is-evil/</guid>
		<description><![CDATA[The Setup Before I plunge into my rant, lets review a little-ole documentation. Under java.lang.Object, for equals() we have this: It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently &#8230; <a href="http://sworddance.com/blog/2007/09/09/code-review-4-always-read-the-documentationcode-aka-javaneturl-is-evil/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><em><strong>The Setup</strong></em><br />
Before I plunge into my rant, lets review a little-ole documentation. Under <a href="http://java.sun.com/javase/6/docs/api/java/lang/Object.html"><code>java.lang.Object</code></a>, for <code>equals()</code> we have this:</p>
<blockquote><p>
It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true  or consistently return false, provided no information used in equals comparisons on the objects is modified.
</p></blockquote>
<p>Over in <a href="http://java.sun.com/javase/6/docs/api/java/util/Collection.html"><code>java.util.Collection</code></a> land, there is this little bit of documentation, highlighting the importance of overriding the default implementations of equals() and hashCode() if one wants to play nice in a Collection:</p>
<blockquote><p>
Many methods in Collections Framework interfaces are defined in terms of the <em>equals</em> method. This specification should not be construed to imply that invoking Collection.contains with a non-null argument o will cause o.equals(e) to be invoked for any element e. Implementations are free to implement optimizations whereby the equals invocation is avoided, for example, by first comparing the hash codes of the two elements.</p></blockquote>
<p>So for instances of a class to function well as a key in a <code>java.util.Map</code> or be placed into a <code>java.util.Set</code>, the class should override the standard equals() and hashCode() provided by Object. Because of this universal need, it is a reasonable expectation that implementors of <code>equals()</code> and <code>hashCode()</code> pay attention to performance. For example, the programmers who wrote java.lang.String did a fairly simple implementation of hashCode() and then cached the result so the calculation was not repeated for a given String object.</p>
<p>The resulting ubiquity of overridden <code>equals()</code> and <code>hashCode()</code> results in a certain set of expectations:</p>
<ol>
<li>if the object doesn&#8217;t change the results of <code>equals()/hashCode()</code> shouldn&#8217;t change (otherwise Set collections will break)</li>
<li>equals()/hashCode() should be fast and in the case of hashCode &#8211; for potentially expensive hashCode() operations the results should be cached.</li>
<li>Immutables (such as URL) should be good candidates to be keys in a <code>java.util.Map</code></li>
</ol>
<p><em><strong>The Takedown</strong></em><br />
So I was completely blindside by the brain-dead, high school, freshman implementation of <code>java.net.URL</code>.</p>
<p>The only thing I will say positive about the <code>java.net.URL</code> implementation <code>equals()/hashCode()</code> is this: buried deep, deep in the documentation, the high school students who wrote the implementation do casually tell you that they are going to screw you over.</p>
<p>In java.net.URL.equals() (only if you go look at the detailed documentation) do you see this:</p>
<blockquote><p>Compares this URL for equality with another object.</p>
<p>If the given object is not a URL then this method immediately returns false.</p>
<p>Two URL objects are equal if they have the same protocol, reference equivalent hosts, have the same port number on the host, and the same file and fragment of the file.</p>
<p><em>Two hosts are considered equivalent if both host names can be resolved into the same IP addresses; (emphasis mine)</em> else if either host name can&#8217;t be resolved, the host names must be equal without regard to case; or both host names equal to null.</p>
<p>Since <em>hosts comparison requires name resolution (emphasis mine)</em>, this operation is a blocking operation.</p>
<p><em>Note: The defined behavior for equals is known to be inconsistent with virtual hosting in HTTP.  (emphasis mine)</em></p></blockquote>
<p>Translation: We are going to screw you and you <em>will</em> enjoy it. </p>
<p><em><strong>The Scream</strong></em><br />
How does this screw you?</p>
<ol>
<li>Two fundamental operations equals()/hashCode() are now ridiculously expensive since they involve a DNS lookup to see if they resolve to the same ip address. So now an operation that is optimize in other classes is outrageously expensive (milliseconds long) for a very fundamental internet class.</li>
<li>URL looks to be an immutable. Immutable objects should mean that the identity: x.equals(x) is true. But this isn&#8217;t the case for URL. If you serialize a URL, the resolved hostaddress (it&#8217;s transient) is lost. So serialize/deserialize a URL. Wait a little bit. Add a little bit of the <a href="http://en.wikipedia.org/wiki/Dynamic_DNS">Dynamic DNS</a> magic. Presto &#8220;http://google.com&#8221; will  not equal the deserialized version of itself</li>
<li>It is simple wrong. Take the case of a hosting service that hosts two different sites on the same server. The DNS lookup resolves the 2 domains to the same physical ip address. URL (with an &#8220;assist&#8221; from URLStreamHandler, InetAddress, and our very expensive DNS lookup) compares URLs based on the ip address not the entered hostname. As a result, <code>http://my-porn-site.com</code> could &#8216;equal&#8217; <code>http://jesus-has-saved-my-soul.org</code>. I think someone might disagree with this assessment, don&#8217;t you?</li>
</ol>
<p><em><strong>The Takeaway</strong></em><br />
So after these very expensive operations <code>URL.equals()/hashCode()</code> is broken. The implementers of URL clearly decided that they were going to be &#8216;clever&#8217; and for all their &#8216;cleverness&#8217; the only thing they managed to do is screw users of this class. Sun should just admit the error of its ways and just reimplement <code>URL.equals()</code> (with <code>hashCode()</code> being the equivalent).</p>
<blockquote>
<pre>
public boolean equals(Object o) {
    if( !(o instanceof URL)) {
        return false;
    } else if ( o == this ) {
        return true;
    } else {
        return ((URL)o).toString().equalsIgnoreCase(this.toString());
    }
}
</pre>
</blockquote>
<p>The old functionality should be quietly pushed to a <code>uselessEquals()</code> method some place.</p>
<p><em><strong>The Net</strong></em><br />
Performance problems and bugs can be introduced from the wildest and least expected locations. Always recheck your assumptions.</p>
<blockquote><p>
&#8220;When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.&#8221;<br />
-<a href="http://www.sherlockian.net/about/faq.html">Sherlock Holmes</a>.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://sworddance.com/blog/2007/09/09/code-review-4-always-read-the-documentationcode-aka-javaneturl-is-evil/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

