有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

oop Java方法实现依赖于参数值

考虑一种方法

public void doSomething(String actionID){
switch (actionID){
    case "dance":
            System.out.print("I'm dancing");
            break;
    case "sleep":
            System.out.print("I'm sleeping");
            break;
    default: 
            System.out.print("I've no idea what I'm doing");
}

该方法的实现取决于参数的值。有没有更优雅的方式来实现这一点,或者有不同的设计模式来复制这种行为


共 (3) 个答案

  1. # 1 楼答案

    如果调用者通过传递不同的字符串来决定执行什么逻辑,那么为什么不让他们调用不同的方法呢

    public void doSomething(String actionID) {...}
    ...
    doSomething("dance");
    doSomething("sleep");
    

    VS:

    public void dance() {...}
    public void sleep() {...}
    ...
    dance();
    sleep();
    

    看起来你不必要地把所有的电话都转移到doSomething


    But the strings might not always be literals. What if you're taking them from the console?

    您可以提供从字符串到相应函数的静态映射:

    class MyClass {
        private static final Map<String, Consumer<MyClass>> map = new HashMap<>();
    
        static {
            map.put("sleep", MyClass::sleep);
            map.put("dance", MyClass::dance);
        }
    
        public void doSomething(String actionID) {
            map.getOrDefault(actionID, MyClass::doNothing).accept(this);
        }
    
        public void dance() {
            System.out.print("I'm dancing");
        }
    
        public void sleep() {
            System.out.print("I'm sleeping");
        }
    
        private void doNothing() {
            System.out.println("I've no idea what I'm doing");
        }
    }
    

    这使得有很多开关箱的场景变得更干净

  2. # 2 楼答案

    引入一个接口,例如

      public interface HumanState {
    
        public void tellMeWhatYouAreDoing();
      }
    

    将逻辑封装在不同的实现中

      public class DancingState implements HumanState {
        @Override
        public void tellMeWhatYouAreDoing() {
          System.out.println("I'm dancing");
        }
      }
    
      public class SleepingState implements HumanState {
    
        @Override
        public void tellMeWhatYouAreDoing() {
          System.out.println("I'm sleeping");
        }
      }
    
      public class UnknownState implements HumanState {
    
        @Override
        public void tellMeWhatYouAreDoing() {
          System.out.println("I've no idea what I'm doing");
        }
      }
    

    使用地图。例如

    public class HumanStateExample {
    
      public static void main(String[] args) {
        HumanStateExample humanStateExample = new HumanStateExample();
    
        humanStateExample.doSomething("dance");
        humanStateExample.doSomething("sleep");
        humanStateExample.doSomething("unknown");
      }
    
      private final HashMap<String, HumanState> humanStateMap;
    
    
      public HumanStateExample(){
        humanStateMap = new HashMap<String, HumanState>();
        humanStateMap.put("dance", new DancingState());
        humanStateMap.put("sleep", new SleepingState());
    
      }
    
      public void doSomething(String action) {
        HumanState humanState = humanStateMap.get(action);
        if(humanState == null){
          humanState = new UnknownState();
        }
    
        humanState.tellMeWhatYouAreDoing();
      }
    }
    
  3. # 3 楼答案

    下面是基于示例问题的命令模式的简单实现。我定义了一个包含两个方法的AbstractCommand抽象类。第一个方法createCommand()根据输入字符串名实例化一个命令类。这就是如何委托字符串输入来创建正确类型的命令。第二种方法是doAction(),它没有定义,稍后将由特定的具体命令类实现

    public abstract class AbstractCommand {
        public static AbstractCommand createCommand(String name) {
            try {
                String clsName = name + "Command";
                Class<?> cls = Class.forName(clsName);
                AbstractCommand command = (AbstractCommand) cls.newInstance();
    
                return command;
            }
            catch (Exception e) {
                System.out.println("Something went wrong.");
            }
        }
    
        public abstract void doAction();
    }
    
    public class DanceCommand extends AbstractCommand {
        public void doAction() {
            System.out.println("I'm dancing");
        }
    }
    
    public class TestCommandPattern {
        public void doSomething(String actionID) {
            AbstractCommand cmd = AbstractCommand.createCommand(actionID);
            cmd.doAction();
        }
    
        public static void main(String[] args) {
            TestCommandPattern test = new TestCommandPattern();
            test.doSomething("Dance");  // should print "I'm dancing"
        }
    }
    

    现在这个框架已经设置好了,您可以轻松地为原始问题中的各种类型的操作添加其他命令。例如,您可以创建一个SleepCommand类,该类将输出I'm sleeping,或者执行任何您想要的操作