[英]how to avoid “cascading if\case”-statements in a factory class
我必须根据具体情况创建一个 object。 我读到,解决方案可能是工厂模式,但就我而言,它有很多缺点。
例如:我有一个管理动物的应用程序。 在某个时候,客户给了我必须创建的动物列表。 使用工厂模式的解决方案应该是:
//PRODUCTS
public interface Animal {
String getCall();
}
public class Dog implements Animal {
public String getCall() {
return "Bau";
}
}
public class Cat implements Animal {
public String getCall() {
return "Miao";
}
}
public class Cow {...}
public class Rooster{...}
public enum AnimalEnum {
Cat, Dog, Cow, Rooster
}
//FACTORY
public class AnimalFactory {
public Animal getAnimal (AnimalEnum type){
Animal retval = null;
switch (type){
case Cat:
retval = new Cat();
break;
case Dog:
retval = new Dog();
break;
case Cow:[...]
case Rooster[...]
}
return retval;
}
}
在我看来,这是一种代码味道。 问题是我必须写一个案例陈述来检查客户想要什么类型的动物。 此外,如果将来我想创建一个新的 object “Tiger”,我必须更改所有工厂类。
我的问题是:有没有办法避免这种情况? 是否有一种模式允许我基于另一个参数创建 object 而无需像那样的“级联 if\case-of”?
我在想,使用命令模式,但最后我仍然有这种情况。
“代码气味”的概念及其相反的“干净代码”可以追溯到 Martin Fowler 和 Robert Martin,请参阅这篇文章,了解软件开发领域中嗅觉、卫生和道德明喻的细微差别。
至于这个问题,您认为这种对枚举进行的切换很臭的想法与 Martin Fowler 在“ 重构:改进现有代码的设计”的原始版本中是一致的,但他在2015 版中撤回了它。 对此没有达成共识,在 10 万名声望贡献者中也没有达成共识,例如,@tim-biegeleisen 宣称没有臭味,@mark-seemann 坚持认为,在 2015 年之后,只要宇宙存在,就必须如此随他的意。
至于您对那段特定代码的不满,您可以将实例创建移动到 Enum 本身,从而避免使用 switch 语句,也避免在扩充枚举时忘记添加额外的 switch 分支。
public enum AnimalEnum {
Cat(Cat::new),
Dog(Dog::new),
Cow(Cow::new),
Rooster(Rooster::new);
private final Supplier<Animal> createAnimal;
public Animal createInstance() {
return createAnimal.get();
}
AnimalEnum(Supplier<Animal> factory) {
this.createAnimal = factory;
}
}
预计该提议将基于个体嗅觉器官的配置引发争议,并围绕臭/干净的二分法展开方式与否。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.