如何根据消息类型进行不同的处理?

发布于 2024-07-18 20:02:05 字数 560 浏览 3 评论 0原文

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

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

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

认为这一点应该工作。

I have a process which has a "notify" method which receives as a parameter the base class of the message type. I'd like to do different processing based on the derived type of message. Does this mean I need to add a method called "process" or something similar to the message type, and invoke it using polymorphism? Is it better to add a "notify" for each specific message type?

More details: The language is C++. I thought notify would be a good idea here, so that I would only need one method to be notified of the various message types. The controller inherits from a listener class which specifies a pure vitual notify(MsgBaseClass) method. I still like that idea, since I don't have to add a notify for each new message type. But in the controller code itself, I don't see any way to distinguish between the message type other than something like dynamic cast, or adding a message type to the message.

edit: I think I'm going to go with the Visitor pattern. It allows me to keep just one method for the notify, and I can avoid a switch statement in my code. A "visitor" interface will specify the various methods needed by the listener to process the various derived message types. This will require only one message to be added to the Message base class, a pure virtual "accept(MyMessageTypeVisitor v). The derived message classes will implement it using v.visit(this);

I think this oughta work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

和影子一齐双人舞 2024-07-25 20:02:05

经典的面向对象答案要求基消息类提供一个抽象方法,具体的消息子类重写该方法以提供特定的处理。

一些(不是很普遍)语言,例如 Dylan 和 CLisp 提供“通用函数”(根据参数类型动态分派),可以彻底解决问题。

在流行语言中可行的一种灵活方法是 Uncle Bob 的“非循环访问者”设计模式,http:// /www.objectmentor.com/resources/articles/acv.pdf; 有关更多访客变体,请参阅 www.ccs.neu.edu/research/demeter/adaptive-patterns/visitor-usage/papers/plop96/variations-visitor-nordberg.ps 。

The classic OO answer requires the base message class to provide an abstract method which concrete message subclasses override to provide the specific processing.

Some (not very widespread) languages such as Dylan and CLisp provide "generic functions" (dispatched dynamically on argument types) that solve the problem quite drastically.

One flexible approach viable in popular languages is Uncle Bob's "Acyclic Visitor" design pattern, http://www.objectmentor.com/resources/articles/acv.pdf ; for more Visitor variants see www.ccs.neu.edu/research/demeter/adaptive-patterns/visitor-usage/papers/plop96/variations-visitor-nordberg.ps .

虫児飞 2024-07-25 20:02:05

编辑:我认为 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,多态性是要走的路。 我猜测您想要执行的处理逻辑类型不属于消息类,应该移动到单独的类中。 我更喜欢这种方法的另一个原因是,如果我添加其他消息,它不需要我更改被通知的类的结构。 如果只有一两种消息类型,这可能不是问题。

Edit: I think dirkgently has a good point, and that messages shouldn't know how to process themselves. Therefore the approach I described where messages could be used as factories isn't a good idea. I do think that an abstract process factory might be a good solution though.

Use an abstract factory to create an object that can handle the processing, and invoke it using polymorphism. This factory could possibly be included directly in the message class, or you could create a separate factory class that accepts the message type as a parameter and returns an appropriate object.

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

(Sorry if this is incorrect. My C++ is a bit weak, but I believe it illustrates the principle.)

This would allow you to just override getProcessor() for each message type, and create the appropriate processor there.

IMVHO, Polymorphism is the way to go. My guess it that the kind of processing logic that you want to do doesn't belong in the message class and should be moved to separate classes. Another reason that I would prefer this approach is that it doesn't require me to change the structure of the class being notified if I add additional messages. If there's only one or two message types, this might not be an issue.

怪我闹别瞎闹 2024-07-25 20:02:05

您可以执行以下操作:

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

只需尝试对每个处理的 DerivedType 进行动态转换。 如果你得到一个非空指针,那么你就知道你已经收到了你试图转换的类型。

You could do something like this:

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

Just try doing a dynamic_cast to each handled DerivedType. If you get a non-null pointer then you know that you have received the type you attempted to cast to.

油饼 2024-07-25 20:02:05

您是否被观察者设计模式所困扰?

重载的 notify 看起来像一个候选者。 观察者模式非常简单。 它基于好莱坞原则,即“不要给我们打电话,我们会给你打电话” !”。 这个想法是拥有一组对象(观察者)并通知他们而不是让他们查询你。 您将通用的Event 类型的数据传递给观察者。 应该由观察者来决定如何处理这个问题。 如果观察者对不同的事件做出反应,就会有一些dynamic_casts(是的,您也需要一个事件层次结构)。

Are you stuck with the observer design pattern?

Overloaded notify looks like a candidate. The observer pattern is really simple. It's based on the Hollywood Principle namely, "Don't call us, we'll call you!". The idea is to have a set of objects (observers) and notify them instead of having them query you. You pass in a generic Event sort of data to the observers. It should be left to the observer to decide what to do with this. There'd be some dynamic_casts if the observers react to different events (yes, you'd need an event hierarchy too).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文