【问题标题】:Refactoring predecessor code重构前代代码
【发布时间】:2014-03-10 18:50:25
【问题描述】:

我想寻求帮助和一些建议如何重构我收到的源代码。 这是我的方法的伪代码:

    public void generalMethod(String type) {

     InputParameters params = new InputParameters();

      if (type.equals("someKey1"){
             decodeSomeKey1(params);
          } else if (type.equals("someKey2"){
             decodeSomeKey2(params);
          } else if (type.equals("someKey3"){
             decodeSomeKey3(params);
          } else if (type.equals("someKey4"){
             etc...
          }
      }
    }

所有方法都有相同的输入参数。在第一步中,我创建了新接口并为每个方法创建了实现创建接口的单独类。

interface ISomeInterfaceDecoder {
    void decode(InputParameters params);
}

class DecodeSomeKey1 implements ISomeInterfaceDecoder {

    @Override
    public void decode(InputParameters params) {
        // some implementation
    }
}

class DecodeSomeKey2 implements ISomeInterfaceDecoder {

    @Override
    public void decode(InputParameters params) {
        // some implementation
    }
}   

然后我创建工厂类如下:

类工厂{

    ISomeInterfaceDecoder getDecoder(String type) {
         if (type.equals("someKey1"){
             return new DecodeSomeKey1();
          } else if (type.equals("someKey2"){
             return new DecodeSomeKey2();
          } else if (type.equals("someKey3"){
             return new DecodeSomeKey3());
          } else if (type.equals("someKey3"){
             etc...
          }
      }
    }

}

这些更改后的代码如下所示:

类 SomeClass {

    Factory factory = new Factory();

    public void generalMethod(String type) {
         InputParameters params = new InputParameters();
         ISomeInterfaceDecoder decoder = factory.getDecoder(type); 
         decoder.decode(params);
       }
}

这个方法的代码看起来更好但是... 这种方法经常被调用。每次创建给定类的新实例时。这可能会导致性能问题。所以,我认为这不是解决这个问题的好方法。 你能给我一些建议我应该如何重构这段代码吗? 提前感谢您的帮助。

【问题讨论】:

    标签: java refactoring


    【解决方案1】:

    不要将键作为字符串,而是将其设为枚举。然后在枚举中你可以像这样实现 decode() 方法:

    public enum MyKeyEnum {
        VALUE1 {
            public void decode(InputParameters ip) {
                // do specific decoding for VALUE1
            }
        },
        VALUE2 {
            public void decode(InputParameters ip) {
                // do specific decoding for VALUE2
            }
        }
        ...
        ;
    
        public abstract void decode(InputParameters ip);
    }
    

    现在在调用代码中您可以执行以下操作:

    public void generalMethod(MyKeyEnum type) {
       InputParameters params = new InputParameters();
       type.decode(params);
    }
    

    优点是所有解码方法都在 1 个枚举中,您不需要为每个解码器指定一个特定的类。此外,当一个新值被添加到枚举中时,你不能忘记实现 decode 方法(否则它不会编译)。

    【讨论】:

      【解决方案2】:

      你能给我一些建议我应该如何重构这段代码吗?

      我没有看到任何提及自动化回归测试,这将是我的第一步,在继续之前放入一个测试套件(例如,通过 JUnit 或 TestNG)。

      在那之后,我可能会向Decoder 对象引入StringMap 键。

      但是把测试框架放在第一位。否则你永远不会真正知道你是否引入了错误或不同的操作模式。

      【讨论】:

        【解决方案3】:
        1. 在您的工厂中引入缓存/单例,即您只返回一次算法。另外,让你的工厂成为单身。

        2. 创建一个静态Map<String, ISomeInterfaceDecoder>,在其中将标识符映射到执行调用的算法,这意味着没有工厂类和算法实例化。仅当您有无状态算法时才有效。

        【讨论】:

        • 为什么要添加单例?他们很难测试。为什么需要缓存?这不是过早的优化吗?
        • 如果算法是无状态/不可变的,为什么要在每次调用时创建一个?与“过早优化”无关,而是了解代码的需求。
        • +1 用于建议 Map
        猜你喜欢
        • 1970-01-01
        • 2011-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多