Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 根据“采取具体行动”;“外国”;子类型,不带开关,强制类型转换等。我们可以用多态性吗?_Java_C++_Oop_Design Patterns - Fatal编程技术网

Java 根据“采取具体行动”;“外国”;子类型,不带开关,强制类型转换等。我们可以用多态性吗?

Java 根据“采取具体行动”;“外国”;子类型,不带开关,强制类型转换等。我们可以用多态性吗?,java,c++,oop,design-patterns,Java,C++,Oop,Design Patterns,我曾多次遇到类似的问题,但都没有找到好的解决办法。下面是一个具体的例子,我现在正在努力,但问题实际上是普遍的 假设我们有一个应用程序,它监听来自串行端口的二进制数据,对其进行解码,并在需要时发回一些数据。这是核心功能,由一种“核心”模块完成 这个核心模块发出事件。有一个抽象类型Event,它包含一些常见的数据,如事件时间,还有Event的一些子类:例如,有一个EventEventRawData,在接收任何原始数据时发出,还有一个EventMessage,在解码或发送消息时发出 有一个GUI监听这

我曾多次遇到类似的问题,但都没有找到好的解决办法。下面是一个具体的例子,我现在正在努力,但问题实际上是普遍的

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

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

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

<> >朴素的方法是使用某种代码>开关<代码>:在C++中,我们将使用<代码> DyrimeCase> <代码>,在java中,它将是<代码>实例< /COD> >等。这是我以前做过的,我不喜欢它:

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

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


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

如果您将用户界面与域完全分离,则必须在域和用户界面之间的某个位置创建一个条件类型树。但是,一种选择是在工厂中“隐藏”条件树,并生成多态工作的事件“视图模型”:

// 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...
    }
}

如果您将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...
    }
}

看起来像是一种。您可以使用类似的方法来实现这一点。您希望事件层次结构本身独立于GUI,但这并不意味着您不能从每个事件类型获得一个派生类,该类可以感知GUI。(或来自每个事件类型的多个派生类,每个派生类都包含在特定上下文中触发的功能,例如GUI、日志记录、持久性等)。通过使用多重继承,例如从EventMessage和GuiElement中私下派生EventMessageGuiElement,为特定事件类型实现GuiElement的某些虚拟函数,代码复制量将降至最低。@TartanLlama,非常感谢;我在Stroustrup读过访问者的拍子,《C++程序设计语言》,2013;但我忘了这个概念。现在,你帮我刷新了我的记忆,我已经实现了它,它工作得非常完美。请考虑把它写成答案,我当然接受。再次感谢你,这似乎是一种感谢。您可以使用类似的方法来实现这一点。您希望事件层次结构本身独立于GUI,但这并不意味着您不能从每个事件类型获得一个派生类,该类可以感知GUI。(或来自每个事件类型的多个派生类,每个派生类都包含在特定上下文中触发的功能,例如GUI、日志记录、持久性等)。通过使用多重继承,例如从EventMessage和GuiElement中私下派生EventMessageGuiElement,为特定事件类型实现GuiElement的某些虚拟函数,代码复制量将降至最低。@TartanLlama,非常感谢;我在Stroustrup读过访问者的拍子,《C++程序设计语言》,2013;但我忘了这个概念。现在,你帮我刷新了我的记忆,我已经实现了它,它工作得非常完美。请考虑把它写成答案,我当然接受。再次感谢。感谢您的回答,但是@TartanLlama在评论中建议的访问者模式()更合适:我们不必使用任何类型的
实例。感谢您的回答,但是访问者模式()@TartanLlama在评论中的建议更合适:我们不必使用任何类型的
实例。