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