23種設計模式之工廠方法模式

卡奴達摩的專欄發表於2015-04-01

23種設計模式總篇:chenmingyu.top/design/

工廠方法模式

工廠模式屬於建立型設計模式

定義:定義一個用於建立物件的介面,讓子類決定例項化哪一個類。工廠方法使一個類的例項化延遲到其子類

工廠方法模式是new一個物件的替代品,所以在所有需要生成物件的地方都可以使用,但如果隨意增加工廠類會增加系統程式碼的複雜度

模式類圖

23種設計模式之工廠方法模式

角色

  1. 抽象產品:Product抽象產品定義
  2. 具體產品類:ConcreteProduct實現Product介面
  3. 抽象工廠:Creatot抽象工廠定義
  4. 具體工廠類:ConcreteCreator實現Creatot介面

優點:

  1. 解耦:呼叫方不用負責物件的建立,只需要使用,明確各自的職責
  2. 維護方便:後期如果建立物件時需要修改程式碼,也只需要去工廠方法中修改,易擴充

模式程式碼實現

原始碼地址:github.com/mingyuHub/d…

工廠方法模式可以分為:簡單工廠和工廠方法

簡單工廠

以遊戲為例子,涉及四個類:GameFactory(遊戲工廠類),Gameable(遊戲介面),ShootGame(射擊類遊戲),TowerDefenceGame(塔防類遊戲)

比如遊戲工廠,工廠方法通過出入的引數生成生成不同產品型別的遊戲

Gameable

遊戲介面,提供一個校驗賬戶資訊的介面

/**
 * @auther: chenmingyu
 * @date: 2019/2/14 11:19
 * @description:
 */
public interface Gameable {

    /**
     * 校驗賬戶資訊
     * @param nickName
     */
    void validateAccount(String nickName);
}
複製程式碼
ShootGame

射擊類遊戲,實現Gameable介面

/**
 * @auther: chenmingyu
 * @date: 2019/2/14 11:26
 * @description: 射擊類遊戲
 */
public class ShootGame implements Gameable{

    @Override
    public void validateAccount(String nickName) {
        System.out.println("射擊遊戲校驗暱稱:"+nickName);
    }
}
複製程式碼
TowerDefenceGame

塔防類遊戲,實現Gameable介面

/**
 * @auther: chenmingyu
 * @date: 2019/2/14 11:28
 * @description: 塔防類遊戲
 */
public class TowerDefenceGame implements Gameable{

    @Override
    public void validateAccount(String nickName) {
        System.out.println("塔防遊戲校驗暱稱:"+nickName);
    }
}
複製程式碼
GameFactory

遊戲工廠,封裝了建立遊戲物件的過程

/**
 * @auther: chenmingyu
 * @date: 2019/2/14 11:29
 * @description: 工廠類
 */
public class GameFactory {

    /**
     * 根據傳入型別生成例項
     * @param gameType
     * @return
     */
    public static Gameable creator(String gameType){
        Gameable gameable = null;
        if(StringUtils.isEmpty(gameType)){
            return gameable;
        }
        if("shoot".equalsIgnoreCase(gameType)){
            gameable = new ShootGame();
        }else if("towerDefence".equalsIgnoreCase(gameType)){
            gameable = new TowerDefenceGame();
        }
        return gameable;
    }
}
複製程式碼
驗證

客戶端決定例項化哪個物件

public static void main(String[] args) {
    Gameable shootGame = GameFactory.creator("shoot");
    shootGame.validateAccount("明羽");
    System.out.println("... 分割線 ...");
    Gameable towerDefenceGame = GameFactory.creator("towerDefence");
    towerDefenceGame.validateAccount("明羽");
}
複製程式碼

輸出

射擊遊戲校驗暱稱:明羽
... 分割線 ...
塔防遊戲校驗暱稱:明羽
複製程式碼

如果要新增一個拳擊類遊戲的話,就需要新建一個拳擊遊戲類,然後修改工廠方法。

工廠方法模式

工廠模式跟簡單工廠模式的區別在於簡單工廠只有一個工廠類,提供了一個工廠方法,由入參決定生產那個產品,而工廠模式則定義一個工廠介面,不同的產品工廠實現工廠介面,生產的產品由產品工廠決定

以遊戲為例子,在上面四個類的基礎上修改GameFactory(遊戲工廠類)為介面,新增了兩個類:ShootGameFactory(射擊類遊戲工廠),TowerDefenceGameFactory(塔防類遊戲工廠)

修改了的GameFactory
/**
 * @auther: chenmingyu
 * @date: 2019/2/14 11:29
 * @description: 工廠類
 */
public interface GameFactory {

    /**
     * 生成例項
     * @return
     */
    Gameable creator();
}
複製程式碼
ShootGameFactory

實現GameFactory,重寫creator()

/**
 * @auther: chenmingyu
 * @date: 2019/2/14 15:14
 * @description: 射擊類遊戲工廠
 */
public class ShootGameFactory implements GameFactory{

    @Override
    public Gameable creator() {
        return new ShootGame();
    }
}
複製程式碼
TowerDefenceGameFactory

實現GameFactory,重寫creator()

/**
 * @auther: chenmingyu
 * @date: 2019/2/14 15:15
 * @description: 塔防類遊戲工廠
 */
public class TowerDefenceGameFactory implements GameFactory{

    @Override
    public Gameable creator() {
        return new TowerDefenceGame();
    }
}
複製程式碼
驗證
/**
 * @auther: chenmingyu
 * @date: 2019/2/14 11:38
 * @description:
 */
public class FactoryTest {

    public static void main(String[] args) {

        GameFactory shootGameFactory = new ShootGameFactory();
        Gameable shootGame = shootGameFactory.creator();
        shootGame.validateAccount("明羽");
        System.out.println("... 分割線 ...");
        GameFactory towerDefenceGameFactory = new TowerDefenceGameFactory();
        Gameable towerDefenceGame = towerDefenceGameFactory.creator();
        towerDefenceGame.validateAccount("明羽");
    }
}
複製程式碼

輸出

射擊遊戲校驗暱稱:明羽
... 分割線 ...
塔防遊戲校驗暱稱:明羽
複製程式碼

相關閱讀

建立型設計模式

關注於如何建立物件

  1. 23種設計模式之單例模式

    保證在程式執行期間一個類只有一個例項,並提供一個全域性訪問點

  2. 23種設計模式之工廠模式

    用工廠方法代替new操作,讓子類去決定例項化哪個類,工廠方法將一個類的例項化延遲到子類

  3. 23種設計模式之抽象工廠

    抽象工廠模式屬於建立型模式,是對工廠方法模式的擴充套件,抽象工廠比工廠模式更為抽象,工廠方法模式針對產品等級結構,而抽象工廠針對產品族

  4. 23種設計模式之建造者模式

    通過克隆一個已經存在的物件例項來返回新的例項,而不是通過new去建立物件

  5. 23種設計模式之原型模式

    通過克隆一個已經存在的物件例項來返回新的例項,而不是通過new去建立物件

結構型設計模式

關注於類和物件之間的關係

  1. 23種設計模式之介面卡模式

    組合兩個不相干類,在兩個不相容的介面之間提供一個混合介面,使其相容適配

  2. 23種設計模式之橋接模式

    將抽象部分與它的實現部分分離,使它們都可以獨立地變化。橋接模式將系統各維度抽象出來,各維度獨立變化,之後可通過聚合,將各維度組合起來,減少它們之間耦合

  3. 23種設計模式之組合模式

    用來描述部分與整體的關係,是用於把一組相似的物件當作一個單一的物件。組合模式依據樹形結構來組合物件,所以組合模式的使用場景就是出現樹形結構的地方。

  4. 23種設計模式之裝飾器模式

    裝飾器模式可以為一個現有的類增加新功能,又不改變其結構,要求裝飾類和被裝飾類實現同一個介面,裝飾類持有被裝飾類的例項

  5. 23種設計模式之外觀模式

    外觀模式是為了解決類與類之家的責任關係和依賴關係的,通過提供一個Facade類來隱藏這些複雜的類之間關係的呼叫,並提供一個介面,供外部呼叫,利用這種方式進行類之間的解耦

  6. 23種設計模式之代理模式

    代理模式就是在操作原物件的時候,多出來一個代理類,用來對原物件的訪問進行控制和替代原物件進行一些操作

  7. 23種設計模式之代理享元模式

    運用共享技術有效地支援大量細粒度物件的複用,主要用來減少物件的建立,用來減少記憶體和提高效能,比較常見的連線池,緩衝池這類的池技術都是享元模式

行為型設計模式

關注於物件之間的通訊

  1. 23種設計模式之模板方法模式

    在父類(抽象類)中定義好演算法的流程,提供抽象方法,針對不同的實現交由不同的子類去實現,通過這種方式將公共程式碼提取出來封裝在父類中,然後父類去控制行為,子類負責實現

  2. 23種設計模式之策略模式

    在系統中提供一組策略,並將每個策略封裝成類,使他們可以相互轉換,具體策略的選擇由客戶端決定

  3. 23種設計模式之觀察者模式

    定義物件間一種一對多的依賴關係,使得每當一個物件改變狀態,則所有依賴於它的物件都會得到通知並被自動更新

  4. 23種設計模式之迭代器模式

    迭代器模式就是為解決遍歷元素而誕生的,它提供一種方法訪問一個容器物件中各個元素,而又不需暴露該物件的內部細節

  5. 23種設計模式之責任鏈模式

    使多個物件都有機會處理請求,從而避免了請求的傳送者和接受者之間的耦合關係。將這些物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有物件處理它為止

  6. 23種設計模式之命令模式

    將一個請求封裝成一個物件,從而讓你使用不同的請求把客戶端引數化,對請求排隊或者記錄請求日誌,可以提供命令的撤銷和恢復功能,用來降低類之間解耦

  7. 23種設計模式之備忘錄模式

    在不破壞封裝性的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態,其實就是在某個時刻備份了物件的狀態,在更改物件狀態後,可以通過備份將物件還原成備份時刻的狀態

  8. 23種設計模式之狀態模式

    允許一個物件在其內部狀態改變時改變它的行為,物件看起來似乎修改了它的類,物件的行為依賴於它的狀態(屬性),並且可以根據它的狀態改變而改變它的相關行為

  9. 23種設計模式之訪問者模式

    封裝一些作用於某種資料結構中的各元素的操作,它可以在不改變資料結構的前提下定義作用於這些元素的新的操作,訪問者模式就是將資料結構與資料操作相分離

  10. 23種設計模式之中介者模式

    用一箇中介物件來封裝一系列的物件互動,中介者使各物件不需要顯式地相互引用,從而使其耦合鬆散,而且可以獨立地改變它們之間的互動

  11. 23種設計模式之直譯器模式

    給定一門語言,定義它的文法的一種表示,並定義一個直譯器,該直譯器使用該表示來解釋語言中的句子

相關文章