我有2个应用程序: application_1
和 applicaion_2
appplication_1
将不同类型的消息发送给application_2
有几种类型。我可以声明这些类型的枚举。
enum MessageType{
TYPE_1,
TYPE_2,
...
}
在application_2框架中我使用建议我写下API
public void handle(Object o){
//logic
}
我考虑如何构建类别分别处理每个消息。
我知道我可以为所有消息声明常见类型:
abstract class AbstractMessage{
MessageType type;
Object o;
//...
}
和在application_2
中,我可以像这样写SMTH:
MessageType mt = ((AbstractMessage) o).getType();
switch(mt){
case TYPE_1:
//handle TYPE_1
break;
case TYPE_2:
//handle TYPE_2
break;
....
}
但是这个代码看起来很丑。
请帮助找到更好的解决方案。
如果要使用polymorfism,则可以定义abstract
消息类:
abstract class AbstractMessage {
public abstract void doStuff();
//...
}
而不是使用enums
,而是为每个消息类型创建一个集体,以扩展抽象类并覆盖方法:
class Type1Message extends AbstractMessage {
@Override
public void doStuff() {
//handle TYPE_1
}
}
class Type2Message extends AbstractMessage {
@Override
public void doStuff() {
//handle TYPE_2
}
}
然后在您的handle
方法中:
((AbstractMessage) o).doStuff();
application_2
无论如何都需要知道它已收到的消息类型,因此不可避免的是某种switch
。但是,关键是只在一个地点 让此switch
。例如,您可以使用以下方法:
public MessageHandler getHandlerFor(MessageType messageType) {
switch (messageType) {
case TYPE_1: return Type1MessageHandler();
case TYPE_2: return Type2MessageHandler();
............
default: throw new IllegalArgumentException("No handler found for messageType: " + messageType);
}
}
然后,您将需要MessageHandler
的层次结构,该层次结构对应于策略模式:
public interface MessageHandler {
void handle();
}
MessageHandler
接口的每个实现都应提供MessageType
-特定处理逻辑。
您可以使用责任链模式。它与策略模式不同,因为您的消息指示每个应用程序执行的命令。从本质上讲,这是switch
正在做的。
您动态加载了与您的handle
方法实现接口的类(Pavlo的类一起使用一些修改,将其与Loris的抽象消息结合在一起(:
public interface MessageHandler
{
void handle (AbstractMessage msg);
}
Java具有服务提供商的概念,该概念是一种动态加载的方法(我敢肯定,如果您不符合您的需求,可以使用其他方法(。您可以在处理消息时迭代处理程序,并将每个处理程序传递给消息实例。每个处理程序都决定是否要处理消息。您甚至可以使handle
返回boolean
,以表明该链可以停止致电后续处理程序,如果您愿意。
您可以在每个应用程序中实现您要处理的消息类型的操作员。有很多方法可以解决此问题(加载处理程序并在启动时初始化每个人,在消息处理时加载它们等(,因此请选择适合您需求的操作人员。链接的服务提供商文章有一个简单的循环,展示了处理程序的加载。
不需要随着代码的修改而更改的switch
,您只需重新配置jar的构建方式即可。这也是开放闭合原理的一个很好的例子,其中您的代码不更改但开放为扩展。
也许下面类似。它确实有一个开关,但是每种类型的代码都在枚举中。
public class So43459907 {
public enum Type {
m1 {
@Override Object create(Object o) {
return o;
}
@Override void handle(Object o) {}
},
m2 {
@Override Object create(Object o) {
return o;
}
@Override void handle(Object o) {}
};
abstract Object create(Object o);
abstract void handle(Object o);
public static Object create(Type type,Object o) {
switch(type) {
case m1:
return m1.create(o);
case m2:
return m2.create(o);
default:
throw new RuntimeException("oops");
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}