2010-07-12 45 views
1

我想使用复合模式将一个对象接收到的呼叫转发给其他人。具有不同类型对象的复合图案

目前,接收端的物体都是一样的Abstract类型,但障碍是他们根据具体类型(认为不同的模型)选择性地接受不同类型的objet作为参数。

据我所看到的,有两个解决方案,但都不是令人满意的:

  • 使用instanceof来检测输入端类类型的对象。这通常被认为是一种不好的做法。
  • 尽可能多的有Lists,因为有输入类型。这带来了必须添加List以适应新的输入类型的问题,并且每个List必须依次进行明确处理。

我一直在接口方面想,但还没有提出一个可行的想法。什么是解决这个设计问题的方法?综合是否合适?

P.S:这是在mvc的上下文中。

回答

3

复合图案允许您将对象的集合视为与叶对象相同。

我想说的是,你可以做这样的事情:

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); 
     } 
    } 

} 

这就是复合对我意味着什么。你是对的 - 如果你不得不使用instanceof你做错了。

+0

是的,这也是我看到复合材料的方式。对于我所描述的内容,将会有一种方法让'Command'根据它的类型忽略参数Object。该对象仍然会使用相同的方法传递,但会让我回到在Command中使用'instanceof'。 – 2010-07-12 22:35:58

+0

我会说可能在具体类中有多个重载的方法签名和相应的实现。难道你不需要做什么? – duffymo 2010-07-12 22:40:00

+0

好吧,考虑一下,我想要做的是在想法上与在工厂中使用的选择过程相似,以根据它们的大小分隔项目(想象筛选)。不同的重载方法将是理想的,但是对象类型允许一些灵活性是一个障碍。也许我想的太难了,有一个更简单的方法。我想到的另一件事是可以抛出一个对象,忽略ClassCastException,并且只在引用不为null时才执行某些操作。 – 2010-07-12 23:20:45

0

我在Java Practices的StocksMonitor应用程序中找到了以下方法。这是主要的视图的在MVC上下文中的更新方法:

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(); 
    } 
    } 

的参考文献,其用于有选择地更新相应的视图不同的模型的实例。这种方法尊重组合模式,并允许根据参数实例进行逐案处理。当然,这只依赖于运行时使用的模型的一个实例。

+0

另一种可能性是创建一个包含某种类型标识符(如String)的自定义对象。这可以代替Object参数发送。 – 2010-07-13 21:08:38