2010
02.22

In previous post I mentioned about the visitor pattern and how to use it in Java. I also use groovy in my projects and there’s a much better way to solve the problem with processing collections.

I have found a site about shortcomings of the visitor pattern.
The proposed solution in Nice programming language are, so called, multimethods.
I asked myself if I could use similar solution in groovy. The answer is yes, fortunately. Multimethods (or multiple dispatch) can be used in groovy.

In groovy you don’t have to implement visitor pattern and extend your domain objects. The following code will work just as you would expect:

// Base class
class Feature {
    String name

    public String toString() {
        return "Feature{" +
                "name='" + name + '\'' +
                '}';
    }
}

class BooleanFeature extends Feature{
    boolean value

    public String toString() {
        return "BooleanFeature{" +
                "value=" + value +
                '}';
    }
}

class StringFeature extends Feature{
    String value

    public String toString() {
        return "StringFeature{" +
                "value='" + value + '\'' +
                '}';
    }
}

// Class that processes Feature and its descendants
class Multimethod {
    def printFeature(Feature feature) {
        println "printFeature: $feature"
    }

    def printFeature(BooleanFeature feature) {
        println "printBooleanFeature: $feature"
    }

    def printFeature(StringFeature feature) {
        println "printStringFeature: $feature"
    }
}

Feature feature = new Feature(name:'feature')
Feature booleanFeature = new BooleanFeature(name:'booleanFeature', value:true)
Feature stringFeature = new StringFeature(name:'stringFeature', value:'Hello world')
List<Feature> features = [feature, booleanFeature, stringFeature, otherFeature]

Multimethod multimethod = new Multimethod()

features.each { multimethod.printFeature it}

The output is:

printFeature: Feature{name='feature'}
printBooleanFeature: BooleanFeature{value=true}
printStringFeature: StringFeature{value='Hello world'}

You can see the Feature class and some simple hierarchy. They represent domain classes. The Multimethod class is our processor. It would have to be a Visitor in java, in order to correctly process the collection of Feature elements. It’s not the case in groovy, as it dynamically resolves the type of parameters during runtime.

It saves a lot of coding. Now there’s no need to create class hierarchy only to process a collection properly. This also means, that there’s no need to overload a method for all classes that extend the Feature class.

No Comment.

Add Your Comment