我正在尝试用Java创建一个消息传递系统。我有一个接口消息,它将有多个实现(例如 TextMessage 和 AudioMessage )。该接口将在服务器和客户端上都可用。
我的问题是客户端应根据从服务器收到的消息类型呈现不同的可视输出。因此,我要么必须知道我正在处理的消息的类型,我可以使用 instanceof(),或者我可以在Message接口中放置一个抽象方法并使用多态来使消息负责创建视觉输出。
然而,任何这样做都会感觉很脏,因为我每次都要创建一个新的 if instanceof block ,或者让 Message 来创建可视化部分,这应该是一种错误,因为它应该是某种模式。
有没有人有我可以在这里使用的解决方案或适当的设计模式?
谢谢!
答案 0 :(得分:7)
您可以使用Visitor Pattern。
interface Message{
public void accept(MessageVisitor visitor);
}
interface MessageVisitor{
public void visit(TextMessage message);
public void visit(AudioMessage message);
}
class PrintVisitor implements MessageVisitor{
public void visit(TextMessage message){
//print text message
}
public void visit(AudioMessage message){
//do step required
}
}
class TextMessage implements Message{
//other methods
public void accept(MessageVisitor visitor){
visitor.visit(this);
}
}
使用此double dispatch技术,您的instanceof
检查不是必需的。除了打印逻辑在PrintVisitor
类中出现之外,它还具有更大的灵活性。
visitor.visit(this);
在这一行中,您使用visit
在visitor
上呼叫this
,现在this
将使用 实际 实例的类型,因此将调用visitor
的方法将根据实际类型。
因为现在您可以向Message
课程添加新操作,而无需使用Message
s
Visitor
的实际代码
谨防一些垮台。当您的Message
层次结构发生变化时,它会导致所有Visitor
更改。所以要注意这一点。
答案 1 :(得分:2)
在Java中,您应该考虑创建一个访问者类型的模式:
public interface MsgVisitor{
public Command handleMsg(FooMsg msg);
public Command handleMsg(BarMsg msg);
public Command handleMsg(BazMsg msg);
}
abstract class MyMessage{
public Command visit(MsgVisitor visitor){
return visitor.handleMsg(this);
}
}
然后您将从管道中发出的内容发送到管道中,以便将正确的命令绑定到正确的消息类型。
Command
(使用Command pattern)与您需要处理的内容及其含义有关。因此,此访问者只是在那里汇集Commands
。它充当行动的代表点。这使您可以更丰富地处理和组装逻辑层次结构。
答案 2 :(得分:1)
您可以查看adapter pattern。通过这种方式,您可以清楚地区分消息和可视化,并且可以避免使用广泛的if子句。
基本上,您需要某种知道消息类型和可视化类型之间映射的映射类。此类可用于根据收到的消息请求可视化实例。