工廠模式(Factory Pattern
)屬於建立型模式,它提供了一種建立對象的最佳方式。html
在工廠模式中,咱們在建立對象時不會對客戶端暴露建立邏輯,而且是經過使用一個共同的接口來指向新建立的對象。術業有專攻就能很好的解釋工廠模式,工廠模式就是專業生產商,咱們拿來用就行了,不須要本身粗製亂遭,也不須要購買假冒僞劣產品,正規渠道拿貨,質量有保障,安全,放心。java
簡單工廠模式不屬於23種設計模式。他是由一個工廠實例來建立咱們所須要的實例,適用於工廠類建立對象較少的場景。客戶端只須要傳入合適的參數就能獲取所需對象,不須要關心對象的建立邏輯。設計模式
代碼示例:安全
/** * @description: 水果產品接口 * @author: lmc * @create: 2019-03-19 21:28 **/ public interface IFruits { /** * 水果名稱 */ void getName(); /** * 水果顏色 */ void getColor(); /** * 水果味道 */ void getTaste(); }
/** * @description: 蘋果 * @author: lmc * @create: 2019-03-19 21:33 **/ public class Apple implements IFruits { @Override public void getName() { System.out.println(" 我是蘋果,水果的一種"); } @Override public void getColor() { System.out.println(" 蘋果是紅色的"); } @Override public void getTaste() { System.out.println(" 蘋果饞起來很甜很脆"); } }
/** * @description: 香蕉 * @author: lmc * @create: 2019-03-19 21:33 **/ public class Banana implements IFruits { @Override public void getName() { System.out.println(" 我是香蕉,水果的一種"); } @Override public void getColor() { System.out.println(" 香蕉是黃色的"); } @Override public void getTaste() { System.out.println(" 香蕉饞起來很甜很滑"); } }
/** * @description: 橙子 * @author: lmc * @create: 2019-03-19 21:33 **/ public class Orange implements IFruits { @Override public void getName() { System.out.println(" 我是橙子,水果的一種"); } @Override public void getColor() { System.out.println(" 橙子是橙色的"); } @Override public void getTaste() { System.out.println(" 橙子饞起來很甜水分足"); } }
上面的代碼 建立了一個水果接口,而且建立了三種水果分別實現了水果接口。app
/** * @description: 水果工廠 * @author: lmc * @create: 2019-03-19 21:38 **/ public class FruitsFactory { /** * @description: * @param fruitsName * @return com.lmc.gp12380.pattern.factory.fruits.IFruits * @date 2019/5/23 15:44 * @author lmc */ public IFruits product(String fruitsName){ if(null != fruitsName && fruitsName != ""){ System.out.println("客戶需求的水果是"+fruitsName); if("蘋果".equals(fruitsName)){ System.out.println("水果工廠生產了蘋果"); return new Apple(); } if("橙子".equals(fruitsName)){ System.out.println("水果工廠生產了橙子"); return new Orange(); } if("香蕉".equals(fruitsName)){ System.out.println("水果工廠生產了香蕉"); return new Banana(); } return null; }else{ return null; } } }
簡單工廠測試類ide
/** * @description: 水果工廠測試類 * @author: lmc * @create: 2019-03-19 21:50 **/ public class SimpleFactoryTest { public static void main(String[] args) { IFruits ifruits=null; FruitsFactory ifruitsFactory =new FruitsFactory(); ifruits = ifruitsFactory.product("香蕉"); getFruitsName(ifruits,"香蕉"); ifruits = ifruitsFactory.product("蘋果"); getFruitsName(ifruits,"蘋果"); ifruits = ifruitsFactory.product("橙子"); getFruitsName(ifruits,"橙子"); ifruits = ifruitsFactory.product("草莓"); getFruitsName(ifruits,"草莓"); } public static void getFruitsName(IFruits ifruits,String ifruitsName){ if(null != ifruits){ ifruits.getName(); }else{ if(null == ifruitsName || ifruitsName==""){ System.out.println("未指定水果讓水果工廠生產"); }else{ System.out.println("水果工廠暫時沒法生產"+ifruitsName); } } } }
測試結果測試
客戶需求的水果是香蕉 水果工廠生產了香蕉 我是香蕉,水果的一種 客戶需求的水果是蘋果 水果工廠生產了蘋果 我是蘋果,水果的一種 客戶需求的水果是橙子 水果工廠生產了橙子 我是橙子,水果的一種 客戶需求的水果是草莓 水果工廠暫時沒法生產草莓
上面的代碼很簡單,客戶傳入不一樣的參數,就能獲取工廠對象可以生產的產品。業務需求中,工廠實例建立對象的業務邏輯每每是複雜的,運用簡單工廠模式,客戶端就不須要關心業務了,只要建立工廠對象,傳入參數調用就能獲取所需對象。ui
利:客戶端調用簡單,對於簡單的業務邏輯清晰明瞭。spa
弊:設計
簡單工廠類圖:
工廠方法模式(FactoryMethodPattern
)是指定義一個建立對象的接口(工廠接口),但讓實現這個 接口的類(工廠具體實現類)來決定實例化哪一個類,工廠方法讓類的實例化推遲到子類中進行。
現代化管理都是明確分工、專人幹專事、團隊協做。我們的程序代碼意思同樣的。
來一個水果工廠接口
/** * @description: 水果工廠接口 * @author: lmc * @create: 2019-03-20 20:14 **/ public interface IFruitsFactory { /** * 工廠的生產方法 * @return IFruits */ IFruits product(); }
/** * @description: 蘋果工廠 * @author: lmc * @create: 2019-03-20 20:19 **/ public class AppleFactory implements IFruitsFactory { @Override public IFruits product() { System.out.println("蘋果工廠只生產蘋果"); return new Apple(); } }
/** * @description: 香蕉工廠 * @author: lmc * @create: 2019-03-20 20:19 **/ public class BananaFactory implements IFruitsFactory { @Override public IFruits product() { System.out.println("香蕉工廠只生產香蕉"); return new Banana(); } }
/** * @description: 橙子工廠 * @author: lmc * @create: 2019-03-20 20:19 **/ public class OrangeFactory implements IFruitsFactory { @Override public IFruits product() { System.out.println("橙子工廠只生產橙子"); return new Orange(); } }
/** * @description: 工廠方法測試 * @author: lmc * @create: 2019-03-20 20:39 **/ public class MethodFactoryTest { public static void main(String[] args) { IFruitsFactory iFruitsFactory= new AppleFactory(); iFruitsFactory.product().getName(); iFruitsFactory = new BananaFactory(); iFruitsFactory.product().getName(); iFruitsFactory = new OrangeFactory(); iFruitsFactory.product().getName(); } }
運行結果:
蘋果工廠只生產蘋果 我是蘋果,水果的一種 香蕉工廠只生產香蕉 我是香蕉,水果的一種 橙子工廠只生產橙子 我是橙子,水果的一種
專人作專事,具體的對象只有具體的工廠建立。用戶只有選擇權,不須要傳入參數。對象的實例化推遲到了工廠實現類建立。
利:
弊:
工廠方法模式類圖
抽象工廠模式(Abstract Factory Pattern
)是指提供一個建立一系列相關或相互依賴對象的接口,無須指定他們具體的類。客戶端(應用層)不依賴於產品類實例如何被建立、實現等細節,強調的是一系列相關的產品對象(屬於同一產品族)一塊兒使用建立對象須要大量重複的代碼。須要提供一個產品類的庫,全部的產品以一樣的接口出現,從而使客戶端不依賴於具體實現。
如今瞭解下上面提到的產品族和產品等級結構的概念。
產品族:屬於一個產品工廠的全部產品。
產品等級結構:不等產品工廠生產的相同的同類產品。
如今水果工廠需求再次升級,以前又一個水果接口 IFruits
,那麼咱們再增長 水果果乾接口IDriedFruits
、水果果汁接口 IJuice
/** * @description: 水果乾產品接口 * @author: lmc * @create: 2019-03-19 21:28 **/ public interface IDriedFruits { void getName(); void getColor(); void getTaste(); }
/** * @description: 水果果汁品接口 * @author: lmc * @create: 2019-03-19 21:28 **/ public interface IJuice { void getName(); void getColor(); void getTaste(); }
如今咱們有實現類 蘋果汁 AppleJuice
、 蘋果乾 DriedApple
......
/** * @description: 蘋果乾 * @author: lmc * @create: 2019-03-19 21:33 **/ public class DriedApple implements IDriedFruits { @Override public void getName() { System.out.println(" 我是蘋果乾,果乾的一種"); } @Override public void getColor() { System.out.println(" 蘋果乾大概也是白色的吧"); } @Override public void getTaste() { System.out.println(" 蘋果乾沒吃過,打個也是酸酸的吧"); } }
/** * @description: 蘋果汁 * @author: lmc * @create: 2019-03-19 21:33 **/ public class AppleJuice implements IJuice { @Override public void getName() { System.out.println(" 我是蘋果汁,果汁的一種"); } @Override public void getColor() { System.out.println(" 蘋果汁大概是白色的吧"); } @Override public void getTaste() { System.out.println(" 蘋果汁酸酸的"); } }
/** * @description: 香蕉幹 * @author: lmc * @create: 2019-05-23 23:06 **/ public class DriedBanana implements IDriedFruits { @Override public void getName() { System.out.println(" 我是香蕉幹,果乾的一種"); } @Override public void getColor() { System.out.println(" 香蕉幹大概也是黃色的吧"); } @Override public void getTaste() { System.out.println(" 香蕉幹甜甜的"); } }
/** * @description: 香蕉汁 * @author: lmc * @create: 2019-05-23 23:10 **/ public class BananaJuice implements IJuice { @Override public void getName() { System.out.println(" 我是香蕉汁,果汁的一種"); } @Override public void getColor() { System.out.println(" 香蕉汁大概是白色的吧"); } @Override public void getTaste() { System.out.println(" 香蕉汁甜甜的"); } }
/** * @description: 橙子幹 * @author: lmc * @create: 2019-05-23 23:08 **/ public class DriedOrange implements IDriedFruits{ @Override public void getName() { System.out.println(" 我是橙子幹,果乾的一種"); } @Override public void getColor() { System.out.println(" 橙子幹大概也是橙黃色的吧"); } @Override public void getTaste() { System.out.println(" 香蕉乾沒吃過 應該是甜甜的"); } }
/** * @description: 橙汁 * @author: lmc * @create: 2019-05-23 23:12 **/ public class OrangeJuice implements IJuice { @Override public void getName() { System.out.println(" 我是橙汁,果汁的一種"); } @Override public void getColor() { System.out.println(" 橙汁是橙色的吧"); } @Override public void getTaste() { System.out.println(" 橙汁汁酸酸甜甜的"); } }
工廠類改造
抽象工廠接口,也能夠改爲抽象類
/** * @description: 抽象工廠 * @author: lmc * @create: 2019-03-21 21:59 **/ public interface IAbstractFruitsFactory { /** * @description: 水果生產 * @return com.lmc.gp12380.pattern.factory.fruits.IFruits * @date 2019/5/24 8:33 * @author lmc */ IFruits productFruits(); /** * @description: 果醬生產 * @return com.lmc.gp12380.pattern.factory.fruits.IDriedFruits * @date 2019/5/24 8:34 * @author lmc */ IDriedFruits productIDriedFruits(); /** * @description: 果汁生產 * @return com.lmc.gp12380.pattern.factory.fruits.IJuice * @date 2019/5/24 8:34 * @author lmc */ IJuice productJuice(); }
/** * @description: 蘋果工廠 * @author: lmc * @create: 2019-03-21 22:02 **/ public class AppleFactory implements IAbstractFruitsFactory { /** * @description:蘋果生成 * @return com.lmc.gp12380.pattern.factory.fruits.IFruits * @date 2019/5/23 15:14 * @author lmc */ @Override public IFruits productFruits() { return new Apple(); } /** * @description: 蘋果醬生產 * @return com.lmc.gp12380.pattern.factory.fruits.IDriedFruits * @date 2019/5/23 15:15 * @author lmc */ @Override public IDriedFruits productIDriedFruits() { return new DriedApple(); } /** * @description: 蘋果汁生產 * @return com.lmc.gp12380.pattern.factory.fruits.IJuice * @date 2019/5/23 15:15 * @author lmc */ @Override public IJuice productJuice() { return new AppleJuice(); } }
/** * @description: 香蕉工廠 * @author: lmc * @create: 2019-05-24 08:35 **/ public class BananaFactory implements IAbstractFruitsFactory { @Override public IFruits productFruits() { return new Banana(); } @Override public IDriedFruits productIDriedFruits() { return new DriedBanana(); } @Override public IJuice productJuice() { return new BananaJuice(); } }
/** * @description: 橙子工廠 * @author: lmc * @create: 2019-05-24 08:27 **/ public class OrangeFactory implements IAbstractFruitsFactory { @Override public IFruits productFruits() { return new Orange(); } @Override public IDriedFruits productIDriedFruits() { return new DriedOrange(); } @Override public IJuice productJuice() { return new OrangeJuice(); } }
抽象工廠實際上是一個產品族,具體的實現抽象工廠類生產的產品實例所產生同一產品類型,好比全部的水果是一個產品等級結構,全部的果醬也是一個產品等級結構,全部的果汁是一個產品等級結構。
/** * @description: 抽象工廠方法測試 * @author: lmc * @create: 2019-03-20 20:39 **/ public class AbstractFactoryTest { public static void main(String[] args) { AppleFactory appleFactory=new AppleFactory(); IFruits apple= appleFactory.productFruits(); apple.getName(); apple.getColor(); apple.getTaste(); IDriedFruits appleDriedFruits=appleFactory.productIDriedFruits(); appleDriedFruits.getColor(); appleDriedFruits.getName(); appleDriedFruits.getTaste(); IJuice appleJuice=appleFactory.productJuice(); appleJuice.getName(); appleJuice.getColor(); appleJuice.getTaste(); System.out.println("_________________________________________"); OrangeFactory orangeFactory=new OrangeFactory(); IFruits orange= orangeFactory.productFruits(); orange.getName(); orange.getColor(); orange.getTaste(); IDriedFruits orangeDriedFruits=orangeFactory.productIDriedFruits(); orangeDriedFruits.getColor(); orangeDriedFruits.getName(); orangeDriedFruits.getTaste(); IJuice orangeJuice=orangeFactory.productJuice(); orangeJuice.getName(); orangeJuice.getColor(); orangeJuice.getTaste(); System.out.println("_________________________________________"); BananaFactory bananaFactory=new BananaFactory(); IFruits banana= bananaFactory.productFruits(); banana.getName(); banana.getColor(); banana.getTaste(); IDriedFruits bananaDriedFruits=bananaFactory.productIDriedFruits(); bananaDriedFruits.getColor(); bananaDriedFruits.getName(); bananaDriedFruits.getTaste(); IJuice bananaJuice=appleFactory.productJuice(); bananaJuice.getName(); bananaJuice.getColor(); bananaJuice.getTaste(); } }
測試結構
我是蘋果,水果的一種 蘋果乾大概也是白色的吧 我是蘋果乾,果乾的一種 蘋果乾沒吃過,打個也是酸酸的吧 我是蘋果汁,果汁的一種 蘋果汁大概是白色的吧 蘋果汁酸酸的 _________________________________________ 我是橙子,水果的一種 橙子幹大概也是橙黃色的吧 我是橙子幹,果乾的一種 橙子乾沒吃過 應該是酸酸甜甜的 我是橙汁,果汁的一種 橙汁是橙色的吧 橙汁汁酸酸甜甜的 _________________________________________ 我是香蕉,水果的一種 香蕉是黃色的 香蕉饞起來很甜很滑 香蕉幹大概也是黃色的吧 我是香蕉幹,果乾的一種 香蕉幹甜甜的 我是香蕉汁,果汁的一種 香蕉汁大概是白色的吧 香蕉汁甜甜的
抽象工廠利弊
利:
弊:
抽象工廠類圖
工廠模式是一種面向對象程序封裝,屬於設計模式的建立型模式。客戶端或者調用者須要的對象由工廠建立,不須要知道建立對象複雜的業務邏輯。簡單工廠模式到工廠方法模式,再到抽象工廠模式。實際上是一種社會進步的表現。
簡單工廠就是一個小做坊,只要是工廠有這種產品均可以去生產。這就形成了管理不規範,維護困難。註定的簡單工廠就是簡單工廠,發展壯大不起來。當是呢方便,就比如你須要一箱牛奶,你去小超市就能夠拿了,確定不須要費九牛二虎之力去大草原找牛去擠奶吧。
工廠方法模式對應流水線生產企業。他們的產品比較少,管理規範,維護簡單。這樣的公司可以作大,出名,就好像那些只作單一產品的企業,好比服裝工廠,塑料工廠。可是呢,產品單一,面臨的競爭壓力大,面臨更復雜的業務一籌莫展,很容易被別人取而代之。對於新的產品,就要新建工程,新增流水線,投入成本過高。
抽象工廠模式:對應現代化產業鏈代工廠,生產、管理規範。強調的是產業鏈,一系列相互關聯的產品。造成了一個產品生態。讓用戶不可或缺,絕對是世界級的大企業,好比華爲,以及一些世界500強公司。他面臨的是一個產業鏈的生產管理。抽象工廠模式封裝的是複雜的產品關係業務。
原文出處:https://www.cnblogs.com/programmerkaixin/p/10918844.html