根据"foreign"子类型采取特定操作,不带开关、强制转换等。我们可以以某种方式使用多态性吗?

Take specific action depending on "foreign" subtype, without switch, casts and so on. Can we use polymorphism somehow?

本文关键字:我们 转换 多态性 方式使 类型 foreign 操作 开关 根据      更新时间:2023-10-16

我多次遇到类似的问题,但都没有找到好的解决方案。下面是一个具体的例子,我现在正在与之斗争,但问题实际上是普遍的。

假设我们有一些应用程序,它从串行端口侦听二进制数据,对其进行解码,并在需要时发回一些数据。这是核心功能,它是由一种"核心"模块完成的。

这个核心模块发出事件。有一个抽象类型Event,它包含一些常见的数据,如事件时间,还有一些Event的子类:例如,有一个事件EventRawData,它在接收任何原始数据时发出,还有EventMessage,它在解码或发送消息时发出。

GUI监听这些事件,并在事件发生时采取一些操作。当然,确切的操作取决于确切的事件类型。问题是如何根据事件类型采取特殊操作。Event本身完全不知道任何类型的GUI(它不应该知道),所以,我不能向Event添加一些以某种方式显示此事件的虚拟方法。

天真的方法是使用某种switch:在C++中,我们会使用dynamic_cast,在Java中,它会是instanceof,等等。这是我以前做过的,我不喜欢它:

if (my_event instanceof EventRawData){
   // ...
} else if (my_event instanceof EventMessage){
   // ...
}

相反,我能想到的是:

也许我们可以为GUI发明一些接口,每个特定的GUI都应该实现这个接口。然后,每个事件可以有show()方法:

abstract class Event {
   // ...
   abstract void show(GuiAbstract gui);
   // ...
}

当这个方法被某个特定的GUI调用时,GUI应该在那里传递this。这可能就是现在所谓的"依赖注入"。

我也不喜欢这样:我希望Event完全不知道GUI。

或者,也许最好去掉基类Event,使每个事件完全独立,并分别侦听它们。我也不喜欢它:我真的希望所有事件都有一些公共数据(比如事件的时间)。

也许有一些我不知道的设计模式?感谢您的帮助。

如果将UI与域完全解耦,则必须在域和UI之间的某个位置具有类型的条件树。然而,一种选择是在工厂中"隐藏"条件树,并生成以多态方式工作的事件的"视图模型":

// DOMAIN LAYER
public class Event {
    // some data, completely agnostic of UI
}

// USER INTERFACE LAYER
public abstract EventViewModel {
    void show();
}
public class EventViewModelFactory {
    EventViewModel createFrom(Event event) {
        if (event instanceof EventA) {
            return EventAViewModel((EventA)event);
        }
        else if (event instanceof EventB) {
            return EventBViewModel((EventB)event);
        }
        //etc...
    }
}
相关文章: