Composite desing pattern & exception handling

Hi, I've been thinking about how to write a reusable composite object. Basically this would be a simple implementation of the composite pattern, but would be general enough that you could reuse it in many places. Here is an example?after the examples I talk about my problem.

/**

* Composite interface: General enough that 慸oOperation()?could be anything,

* e.g. filtering data, loading or saving state, etc.

*/

publicinterface ReusableComposite{

public Object doOperation(Object sharedData);

}

/**

* Base class for composite objects.

*/

publicabstractclass AbstractCompositeimplements ReusableComposite{

private Collection children =new ArrayList();

publicvoid add(ReusableComposite object){

children.add(object);

}

publicvoid remove(ReusableComposite object){

children.remove(object);

}

public Iterator getChildren(){

return children.iterator();

}

}

/**

* Performs some operation on all its children.

*/

publicabstractclass AllOperationextends AbstractComposite{

public Object doOperation(Object sharedData){

for(Iterator it = getIterator(); it.hasNext(); ){

ReusableComposite item = (ReusableComposite) it.next();

sharedData = doOperation(sharedData);

}

return sharedData;

}

}

// --

/**

* Example as some sort of filter:

*/

AbstractComposite licenseFilters =new AllOperator();

licenseFilters.add(new DeluxLicenseFilter());

licenseFilters.add(new StandardLicenseFilter());

licenseFilters.add(new PremiumEditionLicenseFilter());

AbstractComposite composite =new AllOperator();

composite.add(licenseFilters);

composite.add(new PrivilegeFilter());

composite.add(new TimezoneFilter());

// To apply all the filters, just go:

composite.doOperation(?;

The problem is that eventually you need to throw a checked exception.

It seems kind of lame to have 慸oOperation?method signature throwing some generic user written exception, especially when you reuse these classes and find you do not need any exception handling (i.e, you don抰 throw any checked exceptions in doOperation()).

It seems almost equally lame to do it any other way, e.g., wrapping checked exceptions in runtime exceptions and unwrapping them at the top, or maintaining two nearly identical frameworks, one with exception handling and one without?

It makes me think that perhaps it is not a good idea to implement a reusable composite implementation?but it seems so much code replication to re-write the above classes each time you use this pattern.

Any thoughts?

[4347 byte] By [jvaudrya] at [2007-10-2 10:31:50]
# 1

Hi,

I think this could be solved quite elegantly using a dynamic proxy, after having written the generic dynamic proxy glue you can then get a composite with an invocation like

Set<MySpecificInterface> components = ...

MySpecificInterface composed

= GenericComposer.getComposite(MySpecificInterface.class, components);

Once you wrote GenericComposer once, to use it you just need to write an interface and some components implementing it.

The method would look like this:

/** @param type the interface implemented by all the components

*@param components the components, every call to a method on the returned object will result in a call to the corresponding method of each component

* @return the composite instance of T

*/

public static T getComposite(Class<T> type, Set<T> components) {

//can I leave the implementation to you, I suggest instantiating a class (let's say GenericComposer<T>) with the passed values, and have a subclass of java.lang.reflect.InvocationHandler as inner class. This inner class is the used when calling java.lang.reflect.Proxy.newProxyInstance

}

cheers,

reto

netiquettea at 2007-7-13 2:16:17 > top of Java-index,Other Topics,Patterns & OO Design...