2009-05-02 90 views
1

我有一个具有“notify”方法的进程,它接收消息类型的基类作为参数。我想根据派生类型的消息做不同的处理。这是否意味着我需要添加一个名为“process”或类似于消息类型的方法,并使用多态性调用它?为每个特定的消息类型添加“通知”会更好吗?如何根据消息类型处理不同的处理?

更多细节:语言是C++。我认为通知在这里是一个好主意,所以我只需要一种方法来通知各种消息类型。控制器从指定纯虚通知(MsgBaseClass)方法的侦听器类继承。我仍然喜欢这个想法,因为我不必为每个新消息类型添加通知。但是在控制器代码本身中,除了动态类型转换之外,我没有看到任何区分消息类型或向消息添加消息类型的方法。

编辑:我想我要去与访客模式。它允许我只保留一个通知的方法,并且可以避免在代码中使用switch语句。 “访问者”接口将指定侦听器处理各种派生消息类型所需的各种方法。这将只需要一个消息被添加到消息的基类,纯虚“接受(MyMessageTypeVisitor v)的派生消息类别将利用v.visit实现它(这);

认为这个现在应该工作

回答

1

经典的OO答案要求基类消息类提供一个抽象方法,其中具体的消息子类覆盖以提供特定的处理。

Dylan和CLisp等一些(不是很普遍)的语言提供了“通用函数”(在参数类型上动态调度),可以非常彻底地解决问题。

在流行语言中可行的一种灵活方法是Bob叔叔的“Acyclic Visitor”设计模式,http://www.objectmentor.com/resources/articles/acv.pdf;欲了解更多访客变体,请访问www.ccs.neu.edu/research/demeter/adaptive-patterns/visitor-usage/papers/plop96/variations-visitor-nordberg.ps。

1

编辑:我认为dirkgently有一个很好的观点,并且这些消息不应该知道如何处理自己,因此我描述的消息可以用作工厂的方法并不是一个好主意。认为抽象工艺工厂可能是一个很好的解决方案。

使用抽象工厂来创作一个可以处理处理的对象,并使用多态性调用它。这个工厂可能直接包含在消息类中,或者你可以创建一个单独的工厂类来接受消息类型作为参数并返回一个合适的对象。

class Message { 
public: 
    virtual Processor *getProcessor() = 0; 
    // other methods 
}; 

class Processor { 
public: 
    virtual void doWork() = 0; 
}; 

class MyListener : Listener { 
public: 
    void notify(Message *message); 
}; 

void MyListener::notify(Message *message) { 
    Processor *proc = message->getProcessor(); 
    proc->doWork(); 
}; 

(很抱歉,如果这是不正确。我的C++是有点弱,但我相信它说明原理。)

这将允许你只覆盖getProcessor()每个消息类型,在那里创建适当的处理器。

IMVHO,多态是要走的路。我猜想你所要做的处理逻辑不属于消息类,应该移到不同的类中。我更喜欢这种方法的另一个原因是,如果我添加其他消息,它不需要我更改要通知的类的结构。如果只有一种或两种消息类型,这可能不是问题。

0

你是否坚持观察者设计模式?

Overloaded notify看起来像一个候选人。观察者模式非常简单。它基于the Hollywood Principle,即“不要打电话给我们,我们会打电话给你!”。这个想法是有一组对象(观察者)并通知他们而不是让他们查询你。您向观察者传递一种通用的Event类型的数据。应由观察员决定如何处理。如果观察者对不同的事件作出反应(是的,你还需要一个事件层次结构),那么会有一些dynamic_casts

+0

嗨德克, 我给主要问题增加了一些细节。 – 2009-05-02 16:50:25

+0

我喜欢动态演员主意的简单性。但是将处理与消息本身打包在一起更“OO”,不是吗? – 2009-05-02 17:06:59

0

你可以做这样的事情:

DerivedType *dt = dynamic_cast<DerivedType>(&BaseType); 
if(dt != NULL) 
{ 
    // Handle processing of DerivedType 
} 

刚刚尝试做一个dynamic_cast的每个处理DerivedType。如果你得到一个非空指针,那么你知道你已经收到了你想要转换的类型。