Pure Danger Tech


navigation
home

Visitor pattern with closures

13 Mar 2008

I’ve been playing around a bit with how having closures in Java 7 would alter some design patterns. I’m doing a talk on design patterns for Java One so hoping to do some stuff on this for the talk.

Here’s one version of Visitor with closures. I’m not too happy with it yet. There’s no Visitor interface, I’m just using a closure to handle the visitor callbacks. The downside to that is that I’ve lost the double-dispatch part. I suspect this is probably fine for many common visitor cases and sucks for others.

The main Visitable interface now just takes a block: [source:java]

public interface Visitable {

void accept({ Visitable => void } block);

}

[/source]

And concrete and composite nodes have accept methods like this:

[source:java]

public interface Node extends Visitable {}

public class CompositeNode implements Node {

private List nodes = new ArrayList();

// …

public void accept({ Visitable => void } block) {

block.invoke(this);

for(Node node : nodes) {

node.accept(block);

}

}

}

public class ConcreteNode implements Node {

// …

public void accept({ Visitable => void } block) {

block.invoke(this);

}

}

[/source]

And you can use it like this: [source:java]

public class Test

{

public static void main(String[] arg) {

CompositeNode n = new CompositeNode();

n.addNode(new ConcreteNode());

n.addNode(new ConcreteNode());</p>

List strings = new ArrayList();

n.accept({ Visitable v =>

if(v instanceof ConcreteNode) {

strings.add(((ConcreteNode)v).getName());

}

});

System.out.println(strings);

}

}

[/source]

I’d like to take advantage of double-dispatch to “choose” one of a family of blocks that might apply but seems like that takes you in the direction of having a Visitor again with one method per concrete type and that seems worse than the non-closure version.

Thoughts and ideas?