gpt4 book ai didi

java - 我应该如何在 Java 中实现 Message 类的子类型?

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:55:57 32 4
gpt4 key购买 nike

我确信这是一个基本的 OOP 问题——我正在设计一个消息传递系统,其中有几种完全不同的消息格式,但我希望它们都能够放置在 PriorityBlockingQueue 中。我的第一个想法是定义一个抽象类 Message,然后为每个消息类型定义扩展 Message 的子类。但这意味着,在接收端,消息处理器需要识别子类,以便知道如何处理消息的内容。我知道这样做的唯一方法是使用 .instanceof()Class. 并且它似乎不正确。

正如 Scott Meyers 所写,

Anytime you find yourself writing code of the form "if the object is of type T1, then do something, but if it's of type T2, then do something else," slap yourself.

(他继续指出,在多态性中,您应该为每个子类使用具有不同实现的相同方法名称。我不知道如何让这个想法在我的案例中起作用——消息类型本身完全无关。)

为了便于讨论,这里是我的消息类型:

  • ConsoleMessage,标识一个 ConsoleObject 和一个 ObjectState。
  • CardReaderRequestMessage,不包含任何内容,只是请求“下一张卡片”
  • CardReaderMessage,包含 byte[80] 卡片图像和 Last Card 指示符
  • CardPunchMessage,包含一个字节[80]的卡片图像
  • CardPunchResponseMessage,不包含任何内容,只表示卡片图像已复制到打卡缓冲区

我相信我必须知道我正在处理的消息类型,所以我怀疑我不应该使用多态消息。我应该如何正确设计它?

===== 编辑以提出后续问题 =====

我试图找到一种使用多态消息的方法,而无需在某些时候识别其子类。建议的方法是覆盖每个子类中的 process() 方法。这是我的(简化的)抽象消息和两个子类:

public abstract class Message {

public abstract void process() {
// subclasses of Message implement this
}

public static class ConsoleMessage extends Message {
private int obj;
private int state;
public ConsoleMessage(int x, int y) {
obj = x;
state = y;
}
@Override
public void process() {
// do something with obj and state?
}

public static class CardReaderMessage extends Message {
private byte[] card;
private boolean lastCardIndicator;
public CardReaderMessage(byte[] c, boolean lc) {
card = c;
lastCardIndicator = lc;
}
@Override
public void process() {
// do something with card and lastCardIndicator
}
}

对于所有“入站”消息,每个线程都有一个队列。假设我的线程需要等待来自控制台的消息“恢复”,但同时应该接收和处理其他消息类型:

waitForResumeMessage() {
while (true) { // the following will block until a msg arrives
Message msg = inboundMessageQueue.receiveMessage();
msg.process();

但是现在呢? process() 的某些实现已将一些数据移动到某处,但最终我需要能够编写:

        if // msg was ConsoleMessage "resume" command
return; // .. from waitForResumeMessage()
} // else iterate until another message
}

这基本上意味着找出“msg”属于哪个类。

我是不是完全错了?我意识到“等待”在“事件驱动”模型中并不合适,但这是一个长时间运行的后台 worker 。也许使用 process() 的想法对于更改引导事件驱动线程的 FSM 的状态更有用?

最佳答案

你没疯。该参数:

Anytime you find yourself writing code of the form "if the object is of type T1, then do something, but if it's of type T2, then do something else," slap yourself.

只是故事的一方面。故事的另一面是,保持关注点分离同样重要(如果不是更重要的话)。一个常见的例子是,您不应该仅仅因为它可以在模型中进行多态处理就将表示代码添加到您的模型中。不幸的是,Java 语言在同时实现这两个理想方面并没有太大帮助。

有很多方法可以保持“并行但解耦”的代码。 Visitor pattern是一个,就像一个大开关或 if-instance-of block 一样。另一种选择是具体类到具体类的 Map

关于java - 我应该如何在 Java 中实现 Message 类的子类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6798280/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com