Dwins’s Weblog


A Code Smell – the Utilities Trait

Posted in Development by dwins on May 7, 2010

warning: if you’re not a programmer you should probably stop reading now (use the time you’d have spent here at MS Paint Adventures; you’ll be glad you did.)

Back in school I saw a design pattern used in some students’ projects (including my own) where someone would want to have some constants used in several places in their code.  In Python, you would handle this with a simple variable in your module:

SNOWBALLS_CHANCE=6.8e-35
RABBITS_FOOT_INFLUENCE=7.5

A C++ programmer would probably use the preprocessor to define some constants that get replaced with literals before the compiler even sees the code:

#define SNOWBALLS_CHANCE 6.8e-35
#define RABBITS_FOOT_INFLUENCE 7.5

These projects were in Java, however, and Java doesn’t have free-standing values, or even a preprocessor like in C++ does; every single thing has to be part of some class.  Values that aren’t actually associated with class instances require the static modifier to stand apart from objects.  Code referencing such constants needs to qualify them with the name of the class they belong to, unless they subclass it:

class LuckConstants {
    private LuckConstants() { 
        /* don't even THINK of instantiating this, guys */ 
    }
    public static final float SNOWBALLS_CHANCE = 6.8e-35;
    public static final float RABBITS_FOOT_INFLUENCE = 7.5;

}
class PokerPlayer {
    public static void main(String[] args) {
        System.out.println("Odds:" + LuckConstants.SNOWBALLS_CHANCE);
    }
}
class PokerDealer extends LuckConstants {
    public static void main(String[] args) {
        System.out.println("Odds (adjusted):" + RABBITS_FOOT_INFLUENCE);
    }
}

This is kind of a lot of code, and if I want to have PokerDealer inherit from some GameMaster parent class I am going to have to use the long form since Java doesn’t do multiple inheritance.  Fortunately, there is also the option of inheriting constants from an interface, which doesn’t add any restrictions to the other parent types of a class.  The IConstants interface was the most common variation I saw, and I’m not aware of any particular shortcomings with this approach.  Still, it bugged me a bit that this setup involved this kind of useless type.  What use is an interface with no methods?  So I was really glad to find out about import static, which lets Java code reference static members of classes without qualifying them and without adding extra cruft to the type hierarchy.  (I started doing Java programming just before this feature came out, and I wasn’t able to use it for a little while as Apple dragged their feet a bit bringing it to the JVM that they provide for Macs.)

Okay, fast-forward 5 or 6 years.

Imagine my chagrine when, a couple of months into my first serious Scala project, I noticed that I had written some Utility Traits that did much the same things as those constant container interfaces, but providing some methods instead of some constants.  In Java such a thing isn’t possible since interfaces can’t contain implementation, but Scala’s traits can.  (Otherwise they are analogous to interfaces, and even reduce to Java interfaces when they don’t include implementation.)  Scala definitely has a nice equivalent to static class members that would be totally applicable here, so why didn’t I use that? Lame.

So when you find a trait in Scala code that doesn’t have any abstract methods, and maintains no state, it’s definitely time to consider refactoring it to an object instead.  (If it does have state, but no abstract methods, maybe it should be a class instead of a trait.)  You can easily convert any client code to the new way.  Let’s say you have a Utilities trait for doing some housework:

trait Utilities {
    def unclogDrain() {}
    def cleanGutters() {}
    def retileRoof() {}

}

class HiredHand extends Utilities {
    def doWhatYourePayedFor() {
        unclogDrain()
        cleanGutters()
        retileRoof()
    }
}

You could make it a Utilities object instead with:

object Utilities { ... }
class HiredHand {
    import Utilities._  
    // now everything from Utilities is in local scope, woo!
    ...
}

Neat!  Now to go fix up that code.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: