1. 程式人生 > >設計模式-03工廠方法模式(Factory Method Pattern)

設計模式-03工廠方法模式(Factory Method Pattern)

插曲.簡單工廠模式(Simple Factory Pattern)

介紹工廠方法模式之前,先來做一個鋪墊,瞭解一下簡單工廠模式,它不屬於 GoF 的 23 種經典設計模式,它的缺點是增加新產品時會違背“開閉原則”。

1.模式動機

考慮一個簡單的軟體應用場景,一個軟體系統可以提供多個外觀不同的按鈕(如圓形按鈕、矩形按鈕、菱形按鈕等),這些按鈕都源自同一個基類,不過在繼承基類後不同的子類有不同的實現方式從而使得它們可以呈現不同的外觀,如果我們希望在使用這些按鈕時,不需要知道這些具體按鈕類的名字,只需要知道表示該按鈕類的一個引數,並提供一個呼叫方便的方法,把該引數傳入方法即可返回一個相應的按鈕物件,此時,就可以使用簡單工廠模式。

2.模式定義

簡單工廠模式(Simple Factory Pattern):又稱為靜態工廠方法(Static Factory Method)模式,它屬於類建立型模式。在簡單工廠模式中,可以根據引數的不同返回不同類的例項。簡單工廠模式專門定義一個類來負責建立其他類的例項,被建立的例項通常都具有共同的父類。

3.模式結構

這個模式結構有三種。

  • 工廠角色:工廠角色負責實現建立所有例項的內部邏輯。
  • 抽象產品角色:抽象產品角色是所建立的所有物件的父類,負責描述所有例項所共有的公共介面。
  • 具體產品角色:具體產品角色是建立目標,所有建立的物件都充當這個角色的某個具體類的例項。

3.模式程式碼

先定義抽象產品角色,這裡定義一個抽象的動物類。

public abstract class AbstractAnimal {
    public abstract String say();
}

再定義具體產品角色,這裡寫了一個鳥一個貓的實現。

public class Bird extends AbstractAnimal {
    @Override
    public String say() {
        return "I'm a bird.";
    }
}
public class Cat extends AbstractAnimal {
    @Override
    public String say() {
        return "I'm a cat.";
    }
}

最後定義工廠類。

public class AnimalFactory {
    public static AbstractAnimal create(String animalName) {
        if ("cat".equals(animalName)) {
            return new Cat();
        } else if ("bird".equals(animalName)) {
            return new Bird();
        }
        return null;
    }
}

4.總結

簡單工廠模式還是比較簡單吧,雖然它不是 23 種設計模式中的一種,但是理解它可以幫助你理解本文的主角:工廠方法模式。

缺點

  • 由於工廠類集中了所有產品建立邏輯,一旦不能正常工作,整個系統都要受到影響。
  • 系統擴充套件困難,一旦新增新產品就不得不修改工廠邏輯,在產品型別較多時,有可能造成工廠邏輯過於複雜,不利於系統的擴充套件和維護。

1.模式動機

現在對該系統進行修改,不再設計一個按鈕工廠類來統一負責所有產品的建立,而是將具體按鈕的建立過程交給專門的工廠子類去完成,我們先定義一個抽象的按鈕工廠類,再定義具體的工廠類來生成圓形按鈕、矩形按鈕、菱形按鈕等,它們實現在抽象按鈕工廠類中定義的方法。這種抽象化的結果使這種結構可以在不修改具體工廠類的情況下引進新的產品,如果出現新的按鈕型別,只需要為這種新型別的按鈕建立一個具體的工廠類就可以獲得該新按鈕的例項,這一特點無疑使得工廠方法模式具有超越簡單工廠模式的優越性,更加符合“開閉原則”。

2.模式定義

工廠方法模式(Factory Method Pattern)又稱為工廠模式,它屬於類建立型模式。在工廠方法模式中,工廠父類負責定義建立產品物件的公共介面,而工廠子類則負責生成具體的產品物件,這樣做的目的是將產品類的例項化操作延遲到工廠子類中完成,即通過工廠子類來確定究竟應該例項化哪一個具體產品類。

3.模式結構

相對於簡單工廠,無非是將工廠類拆分為抽象和具體了。

  • 抽象工廠
  • 具體工廠
  • 抽象產品
  • 具體產品

4.模式程式碼

先建立抽象工廠。

public abstract class AbstractAnimalFactory {
    public abstract AbstractAnimal create();
}

再建立抽象產品。

public abstract class AbstractAnimal {
    public abstract String say();
}

然後建立具體產品。

public class Bird extends AbstractAnimal {
    @Override
    public String say() {
        return "I'm a bird.";
    }
}
public class Cat extends AbstractAnimal {
    @Override
    public String say() {
        return "I'm a cat.";
    }
}

最後建立具體工廠。

public class BirdAnimalFactory extends AbstractAnimalFactory {
    @Override
    public AbstractAnimal create() {
        return new Bird();
    }
}
public class CatAnimalFactory extends AbstractAnimalFactory {
    @Override
    public AbstractAnimal create() {
        return new Cat();
    }
}

是不是理解了簡單工廠模式,這個就很好理解了。

5.總結

  • 在工廠方法模式中,核心的工廠類不再負責所有產品的建立,而是將具體建立工作交給子類去做。這個核心類僅僅負責給出具體工廠必須實現的介面,而不負責產品類被例項化這種細節,這使得工廠方法模式可以允許系統在不修改工廠角色的情況下引進新產品。
  • 工廠方法模式的主要優點是增加新的產品類時無須修改現有系統,並封裝了產品物件的建立細節,系統具有良好的靈活性和可擴充套件性;其缺點在於增加新產品的同時需要增加新的工廠,導致系統類的個數成對增加,在一定程度上增加了系統的複雜性。