代码重构帮助

时间:2010-10-18 23:59:17

标签: java design-patterns

我有一个这样的例子

class A {

   A() {}
   public C createC () {
      ...
   }

} 

class B {

   B() {}
   public C createC () {

   }
}

A和B的对象是基于

创建的
public enum D { ii, jj };

我看到的代码就像

一样
D d; 

switch (d) {
    case ii: (new A()).createC(); break;
    case jj: (new B()).createC(); break;
 };

如何避免遍布各地的开关箱?我理解代码不太清楚。

5 个答案:

答案 0 :(得分:3)

您可以创建一个Factory类:

public class ClassFactory {

     public static C createC(D type) {
         C c = null;
         switch (type) {
              case ii: 
                  c = new A(); 
                  break;
              case jj: 
                  c = new B(); 
                  break;
         };

         return c;

     }
}

然后在您的代码中执行:

C c = ClassFactory.createC(type);

Factory method pattern的Wiki条目与他们的PizzaFactory非常相似。

答案 1 :(得分:3)

我倾向于将创建代码添加到枚举。

enum D {
    ii {
        public void createC() { new A().createC(); }
    },
    jj {
        public void createC() { new B().createC(); }
    };

    public abstract void createC();
}

然后您可以用

替换开关
d.createC();

话虽如此,我也会考虑将createC方法设为静态或将createC代码移动到枚举而不是将其留在A和B类中。

如果你将A和B中的createC方法设为静态,则enum看起来像

enum D {
    ii {
        public void createC() { A.createC(); }
    },
    jj {
        public void createC() { B.createC(); }
    };

    public abstract void createC();
}

答案 2 :(得分:1)

我没有在这里看到重构机会。

我认为需要工厂。查看“工厂”设计模式。

我看到代码到处都是...... (后面是创建特定实例的条件)_是一个很大的提示。

基本上,你想要做的就是推动决定将哪个类实例化到一个地方的所有 ugliness 。首先,在您的示例中,A和B应共享一个超类或更好的实现一个定义public C createC()的接口。

工厂只不过是一个带有静态方法的类,它决定实例化哪个A或B.

    public class SomeFactory {
        public static YourInterface make(int someNumber) {
            switch (someNumber) {
                case 1: return new A();
                case 2: return new B();
                default:
                    throw new RuntimeException("unknown type");
                }
            }
        }

所以你要做的是:

YourInterface yi = SomeFactory.make(1);
C c = yi.createC();

或者

C c = SomeFactory.make(1).createC();

现在你的代码非常干净。创建SomeInterface的新实现?没问题,将其创建添加到工厂,您的代码仍然有效。如果您的申请make()费用昂贵,没问题,只需制作一个并重复使用它。

答案 3 :(得分:0)

createC方法添加到枚举D

public enum D {
  ii,
  jj;

  public C createC() {
    switch (this) {
      case ii:
        return new A().createC();
      case jj:
        return new B().createC();
    }
    return null;
  }
}

然后拨打D.createC()

答案 4 :(得分:0)

您给出一个switch语句作为示例,但由于未显示与该开关相关的其他条件,我认为建议一个特定的解决方案为时过早。如果你想考虑一系列对“切换”语句的回应,这里有一个链接:http://books.google.com/books?id=1MsETFPD3I0C&lpg=PP1&dq=refactoring&pg=PA82#v=onepage&q&f=false

如果其他条件实际上只是选择相同的条件来构造其中一个对象,请使用extract方法。