工廠模式屬於建立型設計模式,用工廠方法代替new操做,讓子類去決定實例化哪一個類,工廠方法將一個類的實例化延遲到子類java
推薦訪問個人我的網站,排版更好看呦:https://chenmingyu.top/design-factory-method/設計模式
定義一個建立對象的接口,由子類去決定實例化哪個類,將實例化對象的操做延遲到子類ide
優勢:測試
工廠模式細分爲:簡單工廠,工廠模式,抽象工廠網站
以遊戲爲例子,涉及四個類:GameFactory(遊戲工廠類),Gameable(遊戲接口),ShootGame(射擊類遊戲),TowerDefenceGame(塔防類遊戲)設計
好比遊戲工廠,工廠方法經過出入的參數生成生成不一樣產品類型的遊戲code
遊戲接口,提供一個校驗帳戶信息的接口對象
/** * @auther: chenmingyu * @date: 2019/2/14 11:19 * @description: */ public interface Gameable { /** * 校驗帳戶信息 * @param nickName */ void validateAccount(String nickName); }
射擊類遊戲,實現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); } }
塔防類遊戲,實現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); } }
遊戲工廠,封裝了建立遊戲對象的過程
/** * @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(塔防類遊戲工廠)
/** * @auther: chenmingyu * @date: 2019/2/14 11:29 * @description: 工廠類 */ public interface GameFactory { /** * 生成實例 * @return */ Gameable creator(); }
實現GameFactory,重寫creator()
/** * @auther: chenmingyu * @date: 2019/2/14 15:14 * @description: 射擊類遊戲工廠 */ public class ShootGameFactory implements GameFactory{ @Override public Gameable creator() { return new ShootGame(); } }
實現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("明羽"); } }
輸出
射擊遊戲校驗暱稱:明羽 ... 分割線 ... 塔防遊戲校驗暱稱:明羽
抽象工廠比工廠模式更爲抽象,工廠模式只生產一種產品族,而抽象工廠生產多個產品族
產品族是指同一工廠生產的一組不一樣產品結構的一組產品,好比射擊遊戲工廠生產單人射擊遊戲和雙人射擊遊戲兩款產品,這裏的單人射擊遊戲產和雙人射擊遊戲兩款產品統稱爲產品族
以上面的遊戲爲例,如今有射擊遊戲和塔防遊戲倆款遊戲,如今需求變了,要求射擊類遊戲又細分爲單人和雙人兩款遊戲產品,塔防類遊戲細分爲單人和雙人兩款遊戲產品。這時射擊類遊戲和塔防類遊戲就是兩個產品族,旗下分別有兩款產品一款是單人遊戲,一款是雙人遊戲
有點複雜,畫個類圖,看着清晰一些
抽象工廠,規定了生成單人和雙人兩種遊戲
/** * @auther: chenmingyu * @date: 2019/2/14 11:29 * @description: 抽象工廠 */ public interface GameFactory { /** * 生產單人遊戲 * @return */ Gameable createSingleGame(); /** * 生產雙人遊戲 * @return */ Gameable createDoubleGame(); }
具體工廠,負責生產具體的射擊類單人遊戲和射擊類雙人遊戲
/** * @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(); } }
具體工廠,負責生產具體的塔防類單人遊戲和塔防類雙人遊戲
/** * @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(); } }
抽象產品,全部遊戲產品均實現該接口
/** * @auther: chenmingyu * @date: 2019/2/14 11:19 * @description: 遊戲接口 */ public interface Gameable { /** * 校驗帳戶信息 * @param nickName */ void validateAccount(String nickName); /** * 遊戲人數 */ void getPlayerNumber(); }
抽象類,實現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(); }
輸出
這是一個單人玩的射擊遊戲 這是一個雙人玩的射擊遊戲 這是一個單人玩的塔防遊戲 這是一個雙人玩的塔防遊戲