重构if语句以使用适当的模式

我有一个枚举与它的一些国家:

enum State
{
    A,
    B,
    C,
    D
}

以及具有相应状态的对象:

class MyObject
{
    State state;
}

我需要编写一个带有两个MyObject实例的算法,并根据这些实例的特定状态执行一些操作:

void doWork(MyObject o1, MyObject o2)
{
     if (o1.state == A && o2.state == A)
     {
          // do something
     }
     else if (o1.state == A && o2.state == B)
     {}
     // etc for all combinations...

}

显然这种方法有很多问题,我想将其改为理想地摆脱if / else语句。

这种要求是否有任何模式?

谢谢


你可以做什么,虽然我不确定它会更好些,但它是两种state值的所有可能组合的矩阵; 你可以使用o1.stateo2.state作为索引进入该矩阵。

你可以在该矩阵中存储不同的东西:

  • 一个独特的值,你可以用它作为switch块的识别值,它可以替代你的if .. else if .. else块 - 真的没什么进步。
  • 或者你的矩阵可能包含...

  • 命令对象。 (查找命令模式。)
  • 如果你真的想摆脱if语句,那么第二种选择可能会更好; 但是,请注意,您的代码将不再在一个位置靠近在一起,就像if / switch块一样,但会遍布在几个不同的命令对象/类中。

    // forgive my syntax errors etc., my Java has definitely gone a little rusty!
    
    interface WorkCommand {
        public abstract void run(MyObject o1, MyObject o2);
    }
    
    ...
    
    Map<Pair<State,State>, WorkCommand> commands;
    // ^ pseudo-code type for your command look-up map; type Pair<X,Y> doesn't exist,
    //   so replace this with something sensible!
    
    void doWork(MyObject o1, MyObject o2)
    {
        WorkCommand worker = commands.get(new Pair<State,State>(o1, o2));
        worker.run(o1, o2);
    }
    

    你可以用这种方法来构建一个方法,你可以在你的枚举中使用一个抽象方法,每个元素都可以实现:

    enum State
    {
        A{
          public void void doSomeWork(State state){
            switch(state){
               case A:
               case B:
               ...
            }
          }
        },
        B,
        C,
        D
    
        abstract void doSomeWork(State state);
    }
    

    那么你的方法可以看起来像

    void doWork(MyObject o1, MyObject o2){
       o1.state.doSomeWork(o2.state);
    }
    

    是的,它被称为...状态模式。 重要的是只有一个状态可以定义行为,也就是说你可能需要将你的object1.state和object2.state组合成一个元状态。 用statecontext注册这个元状态,这样当Myobject.state更改元状态时就会更新。

    interface MyObjectStates {
      void doWork(MyObject o1, MyObject o2);
    }
    
    class MyObjectStatesAA implements MyObjectStates {
      void doWork(MyObject o1, MyObject o2) {
        // do dowork for both states A
      }
    
    class MyObjectStatesBB implements MyObjectStates {
      void doWork(MyObject o1, MyObject o2) {
        // do dowork for both states B
      }
    
    // etc
    

    然后,您需要在statecontext中保存一个MyObjectStates对象,并在更改MyObject.state时更新它。 你甚至可以全部移除状态枚举。 如果这种方法听起来很有趣,你给我一个笔记,我会详细说明你是否喜欢。

    状态模式的优点是不需要保存和读回枚举并相应地选择不同的代码路径,而是提供单独的代码与每个不同的状态。

    链接地址: http://www.djcxy.com/p/91843.html

    上一篇: Refactor if statement to use appropriate pattern

    下一篇: How to check equals on enum value?