如何避免工厂类中的“级联if \ case"语句 [英] how to avoid "cascading if\case"-statements in a factory class

查看:107
本文介绍了如何避免工厂类中的“级联if \ case"语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须根据特定情况创建一个对象.我读到,解决方案可能是工厂模式",但就我而言,它有很多缺点.

I have to create an object based on a specific situation. I read, that the solution could be the Factory Pattern, but in my case it has a lot of disadvantages.

例如:我有一个管理动物的应用程序.在某个时候,客户给我列出了必须创建的动物清单.使用工厂模式的解决方案应该是:

For instance: I have an application that manages animals. At some point a client gives to me a list of animals that must be created. A solution by using the factory pattern should be:

//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;
    }
}

我认为这是一种代码气味.问题是我必须写案例证明,以检查客户想要哪种动物. 此外,如果将来我想创建一个新的对象"Tiger",则必须更改所有工厂类.

In my opinion this is a code smell. The problem is the case-statement that I have to write in order to check what type of animal the client wants. Furthermore, if in the future I want to create a new object "Tiger", I have to change all the factory classes.

我的问题是:有办法避免这种情况吗?是否有一种模式可以让我根据另一个参数创建对象,而不必像这样级联if \ case-of"?

My question is: is there a way to avoid this situation? Is there a pattern that allows me to create an object based on another parameter without having "cascading if\case-of" like that?

我当时想使用命令模式,但最后我仍然遇到这种情况.

I was thinking, to use the command pattern, but at the end I still have this situation.

推荐答案

代码气味"的概念及其对立的干净代码"可以追溯到马丁·福勒和罗伯特·马丁,有关嗅觉,卫生

The notion of "code smell" and its opposite, "clean code", goes back to Martin Fowler and Robert Martin, see this post for the nuances of olfactory, hygienic and moral simile in the area of software development.

关于该问题,您的想法是,这种对枚举的转换会产生臭味,这与马丁·福勒(Martin Fowler)的原始版本"坚持存在也是在2015年之后,根据他的喜好,只要宇宙存在就必须如此.

As to the question, your notion that this sort of switch over an enum stinks is consistent with Martin Fowler as of the original edition of "Refactoring: Improving the Design of Existing Code", but he retracted it in the 2015 edition. There's no consensus on that, also not among several 100K reputation contributors, e.g. @tim-biegeleisen proclaims that there is no stink, @mark-seemann insists that there is, also after 2015, and necessarily so as long as the universe exists, according to his inclination.

从对特定代码的不满开始,您可以将实例创建移至Enum本身,从而避免使用switch语句,并且避免在增加枚举时忘记添加其他switch分支.

As of the grievance you feel about that particular piece of code, you could move the instance creation to the Enum itself, thus avoid the switch statement and also avoid to forget to add additional switch branches when you augment the enum.

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;
    }
}

预计该提案将基于单个嗅觉器官的配置而引起争议,并且围绕臭味/干净的二分法,我想参考

Anticipating that this proposal will stir controversy based on the dispositions of individual olfactory organs and centered around the smelly/clean dichotomy I'd like to refer to this post dedicated solely to the question, whether functions as members of enums may enrage our noses in justifiable ways or not.

这篇关于如何避免工厂类中的“级联if \ case"语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆