我有一个这样的例子
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;
};
如何避免遍布各地的开关箱?我理解代码不太清楚。
答案 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方法。