簡體   English   中英

如何避免工廠 class 中的“級聯 if\case”語句

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM