Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.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 替换嵌套开关/ifelse的设计模式_Java_Design Patterns_Nested_Switch Statement - Fatal编程技术网

Java 替换嵌套开关/ifelse的设计模式

Java 替换嵌套开关/ifelse的设计模式,java,design-patterns,nested,switch-statement,Java,Design Patterns,Nested,Switch Statement,我在Java工作,我见过很多设计模式,并试图将我的问题融入其中,但不知何故,我就是找不到好的模式 以下是我收到的示例数据包: {String robot, String action, int duration} {"Humanoid", "Forward", 2} {"Humanoid", "Backward", 5} {"Snatcher", "Grab"} 这是我现在的代码: if "humanoid" { if "forward" { humanoid.forw

我在Java工作,我见过很多设计模式,并试图将我的问题融入其中,但不知何故,我就是找不到好的模式

以下是我收到的示例数据包:

{String robot, String action, int duration}
{"Humanoid", "Forward", 2}
{"Humanoid", "Backward", 5}
{"Snatcher", "Grab"}
这是我现在的代码:

if "humanoid" {
    if "forward" {
        humanoid.forward(duration);
    }
    if "backward" {
        humanoid.backward(duration);
    }
    ...
}else if "snatcher" {
    if "forward" {
        snatcher.forward(duration);
    }
    if "grab" {
        snatcher.grab();
    }
}
elseif ...
动态执行此操作的最佳方法是什么

我不想每次我想在嵌套的ifelse中添加一个新的robot及其所有可能的函数时都向ifelse添加一个节点

谢谢

编辑 与此同时,我被要求把问题分成两部分。机器人类型之间的切换将在其他地方完成,我将使用策略模式根据机器人在不同类型的动作之间切换


无论如何,谢谢你的回答!我相信它会有用的另一个时间或其他人

您可以使用dispatcher,以下是伪代码,不编译:

interface Executor { public void execute(); }
class RobotAction {
    String robot;
    String action;
    Executor executor;
}
然后进行一些设置:

list.add(new RobotAction("Humanoid", "Forward", new Executor() { public void execute() { humanoid.forward(5) }));
list.add(new RobotAction("Humanoid", "Backward", new Executor() { public void execute() { humanoid.backward(2) }));
list.add(new RobotAction("Snatcher", "Grab", new Executor() { public void execute() { snatcher.grab() }));
然后,您的方法变成:

public void dispatch(String robot, String action) {
    for (RobotAction robotAction : list) {
         if (robot.equals(robotAction.robot) && action.equals(robotAction.action)) {
             robotAction.execute();
         }
    }
}

因此,要添加新操作,您需要在列表中添加一些内容。更好的方法是从RobotAction->Executor获取地图;这将要求您实现equals&hashCode。

很难知道您在有限的信息下到底想做什么,但是如果您从某处收到一堆“操作请求”,并且需要不同的对象类以不同的方式处理它们,您可以这样做:

interface IActionHandler{
  void HandleAction(Action action);
}

class Humanoid: IActionHandler{
  void HandleAction(Action action){
    switch(action.ActionType){
       ActionType.Forward: Forward();
      ......
    }
  }
...
}

class Catcher: IActionHandler{
  void HandleAction(Action action){
    switch(action.ActionType){
       ActionType.Grab: Grab();
      ......
    }
  }
...
}

class MainActionReceiver{
  ReceiceActionRequest(Action action){
    GetActioner(action.Actioner).HandleAction(action);
  }

  IActionHander GetActioner(string actioner){
    if (actioner == "Humanoid"){
      return humanoidObject;
    }
    return catcherObject;
  }
}
Interface IExecuter<T>{   
  bool CanExecute(Action action)
  void Execute(T owner, Action action); 
}
请原谅这种半C风格——这正是我今天工作的地方

如果要避免HandleAction函数中的switch语句,可以创建ActionExecuter类来实际执行以下操作:

interface IActionHandler{
  void HandleAction(Action action);
}

class Humanoid: IActionHandler{
  void HandleAction(Action action){
    switch(action.ActionType){
       ActionType.Forward: Forward();
      ......
    }
  }
...
}

class Catcher: IActionHandler{
  void HandleAction(Action action){
    switch(action.ActionType){
       ActionType.Grab: Grab();
      ......
    }
  }
...
}

class MainActionReceiver{
  ReceiceActionRequest(Action action){
    GetActioner(action.Actioner).HandleAction(action);
  }

  IActionHander GetActioner(string actioner){
    if (actioner == "Humanoid"){
      return humanoidObject;
    }
    return catcherObject;
  }
}
Interface IExecuter<T>{   
  bool CanExecute(Action action)
  void Execute(T owner, Action action); 
}

这对于你正在做的事情来说很可能是杀伤力过大,但是你的所有动作和动作执行器都被清晰地封装在它们自己的类中。

什么是类人的和抓取者?它们是同一类的实例,还是共享一个公共超类,还是完全无关?