Archive for March, 2009

friendly-coins, Stage 1: Only one level of indentation per method

For the friendly-coins project, my strategy is to start from a completed project, and apply refactorings to arrive at a codebase obeying the Nine Rules.

I think this will be interesting for at least a couple reasons:

  • It’ll give me a chance to see which of the Nine I tend to diverge from the most.
  • I’ll be able to do a before/after measurement on a few code metrics (for example, complexity and cohesion).

The first refactor I applied was “Use only one level of indentation per method”.

Micro-state sharing

The bulk of the changes involved moving loops into their own methods.

I noticed a two variants of a micro-pattern. First, let’s look at a stringJoin (yes, this is available elsewhere — but I decided not to use any non-core libraries, and even to not use core implementations if writing the code might exercise some of the Nine Rules).

BEFORE:


public static String stringJoin( Collection objects, String joiner ) {
    StringBuilder builder = new StringBuilder();
    boolean first = true;
    for( Object o : objects ) {
        if( ! first ) {
            builder.append( joiner );
        } else {
            first = false;
        }
        builder.append( (null == o) ? "null" : o.toString() );
    }
    return builder.toString();
}

AFTER:


public static String stringJoin( Collection objects, String joiner ) {
    StringBuilder builder = new StringBuilder();
    String useJoiner = "";
    for( Object o : objects ) {
        first = stringJoinAppend( o, useJoiner, builder );
        useJoiner = joiner;
    }
    return builder.toString();
}

private static boolean stringJoinAppend( Object o, String joiner, StringBuilder builder ) {
    builder.append( joiner );
    builder.append( (null == o) ? "null" : o.toString() );
}

Now, let’s look at a method which find a minimal value (yes, yes, here I am reimplementing the wheel – in the interest of calisthenics).

BEFORE:


private CoinSet findMin(Collection coinSets) {
     CoinSet theLeast = null;
     for( CoinSet coinSet : coinSets ) {
         if( null == theLeast || coinSet.getNumCoins() < theLeast.getNumCoins() ) {
             theLeast = coinSet;
         }
     }
     return theLeast;
 }

AFTER:


private CoinSet findMin(Collection coinSets) {
     CoinSet theLeast = null;
     for( CoinSet coinSet : coinSets ) {
         theLeast = isItLess( theLeast, coinSet );
     }
     return theLeast;
 }

 private CoinSet isItLess(CoinSet theLeast, CoinSet coinSet) {
     if( null == theLeast || coinSet.getNumCoins() < theLeast.getNumCoins() ) {
         theLeast = coinSet;
     }
     return theLeast;
 }

I am claiming this is a “micropattern” characterized by the fact that there is state associated with the loop, and the state needs to be managed by coordination between the caller and callee methods. In the case of stringJoin, the state is whether or not to append the spearator to the string. In the case of findMin (which actually has a more descriptive name in the real source), it’s what the minimal value found so far is.

How the state is managed between caller and -ee differs in the two examples. In the stringJoin case, the state is independent of the called method (i.e., the caller maintains state). In the findMin case, the called method is responsible for maintaining the correct state. It would be possible to re-implement either method so that the responsibility is flipped. It’s just that the way I implemented both of them smelled right to me on the day I did it. It is worth noting that in the stringJoin, I have a redundant assignment (the assignment need only be done on the first pass through the loop). However, I liked getting rid of the “if” test that would be necessary. On the other hand, finding the minimal value does need a conditional, so putting the “if” in the callee works nicely.

Try / Catch – Problematic

Tricky to eliminate extra indentation were the try/catches – in this case, I took the requirement to be that there be 0 levels if indent inside the try/catch.  These are almost like a loop-removal, but seem to me to be more “woven” into the rest of the method (because of dependencies on variable).  This particular refactor smelled a little bad to me. I’d even say that try/catches might by their very nature introduce extra complexity that requires extra effort in implementation.

Strategy Pattern / Anonymous Methods / Yield / Micro-IOP

Also interesting, was one instance of a “collect” pattern (as in, the Ruby language “collect” method, which in other languages might be called “map”):

BEFORE:


@Override public String toString() {
      String ret = this.getClass().getSimpleName() + "<";
      boolean first = true;
      for( int k : denominations.keySet() ) {
          if( ! first ) {
              ret += ",";
          } else {
              first = false;
          }
          ret += k;
          ret += "'s:";
          ret += denominations.get( k );
      }
      return ret + ">";
      items.add( item );
  }

I tried to get tricky and introduce a first-class “foreach” in order to use the already-refactored stringJoin. The idea is that the difference is what gets executed INSIDE the foreach – so, since Java in its Old Skool way doesn’t yet have real anonymous functions, I tried to make one.

AFTER:


public String toString() {
      final Collection items = new ArrayList();
      new Foreach( denominations.keySet() ) {
          public @Override void each( Object o ) {
              denominationToString(o, items);
          }
      }.apply();
      return this.getClass().getSimpleName() + "<" + Helpers.stringJoin( items, "," ) + ">";
  }

This looks bad. The boilerplate is ugly. Actually what I ended up liking better was this:


public String toString() {
      final Collection items = new ArrayList();
      for( int item : denominations.keySet() ) {
          items.add( denominationToString( o, items ) );
      }
      return this.getClass().getSimpleName() + "<" + Helpers.stringJoin( items, "," ) + ">";
  }

But on further reflection on the pursuit of first-class functions, maybe what I *really* wanted might have been this:


public String toString() {
     final Collection items =
         new Collect( denominations.keySet() ) {
             public @Override void each( Object o ) {
                 denominationToString(o, items);
             }
         }.apply();
     return this.getClass().getSimpleName() + "<" + Helpers.stringJoin( items, "," ) + ">";
 }

No matter what, the boilerplate kills the elegance. If there were more going on besides the boilerplate, I’d like this pattern. What I’m really trying to do is force Java to allow us to do this:


new Collect( denominations.keySet() ) {
    public @Override void each( Object o ) {
    ...
}.apply() ...

by just typing this:


collect { }

You see where I’m coming from. I just want something that Java isn’t prepared to let me have. Not today, anyhow.

Final Java Bash

A final note on this exercise: In two of the cases where a loop was moved out of a more complex method, some sort of state was identified that needed to be shared. This suggests treating the method as a class in its own right. But, Java isn’t geared up to allow this to be done elegantly, especially in the case that the state, or strategy, is trivial. In the “collect” case, what we wanted to do is supply (”inject”) a behavior into an existing algorithm. Again, foiled by the language itself. Finally, in the try/catch case, we’re faced with something that would better be solved using different language feature (assuming that our goal is to make the language support our best coding practices in the easiest way possible). Maybe a type of method which can be then decorated using AOP to insert the try/catch.

Nevertheless, in spite of the dearth of language features, We Can Do it. It just takes the courage to write minimal boilerplate and claim that it’s the Right Thing to Do. Besides, exercise is good for you.

Leave a Comment

New sub-project in the SVN repo: friendly-coins

Hi! First blog post from me.  In at attempt to kill two birds with one stone, I’m:

  • Starting a new small project, called friendly-coins.
  • This project happens to be a suggestion for a new Coding Problem. Therefore we get a solution to the problem, as well as some Object Calisthenics.

The repo is at: http://code.google.com/p/cumulus-code/source/browse/#svn/friendly-coins

Look at the “PROBLEM-STATEMENT.txt” file to see what the problem is all about. Stay tuned (next blog post) for the beginnings of a narrative of Object Calisthenics experiences to date.

Comments (1)

Code is moved to googlecode

After much palaver involving moving the directory structure around, I finally had it working and then remembered about googlecode. As it give quite a nice browsing experience, allows you to review code and also to make comments, I thought I would move it over there.

You can now find it at http://code.google.com/p/cumulus-code/

It also provides issue tracking and a wiki which might be useful.

Leave a Comment

Created a sub-project

We have moved the source code into a sub directory in the svn repository. We have decided to call our first project “feedcloud” because its intent is to turn a feed into a tag cloud. This will allow us to add more projects along the way so that others can contribute to the cloud.

Leave a Comment

Day 3

So we only got about half a day today but completed a small spike getting the database set up correctly. I also had some interesting feedback from Jeff around static methods which I have written up here.

Our DB spike simply does a set of CRUD against mysql, so now everything is set up. To run it you will need a mysql db called cumulusdb with appropriate user, which you can see in the code, you might of course want to change the password.

The code is in the spike package org.ixcode.cumulus.spike.mysql is in svn.

So now we are ready to roll! Oh except we have to go off to some projects…. Hopefully will find some time to work on this in between.

Comments (1)

Great OO Article

Leave a Comment

Day 2

Today we finished off with mingle and have all our stories ready.

The first thing we are going to do is play a spike to set up a mysql DB and get some basic JDBC going. We are doing this a s a spike so that we dont have to worry about the rules just yet and can just get the basic code out.

The first story is called “Store current feed” – it is basically to capture the feed from a http GET and store it in the DB, to get an end to end story, we will provide a simple web page that shows a list of all the entries captured so far.

We returned to our conversation about statics (not that we are obsessed!) we had an interesting email exchange with Jeff on the topic and I will be updating my blog entry to represent the new information.

As an offshoot of statics methods, we explored a bit factory methods, It was an interesting experience for me to try to summarise my thoughts about what factories are for and when they might be used. I will be writing this up in due course.

We wrote some code to illustrate various construction strategies which can be found at org/ixcode/cumulus/spike/staticmethods/factory

Leave a Comment

Day 1

So today we spent most of our time working out what the project is going to be about. We have set up a mingle instance and have a few stories which we have given rough sizing.

We had an interesting discussion around static methods. In the softcopy version of the rules, It says “Only use static methods for factories”. Since communicating with Jeff, we found out that the version on his site was a draft version.

However we did play with some code around when statics are appropriate for our own amusement. This can be seen in code at staticmethods

Leave a Comment