|
I’ve been experimenting lately with a technique that I’m still unsure about. It has a little smell to it, but it has some benefits. The technique is to add static collection-related utility methods on an object. That is, I’ll add a static method that takes a collection of that object on the object itself.
Take the classic Shape example:
public class Shape {
// here’s a typical instance method
public void draw();
// here's what I’m talking about.
public static void draw(Collection shapes) {
for (Iterator it = shapes.iterator(); it.hasNext; ) {
Shape shape = (Shape) it.next();
shape.draw();
}
}
}
Now, I haven’t done this kind of thing much; maybe once or twice. The first time I did it was because I noticed some duplication. The exact looping code was shared by multiple clients. I wanted to remove the duplication, but I didn’t know where to put it, so I stuck it on the object itself. The clients became (in the context of this example):
someShapeClientMethod() {
...
Shape.draw(myShapes);
...
}
I think this actually improves clarity (although I could have accomplished the same thing by creating a helper draw() method in the client). This also has the benefit of grouping the iteration logic close to its source, e.g.,Shape here.
The real world example where I first used this was a query. I had a collection of objects and I wanted to find a specific one. Say, I had a collection of Shapes and I wanted to know who was the biggest:
public static Shape getBiggest(Collection shapes);
I think this technique is most applicable under the following circumstances:
What bothers me most is that I can’t recall seeing this technique used anywhere. That could mean that there’s something really bad about it. One problem is that it clutters the object with additional methods. That’s why I think it should be used judiciously. Also, from a purist view, do these methods really belong on the object?
What do you think?