Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java mess if/then逻辑的设计建议_Java_Oop_Design Patterns - Fatal编程技术网

Java mess if/then逻辑的设计建议

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

我愿意为这种常见场景选择一种设计模式:

我有一个接收消息的模块(MessageListener)。 它接收的每个消息实际上都是一个对象(MyMessage1、MyMessage2、…)

我的消息1,我的消息2扩展了我的消息摘要

现在,当MessageListener对象(onMessage(..))检索消息时 我想根据消息实例执行一个不确定的“命令”。。大概是这样的:

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
执行两个步骤:

  • 找出收到了什么消息
  • 运行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消息){
    /*用味精做点什么*/
    }
    }
    公共类消息总线{
    
    映射所以实际上您的
    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的新类。该类需要处理一个全新的消息类型