Java mess if/then逻辑的设计建议
我愿意为这种常见场景选择一种设计模式: 我有一个接收消息的模块(MessageListener)。 它接收的每个消息实际上都是一个对象(MyMessage1、MyMessage2、…) 我的消息1,我的消息2扩展了我的消息摘要 现在,当MessageListener对象(onMessage(..))检索消息时 我想根据消息实例执行一个不确定的“命令”。。大概是这样的:Java mess if/then逻辑的设计建议,java,oop,design-patterns,Java,Oop,Design Patterns,我愿意为这种常见场景选择一种设计模式: 我有一个接收消息的模块(MessageListener)。 它接收的每个消息实际上都是一个对象(MyMessage1、MyMessage2、…) 我的消息1,我的消息2扩展了我的消息摘要 现在,当MessageListener对象(onMessage(..))检索消息时 我想根据消息实例执行一个不确定的“命令”。。大概是这样的: onMessage(My_Message_Abstract msg) { if (msg instance of My_M
onMessage(My_Message_Abstract msg)
{
if (msg instance of My_Message1)
{
doSomething()..
}
else if(msg instance of My_Message2)
{
doSomethingElse()..
}
}
public class Message1Listener implements MessageListener {
onMessage(SpecificMessage1 msg) {
/* do something with msg */
}
}
public class MessageBus {
Map<Class<? extends Message>, MessageListener> listeners = new HashMap<>();
void register(MessageListener listener, Class<? extends Message> msgType) {
listeners.put(msgType, listener);
}
void onMessage(Message msg) {
listeners.get(msg.getClass()).onMessage(msg);
}
}
我想摆脱这个锅炉如果/然后代码,并有它更好的未来-维护/动态/插件能力/整洁的方式
所以我采用了命令设计模式。我发现我可以有这样的东西:
在MessageListener中,要获得映射,请执行以下操作:
Map<Integer, MessageCommand> messageCommandsMap = new HashMap<Integer, MessageCommand>();
..
sessionTargetMap.put(MSG_1_TYPE, new Message1Command());
sessionTargetMap.put(MSG_2_TYPE, new Message2Command());
(Message1Command,Message2Command implements from Command interface)
onMessage(My_Message_Abstract msg)
{
messageCommandsMap.get(msg.getType).executeCommand(msg);
}
Map messageCommandsMap=newhashmap();
..
sessionTargetMap.put(MSG_1_类型,newmessage1command());
sessionTargetMap.put(MSG_2_类型,newmessage2command());
(Message1命令、Message2命令通过命令界面实现)
onMessage(我的消息摘要消息)
{
messageCommandsMap.get(msg.getType).executeCommand(msg);
}
我不喜欢MessageListener中的hashmap思想,因为我将所有命令耦合到该对象(MessageListener)
作为此线程提供的解决方案:
你知道我该如何改进吗?
Mybe我应该使用其他模式来实现这个想法吗
谢谢,我采取的方法是用一个公共接口来修饰这些类,使我能够利用Java函数的虚拟特性。例如,我会这样做:
public interface CoolInterface
{
void doSomething();
}
My_Message_Abstract implements CoolInterface
{
public abstract void doSomething();
}
Message1Command extends My_Message_Abstract
{
public void doSomething(){ System.out.println("First");
}
Message2Command extends My_Message_Abstract
{
public void doSomething(){ System.out.println("");
}
My_Message_Abstract implements CoolInterface
{
public void doSomething()
{
System.out.println("Default");
}
}
Message1Command extends My_Message_Abstract
{
public void doSomething(){ System.out.println("First");
}
Message2Command extends My_Message_Abstract
{
// no need to override the method just invoke doSomething as normal
}
您的代码现在变成:
onMessage(My_Message_Abstract msg)
{
msg.doSomething();
}
如果要委派,请执行以下操作:
public interface CoolInterface
{
void doSomething();
}
My_Message_Abstract implements CoolInterface
{
public abstract void doSomething();
}
Message1Command extends My_Message_Abstract
{
public void doSomething(){ System.out.println("First");
}
Message2Command extends My_Message_Abstract
{
public void doSomething(){ System.out.println("");
}
My_Message_Abstract implements CoolInterface
{
public void doSomething()
{
System.out.println("Default");
}
}
Message1Command extends My_Message_Abstract
{
public void doSomething(){ System.out.println("First");
}
Message2Command extends My_Message_Abstract
{
// no need to override the method just invoke doSomething as normal
}
我采用的方法是用一个公共接口来修饰这些类,使我能够利用Java函数的虚拟特性。例如,我会这样做:
public interface CoolInterface
{
void doSomething();
}
My_Message_Abstract implements CoolInterface
{
public abstract void doSomething();
}
Message1Command extends My_Message_Abstract
{
public void doSomething(){ System.out.println("First");
}
Message2Command extends My_Message_Abstract
{
public void doSomething(){ System.out.println("");
}
My_Message_Abstract implements CoolInterface
{
public void doSomething()
{
System.out.println("Default");
}
}
Message1Command extends My_Message_Abstract
{
public void doSomething(){ System.out.println("First");
}
Message2Command extends My_Message_Abstract
{
// no need to override the method just invoke doSomething as normal
}
您的代码现在变成:
onMessage(My_Message_Abstract msg)
{
msg.doSomething();
}
如果要委派,请执行以下操作:
public interface CoolInterface
{
void doSomething();
}
My_Message_Abstract implements CoolInterface
{
public abstract void doSomething();
}
Message1Command extends My_Message_Abstract
{
public void doSomething(){ System.out.println("First");
}
Message2Command extends My_Message_Abstract
{
public void doSomething(){ System.out.println("");
}
My_Message_Abstract implements CoolInterface
{
public void doSomething()
{
System.out.println("Default");
}
}
Message1Command extends My_Message_Abstract
{
public void doSomething(){ System.out.println("First");
}
Message2Command extends My_Message_Abstract
{
// no need to override the method just invoke doSomething as normal
}
您可以有一个MessageCommand工厂,它基本上知道给定消息类型要使用哪个MessageCommand。在factory中,您可以使用映射或if/else来标识命令类 现在,您的消息侦听器要求工厂根据类型给出适当的消息命令,然后每个消息命令都包含有效处理命令(doSomethingElse)方法的逻辑 代码外观的抽象概念:
class MessageCommandFactory {
Command get(MessageType messageType) {
if(messageType == MSG_1_TYPE) {
return new Message1Command();
} else ...
}
class MessageListener {
MessageCommandFactory messageCommandFactor;
onMessage(My_Absctract_Message message) {
Command command = messageCommandFactory.get(message.getType());
command.execute();
}
}
您可以有一个MessageCommand工厂,它基本上知道给定消息类型要使用哪个MessageCommand。在factory中,您可以使用映射或if/else来标识命令类 现在,您的消息侦听器要求工厂根据类型给出适当的消息命令,然后每个消息命令都包含有效处理命令(doSomethingElse)方法的逻辑 代码外观的抽象概念:
class MessageCommandFactory {
Command get(MessageType messageType) {
if(messageType == MSG_1_TYPE) {
return new Message1Command();
} else ...
}
class MessageListener {
MessageCommandFactory messageCommandFactor;
onMessage(My_Absctract_Message message) {
Command command = messageCommandFactory.get(message.getType());
command.execute();
}
}
因此,实际上您的
MessageListener
执行两个步骤:
MessageListener
为消息执行以下特定操作:
onMessage(My_Message_Abstract msg)
{
if (msg instance of My_Message1)
{
doSomething()..
}
else if(msg instance of My_Message2)
{
doSomethingElse()..
}
}
public class Message1Listener implements MessageListener {
onMessage(SpecificMessage1 msg) {
/* do something with msg */
}
}
public class MessageBus {
Map<Class<? extends Message>, MessageListener> listeners = new HashMap<>();
void register(MessageListener listener, Class<? extends Message> msgType) {
listeners.put(msgType, listener);
}
void onMessage(Message msg) {
listeners.get(msg.getClass()).onMessage(msg);
}
}
公共类Message1Listener实现MessageListener{
onMessage(SpecificMessage1消息){
/*用味精做点什么*/
}
}
公共类消息总线{
映射所以实际上您的MessageListener
执行两个步骤:
找出收到了什么消息
运行appropiate命令
您可以像@Woot4Moo那样将“running”委托给消息本身,或者使用子类MessageListener
为消息执行以下特定操作:
onMessage(My_Message_Abstract msg)
{
if (msg instance of My_Message1)
{
doSomething()..
}
else if(msg instance of My_Message2)
{
doSomethingElse()..
}
}
public class Message1Listener implements MessageListener {
onMessage(SpecificMessage1 msg) {
/* do something with msg */
}
}
public class MessageBus {
Map<Class<? extends Message>, MessageListener> listeners = new HashMap<>();
void register(MessageListener listener, Class<? extends Message> msgType) {
listeners.put(msgType, listener);
}
void onMessage(Message msg) {
listeners.get(msg.getClass()).onMessage(msg);
}
}
公共类Message1Listener实现MessageListener{
onMessage(SpecificMessage1消息){
/*用味精做点什么*/
}
}
公共类消息总线{
Map在类似的情况下,我从您已有的开始,但添加了一个方法:
addMessageListener(int messageType, MessageCommand messageCommand)
此外,其他类需要一种方法来“定位”您的类。最简单的方法是使用上述方法public static,如果这种方法对您的环境有效的话……但也可以使用其他适当的发现方法
该方法只会添加到您已有的映射中
如果两个命令希望侦听同一条消息,则可以通过将地图的“值”一侧设置为列表来轻松调整
此外,您始终可以使用一些已“预注册”的预定义命令启动映射,或者从某些类型的配置中读取预注册信息……等等
示例1:假设您有一个名为NewMessageHandler的新类。该类需要处理一个全新的消息类型。在适当的时候,当NewMessageHandler初始化自身时,if还可以将自身注册为侦听器。它必须“找到”dispatcher类(希望是单例),然后可以调用addMessageListener()
示例2:Dispatcher类可以读取一个配置文件,该文件定义了将处理消息的消息类型和类对
public class Dispatcher
{
public static Dispatcher getInstance()
{
//return the instance. Could accept parms for more complex needs
}
public void addMessageListener(int messageType, MessageCommand messageCommand)
{
//Add to the internal map
}
private void init()
{
//Optionally, read config file or System properties, and call addMessageListener()
}
private void dispatchMessage(Message msg)
{
//Look up map and dispatch to the registered instance
//Call the handleMessage() method on the appropriate listener
}
}
接口
public interface MessageCommand
{
public void handleMessage(Message msg);
}
另一个
public class NewMessageHandler implements MessageCommand
{
private void init()
{
Dispatcher.addMessageListener(666, this)
}
public void handleMessage(Message msg)
{
}
}
在类似的情况下,我从您已有的开始,但添加了一个方法:
addMessageListener(int messageType, MessageCommand messageCommand)
此外,其他类需要一种方法来“定位”您的类。最简单的方法是使用上述方法public static,如果这种方法对您的环境有效的话……但也可以使用其他适当的发现方法
该方法只会添加到您已有的映射中
如果两个命令希望侦听同一条消息,则可以通过将地图的“值”一侧设置为列表来轻松调整
此外,您还可以使用一些预先确定的命令“预注册”开始映射,或者从某种类型的配置中读取预注册信息……等等
示例1:假设您有一个名为NewMessageHandler的新类。该类需要处理一个全新的消息类型