views:

66

answers:

2

I'd like to use the Composite pattern for forwarding calls received by one object to others.

At present, objects on the receiving end are all of the same Abstract type but the snag is that they selectively accept different types of objet as parameters according to their concrete type (think different models).

As far as I can see, there are two solutions but neither is satisfactory:

  • Use instanceof to detect the class type objects on the input side. This is often said to be a bad practise.
  • Make as many Lists as there are input types. This brings the problem that a List has to be added to accomodate a new input type and each List has to be explicitely processed in turn.

I've been thinking in terms of interfaces but have not come up with a feasible idea as of yet. What would be a solution to this design issue? Is a composite appropriate at all?

P.S: This is in the context of an mvc.

+2  A: 

Composite pattern allows you to treat a collection of objects the same as a leaf object.

I'd say that you could do something like this:

public interface Command
{
    void execute(Object parameter);
}

public class LeafCommand implements Command
{
    public void execute(Object parameter)
    {  
        // do something for a leaf
    }
}

public class CompositeCommand implements Command
{
    private List<Command> commands;

    void execute(Object parameter)
    {
        for (Command child : commands) 
        { 
           child.execute(parameter);
        }
    }

}

That's what Composite means to me. You're right - if you have to use instanceof you've done it wrong.

duffymo
Yes, that's the way I see composite as well. For what I've described what would be great would be a way to have a `Command` ignore a parameter Object according to it's type. The object would still be passed on using the same method but would bring me back to using `instanceof` inside `Command`.
James P.
I would say it's possible to have multiple overloaded method signatures and corresponding implementations inside the concrete classes. Couldn't that do what you need?
duffymo
Well, thinking about it, what I'm trying to do is similar in idea to the selection process used in factories to separate items according to their size (think sieve). Different overloaded methods would be ideal but the Object type which is there to allow for some flexibility is an obstacle. Maybe I'm thinking too hard and there's a simpler approach. Another thing I thought of was the possibility of casting an object, ignoring ClassCastException and only doing something if a reference is not null.
James P.
I'm about to post an answer below that should do the trick.
James P.
A: 

I've found the following approach in the StocksMonitor application at Java Practises. This is the update method of the Main view in an mvc context:

  public void update(Observable aObservable, Object aData) {
    fLogger.fine("Notify being broadcast...");
    if (aObservable == fCurrentPortfolio) {
      fLogger.fine("Notified by Current Portfolio...");
      synchTitleBarWithCurrentPortfolio();
    }
    else if (aObservable == fGeneralLookPrefs) {
      fLogger.fine("Notified by General Look...");
      synchGuiWithGeneralLookPrefs();
    }
  }

The references are instances of different models which are used to selectively update corresponding views. This approach respects the composite pattern and allows case-by-case processing according to the parameter instance. Of course, this relies on only one instance of a model being used at runtime.

James P.
Another possibility is to make a custom object containing an identifier of some sort such as a String. This could be sent in place of the Object parameter.
James P.