23種設計模式之工廠模式

工廠模式屬於建立型設計模式,用工廠方法代替new操做,讓子類去決定實例化哪一個類,工廠方法將一個類的實例化延遲到子類java

推薦訪問個人我的網站,排版更好看呦:https://chenmingyu.top/design-factory-method/設計模式

什麼是工廠模式

定義一個建立對象的接口,由子類去決定實例化哪個類,將實例化對象的操做延遲到子類ide

優勢:測試

  1. 解耦:調用方不用負責對象的建立,只須要使用,明確各自的職責
  2. 維護方便:後期若是建立對象時須要修改代碼,也只須要去工廠方法中修改,易拓展

工廠模式細分爲:簡單工廠,工廠模式,抽象工廠網站

簡單工廠

以遊戲爲例子,涉及四個類:GameFactory(遊戲工廠類),Gameable(遊戲接口),ShootGame(射擊類遊戲),TowerDefenceGame(塔防類遊戲)設計

好比遊戲工廠,工廠方法經過出入的參數生成生成不一樣產品類型的遊戲code

Gameable

遊戲接口,提供一個校驗帳戶信息的接口對象

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

    /**
     * 校驗帳戶信息
     * @param nickName
     */
    void validateAccount(String nickName);
}
ShootGame

射擊類遊戲,實現Gameable接口blog

/**
 * @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. GameFactory:抽象工廠,規定了生成單人和雙人兩種遊戲
  2. ShootGameFactory,ShootGameFactory:具體工廠,負責生產具體的射擊類和塔防類單,雙人遊戲
  3. Gameable是抽象產品,ShootGame和TowerDefenceGame是抽象類,繼承Gameable
  4. SingleShootGame,DoubleShootGame,SingleTowerDefenceGame,DoubleTowerDefenceGame是具體產品
GameFactory

抽象工廠,規定了生成單人和雙人兩種遊戲

/**
 * @auther: chenmingyu
 * @date: 2019/2/14 11:29
 * @description: 抽象工廠
 */
public interface GameFactory {

    /**
     * 生產單人遊戲
     * @return
     */
    Gameable createSingleGame();

    /**
     * 生產雙人遊戲
     * @return
     */
    Gameable createDoubleGame();

}
ShootGameFactory

具體工廠,負責生產具體的射擊類單人遊戲和射擊類雙人遊戲

/**
 * @auther: chenmingyu
 * @date: 2019/2/14 18:20
 * @description: 設計遊戲製造廠
 */
public class ShootGameFactory implements GameFactory{

    @Override
    public Gameable createSingleGame() {
        return new SingleShootGame();
    }

    @Override
    public Gameable createDoubleGame() {
        return new DoubleShootGame();
    }
}
TowerDefenceGameFactory

具體工廠,負責生產具體的塔防類單人遊戲和塔防類雙人遊戲

/**
 * @auther: chenmingyu
 * @date: 2019/2/14 18:20
 * @description: 塔防遊戲製造廠
 */
public class TowerDefenceGameFactory implements GameFactory {

    @Override
    public Gameable createSingleGame() {
        return new SingleTowerDefenceGame();
    }

    @Override
    public Gameable createDoubleGame() {
        return new DoubleTowerDefenceGame();
    }
}
Gameable

抽象產品,全部遊戲產品均實現該接口

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

    /**
     * 校驗帳戶信息
     * @param nickName
     */
    void validateAccount(String nickName);


    /**
     * 遊戲人數
     */
    void getPlayerNumber();
}
ShootGame和TowerDefenceGame

抽象類,實現Gameable接口

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

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

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

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

}
具體產品

共四款遊戲產品:SingleShootGame,DoubleShootGame,SingleTowerDefenceGame,DoubleTowerDefenceGame

/**
 * @auther: chenmingyu
 * @date: 2019/2/15 16:55
 * @description: 單人射擊遊戲
 */
public class SingleShootGame extends ShootGame {

    @Override
    public void getPlayerNumber() {
        System.out.println("這是一個單人玩的射擊遊戲");
    }
}
/**
 * @auther: chenmingyu
 * @date: 2019/2/15 16:57
 * @description: 雙人射擊遊戲
 */
public class DoubleShootGame extends ShootGame{

    @Override
    public void getPlayerNumber() {
        System.out.println("這是一個雙人玩的射擊遊戲");
    }
}
/**
 * @auther: chenmingyu
 * @date: 2019/2/15 17:17
 * @description: 單人塔防遊戲
 */
public class SingleTowerDefenceGame extends TowerDefenceGame{

    @Override
    public void getPlayerNumber() {
        System.out.println("這是一個單人玩的塔防遊戲");
    }
}
/**
 * @auther: chenmingyu
 * @date: 2019/2/15 17:18
 * @description: 雙人塔防遊戲
 */
public class DoubleTowerDefenceGame extends TowerDefenceGame{
    @Override
    public void getPlayerNumber() {
        System.out.println("這是一個雙人玩的塔防遊戲");
    }
}
測試
public static void main(String[] args) throws Exception{

    ShootGameFactory shootGameFactory = new ShootGameFactory();
    shootGameFactory.createSingleGame().getPlayerNumber();
    shootGameFactory.createDoubleGame().getPlayerNumber();

    TowerDefenceGameFactory towerDefenceGameFactory = new TowerDefenceGameFactory();
    towerDefenceGameFactory.createSingleGame().getPlayerNumber();
    towerDefenceGameFactory.createDoubleGame().getPlayerNumber();
}

輸出

這是一個單人玩的射擊遊戲
這是一個雙人玩的射擊遊戲
這是一個單人玩的塔防遊戲
這是一個雙人玩的塔防遊戲
相關文章
相關標籤/搜索