Search the archives!
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
design question: deriving ouputs walking a tree
- From: boazbk@xxxxxxxxxxxxxx (Boaz Barak)
- Subject: design question: deriving ouputs walking a tree
- Date: Sun, 27 Sep 1998 13:44:49 +0200
Here is a suggestion for another approach (of course , since I don't really know all the details it may not be the right one for you): have the renderer provide methods such as void render(A a); void render(B b); void render(C c); ... for all the classes it supports , have a dispatch method which will find out using reflection which is the most appropriate method to call. I have used this technique in places where I wished for "runtime overloading" - like message handling where you wish you can add a derived class which handles a particular message ( I think a place where we all miss runtime overloading is the equals() method where we are forced to define it as equals(Object o) ). I've used the following code, but you can probably write more optimized code , I think also that JDK 1.3 might have something like as part of their proxy creation mechanism. I also don't handle here problems that might appear if the class declaring the method is public, but the derived class is not. Boaz Barak code from http://www.math.tau.ac.il/~boazbk/pos /** * returns true iff types1 is more specific than types2 * @exception POSException is thrown if they are incomparable. */ public static boolean isMoreSpecific(Class[] types1,Class[] types2) throws IL.ac.tau.pos.POSException { if (types1 == null) return false; if ((types1 != null) && (types2 == null)) return true; if (types1.length != types2.length) throw new IL.ac.tau.pos.POSException("Args not of the same length - " + types1.length +" != " + types2.length); for (int i = 0 ; i < types1.length ; i++) if (!types2[i].isAssignableFrom(types1[i])) return false; return true; } /** * try to get most appropriate method ,return null if fails. */ public static java.lang.reflect.Method getMethod(Class cls,String name,Object[] args) throws IL.ac.tau.pos.POSException { Log.debug("ProxyFactory.getMethod called withh Class "+ cls + " MethodName = " + name + " args="+args); try { Method[] methods = cls.getMethods(); Class[] paramTypes = new Class[args.length]; for (int i = 0 ; i < args.length ; i++) paramTypes[i] = (args[i]==null ? null : args[i].getClass()); for (int i = 0 ; i <methods.length ; i++) if (!methods[i].getName().equals(name) || (!isApplicable(paramTypes,methods[i].getParameterTypes()))) methods[i] = null; Method method = null; for (int i = 0 ; i < methods.length ; i++) { if (methods[i]==null) continue; if (method==null || (isMoreSpecific(methods[i].getParameterTypes(),method.getParameterTypes()))) method = methods[i]; } return method; } catch (IL.ac.tau.pos.POSException e) { throw e; } catch (Exception e) { Log.error(e); throw new IL.ac.tau.pos.POSException("Exception " + e + " getting method"); } } ----- Original Message ----- From: James Tauber <jtauber@xxxxxxxxxxx> To: <advanced-java@xxxxxxxxxxxxxxxx> Sent: ùáú 25 ñôèîáø 1999 10:48 Subject: design question: deriving ouputs walking a tree > As I've mentioned before, I'm working on an XSL formatter called FOP (see > http://www.jtauber.com/fop/). I'm rethinking a lot of the overall design and > the following question has come up: > > XSL formatting really has two stages, formatting and rendering. The result > of formatting is a tree where each node is a particular type of layout area. > I don't need to be any more specific than this for my question. > > The rendering step (which my design question relates to) involves walking > the layout area tree and producing output in a particular format. The way I > implement it, FOP can use different renderers (implementations of a Renderer > inteface) to produce different output formats, although the principal one at > the moment is a render for PDF (PDFRenderer). > > My question relates to the relationship between the classes representing > different area types in the layout area tree and the renderer class. > > They way I do it at the moment (which I don't really like) is PDFRenderer > has a method for handling each area type and as well as outputing the PDF > for the particular area type, the method iterates over the child nodes of > the layout area tree and calls other methods in the class on those child > nodes, using a series of "if A instanceof B" (which is the part I *really* > don't like). > > Here is what I am thinking of changing it to: > > * The classes representing the different layout area types have a static > "registerRenderer" method that takes the renderer as a parameter and puts it > in a static variable. > * The classes representing the different layout area types have a instance > method "render" that causes the appropriate method (for the particular > layout area type) of the registered render class to be called with "this" as > a parameter. > * After the layout area tree has been built, the first thing the renderer > does is call the registerRenderer method of each class representing a layout > area type, thus registering itself. > * The individual methods don't have a series of "if A instanceof B", any > more. They simply call the "render" method of whatever node in the layout > area tree is currently being traversed. > > Do people agree that this is a better approach? It seems to me to be a good > use of polymorphism. > > I look forward to your learned opinions > > Thanks > > James > -- > James Tauber / jtauber@xxxxxxxxxxx / www.jtauber.com > Maintainer of : www.xmlinfo.com, www.xmlsoftware.com and www.schema.net > <pipe>Ceci n'est pas une pipe</pipe> > > > > > > > > > > > --- > To unsubscribe, mail advanced-java-unsubscribe@xxxxxxxxxxxxxxxx > To get help, mail advanced-java-help@xxxxxxxxxxxxxxxx > --- To unsubscribe, mail advanced-java-unsubscribe@xxxxxxxxxxxxxxxx To get help, mail advanced-java-help@xxxxxxxxxxxxxxxx
- Prev by Date: focus event problem...
- Next by Date: On closing Java shell
- Previous by thread: focus event problem...
- Next by thread: On closing Java shell
- Index(es):