Skip to Content.
Sympa Menu

xom-interest - Re: [XOM-interest] Code compactness vs instanceof

xom-interest AT lists.ibiblio.org

Subject: XOM API for Processing XML with Java

List archive

Chronological Thread  
  • From: Remko Popma <remko.popma AT azzurri.jp>
  • To: XOM-interest <XOM-interest AT lists.ibiblio.org>
  • Subject: Re: [XOM-interest] Code compactness vs instanceof
  • Date: Fri, 20 Sep 2002 02:58:26 +0900 (JST)

--- Elliotte Rusty Harold <elharo AT metalab.unc.edu> wrote:
>
> At 10:33 AM +0200 9/19/02, Laurent Bihanic wrote:
>
>
> > - Code compactness: As I already said on the jdom-interest mailing
> >list, there are cases (e.g. TreeNode.getChild()) where instanceof
> >tests make the code very unclear and thus harder to maintain.
> >I know Elliotte does not like the idea of a int getNodeType() method
> >but we need to find a way to remove these ugly tests.
> >
>
>
> I agree the situation is imperfect. I think there's a bit of a
> mismatch between the XML model and the Java model, but I don't see
> how we can do any better than I've done.
>
> Why would
>
> if (node.getNodeType() == Node.ELEMEBT_TYPE)
>
> be preferable to
>
> if (node instanceof Element)
>
> ?
>
> They're both ugly. I think the second one is less ugly.

I agree.

> Do you see something different? What do you think the code should
> look like? (Actually what I think the code should look like is
> polymorphic method dispatching, where I can pass a Node to a
> process() method and have the runtime choose the overloaded method to
> dispatch based on the node's subtype, but that's not a feature Java
> gives us so we have to deal. :-( )

If this is really an issue, you could use the "double dispatch" pattern, eg:

public interface ICallback {
public handleElement(Element element);
public handleDocument(Document document);
public handleComment(Comment comment);
public handleAttribute(Attribute attribute);
// etc for all Node subclasses
}

then, in the Node class you can add this method:
public abstract void process(ICallback callback);

and every Node subclass would call the appropriate method
in the ICallback interface:

class Element {
public void process(ICallback callback) {
callback.handleElement(this);
}
}

class Document {
public void process(ICallback callback) {
callback.handleDocument(this);
}
}

class Comment {
public void process(ICallback callback) {
callback.handleComment(this);
}
}

You could improve usability with a CallbackAdapter class that
provides an empty implementation for every method (like
java.awt.MouseAdapter).

This would make for very clean client code, at the expense of
growing the API with a method that may not be obvious at first glance.
Good class and method names (suggestions for better names than
"ICallback" and "process"?), and some good examples may help out a little
here.

Remko




Archive powered by MHonArc 2.6.24.

Top of Page