日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

干货分享:什么是Java设计工厂模式?

發布時間:2024/4/14 java 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 干货分享:什么是Java设计工厂模式? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文主要會介紹三種工廠模式:簡單工廠,工廠方法,抽象工廠。其中簡單工廠并不屬于 GoF 23 種設計模式,工廠方法和抽象工廠模式則是屬于 GoF 23 種設計模式之中的 2 種。工廠模式作為一種非常常用的設計模式,在日常開發中非常常見,也是一種非常基礎的設計模式。

知識點

簡單工廠模式

工廠方法模式

抽象工廠模式

三種工廠模式對比

工廠模式能解決什么問題

簡單工廠模式

簡單工廠設計模式:Simple Factory Pattern,指的是由一個工廠對象來決定創建具體的產品實例,簡單工廠模式并不屬于 GoF 23 種設計模式之一,但是我們在平常開發中也運用得非常廣泛。

示例
下面我們就農場里面種植水果來舉例看看簡單工廠模式該怎么寫(這里我們需要新建一個 simple 目錄,相關類創建在 simple 目錄下)。

  • 新建一個產品接口 IProduct.java,接口中定義了一個種植方法。
package simple;public interface IProduct {void grow();//種植水果 }
  • 新建一個蘋果類 Apple.java 來實現產品接口。
package simple;public class Apple implements IProduct {@Overridepublic void grow() {System.out.println("種植蘋果");} }
  • 新建一個桔子類 Orange.java 來實現產品接口。
package simple;public class Orange implements IProduct {@Overridepublic void grow() {System.out.println("種植桔子");} }

如果不用工廠模式那么創建 Apple 和 Orange 對象都直接 new 一個出來就好了,但是這種方式很不友好,一旦一個對象的創建非常復雜,那么會非常不方便,所以需要一個工廠來幫助我們創建具體的產品類,從而隱藏創建細節。

  • 新建一個簡單工廠類 SimpleFactory.java 來創建產品,其中定義了一個創建方法,根據產品類型來決定創建哪種產品。
package simple;public class SimpleFactory {public IProduct createProduct(String productType){if("apple".equals(productType)){return new Apple();}else if("orange".equals(productType)){return new Orange();}return null;} }
  • 新建一個測試類 TestSimpleFactory.java 來測試一下。
package simple;public class TestSimpleFactory {public static void main(String[] args) {SimpleFactory factory = new SimpleFactory();IProduct apple = factory.createProduct("apple");apple.grow();//輸出:種植蘋果IProduct orange = factory.createProduct("orange");orange.grow();//輸出:種植桔子} }

接下來我們需要先執行 javac simple/*.java 命令進行編譯。然后再執行 java simple.TestSimpleFactory 命令運行測試類(大家一定要自己動手運行哦,只有自己實際去運行了才會更能體會其中的思想)。

這時候我們就將創建細節隱藏了,全部產品都通過 SimpleFactory 來幫忙創建。但是這種寫法仍然存在兩個問題:

假如我調用 createProduct 方法參數寫錯了,比如 apple 寫成了 aple,這時候代碼編譯可以通過,運行的時候才能發現問題。
如果產品很多,那么 SimpleFactory 類中會產生大量的 if 分支。
所以為了解決上面的兩個問題,我們可以再優化一下 SimpleFactory 類中的 createProduct 方法。

改造一下 SimpleFactory 類,新增一個 createProduct2 方法。

package simple;public class SimpleFactory {public IProduct createProduct(String productType){if("apple".equals(productType)){return new Apple();}else if("orange".equals(productType)){return new Orange();}return null;}public IProduct createProduct2(Class<? extends IProduct> clazz) throws Exception {if (null == clazz){throw new Exception("無法識別的產品");}return clazz.newInstance();} }
  • 同樣的,我們再重新建立一個測試類 TestSimpleFactory2.java,改成調用 createProduct2
    方法來獲取產品對象。
package simple;public class TestSimpleFactory2 {public static void main(String[] args) throws Exception {SimpleFactory factory = new SimpleFactory();IProduct apple = factory.createProduct2(Apple.class);apple.grow();//輸出:種植蘋果IProduct orange = factory.createProduct2(Orange.class);orange.grow();//輸出:種植桔子} }

同樣的我們需要再執行 javac simple/*.java 命令進行編譯。然后再執行 java simple.TestSimpleFactory2 命令運行測試類(大家一定要自己動手運行哦,只有自己實際去運行了才會更能體會其中的思想)。

可以看到,這種寫法完美的解決了上面存在的兩個問題(不過一般我們的工廠類都會將創建對象實例的方法設置成靜態方法)。

簡單工廠模式適用場景
簡單工廠適用于工廠類負責創建的對象較少的場景,且客戶端只需要傳入工廠類的參數,對于如何創建對象的邏輯不需要關心。

簡單工廠模式存在的問題
假如每種產品創建不僅僅只是實例化一個對象,還有其它邏輯需要處理,那么我們無法直接使用一句反射語句來創建對象,所以還是避免不了要寫很多 if 或者 switch 循環分支。這樣每新增一個產品我們都需要修改簡單工廠類,違背了開閉原則,而且隨著產品越來越豐富,工廠的職責會變得越來越多,久而久之會越來越難以維護。

為了彌補簡單工廠方法的不足之處,所以就有了工廠方法模式。

工廠方法模式

工廠方法模式:Fatory Method Pattern,主要用來解決簡單工廠模式存在的問題。其是指定義一個創建對象的接口,然后創建不同的具體工廠來創建對應的產品。工廠方法讓類的實例化推遲到工廠子類中進行,在工廠方法模式中用戶只需要關心所需產品對應的工廠,無須關心創建細節。

工廠方法模式中假如需要新增產品,只需要再新建工廠實現類,無需修改源碼,符合開閉原則。
示例
我們還是以上面農場種植水果舉例進行說明,產品接口和產品類不做修改,為了方便大家練習的時候對照,所以我還是把產品接口和產品類在下面重寫一下(這里我們需要新建一個 method 目錄,相關類創建在 method 目錄下)。

  • 新建一個產品接口 IProduct.java。
package method;public interface IProduct {void grow(); }
  • 新建一個具體產品蘋果類 Apple.java。
package method;public class Apple implements IProduct {@Overridepublic void grow() {System.out.println("種植蘋果");} }
  • 新建一個具體產品桔子類 Orange.java 。
package method;public class Orange implements IProduct {@Overridepublic void grow() {System.out.println("種植桔子");} }

現在我們需要將工廠也抽象化,新建一個工廠接口 IFarmFactory.java,定義一個 create 方法,這個方法的返回值就是產品。

package method;public interface IFarmFactory {IProduct create();//創建產品 }

新建一個生產蘋果的具體工廠類 AppleFactory.java,并實現工廠接口 IFarmFactory。

package method;public class AppleFactory implements IFarmFactory {@Overridepublic IProduct create() {return new Apple();//蘋果工廠生產蘋果} }

新建一個生產桔子的具體工廠類 OrangeFactory.java,并實現工廠接口 IFarmFactory。

package method;public class OrangeFactory implements IFarmFactory {@Overridepublic IProduct create() {return new Orange();//桔子工廠生產桔子} }

到這里大家應該很明白工廠方法和簡單工廠的區別了,簡單工廠就是所有產品都由一個工廠類一個方法來創建,而工廠方法將工廠的職責也進行細化了,每種產品都由自己特定的工廠來生產,這也是單一職責原則的體現。

最后新建一個測試類 TestFactoryMethod.java 來進行測試。

package method;public class TestFactoryMethod {public static void main(String[] args) {IFarmFactory appleFactory = new AppleFactory();IProduct apple = appleFactory.create();apple.grow();//輸出:種植蘋果IFarmFactory orangeFactory = new OrangeFactory();IProduct orange = orangeFactory.create();orange.grow();//輸出:種植桔子} }

接下來我們需要先執行 javac method/*.java 命令進行編譯。然后再執行

  • java method.TestFactoryMethod

命令運行測試類(大家一定要自己動手運行哦,只有自己實際去運行了才會更能體會其中的思想)。

這時候如果需要新增其它商品,需要創建兩個類:一個具體產品類,一個具體工廠類,所以說靈活的同時付出的代價就是類的數量變多了,學習到后面大家就知道,這也是設計模式的共性。

工廠方法模式的適用場景
工廠方法模式主要適用于以下場景:

  • 創建對象需要大量重復的代碼。
  • 客戶端(應用層)不依賴于產品類實例如何被創建、實現等細節。
  • 一個類通過其子類來指定創建哪個對象。

工廠方法模式的缺點
工廠方法模式的缺點也是很明顯的,每新增一個產品就需要新增兩個類,一旦產品數量上來了,類的個數也會過多,就會增加了系統的復雜度,也使得系統更加抽象難以理解。

抽象工廠模式

抽象工廠模式:Abstract Factory Pattern,是指提供一個創建一系列相關或相互依賴對象的接口,而無須指定它們具體的類。客戶端(應用層)不依賴于產品類實例如何被創建、實現等細節。

抽象工廠模式強調的是一系列相關的產品對象(屬于同一產品族)一起使用創建對象時需要大量重復的代碼。此時我們就需要提供一個產品類的庫,使得所有的產品以同樣的接口出現,這樣客戶端就可以不依賴于具體實現。

什么是產品族
在學習抽象工廠模式之前,我們需要先了解一下什么叫產品族。產品族指的就是相似的產品,比如說我們常用的手機,有華為、小米、OPPO,這些不同品牌的手機就屬于同一個產品族,它們隸屬于不同的公司,也就是需要由不同的工廠進行生產,這些工廠都可以共用同一個抽象方法來生產手機,這就是抽象工廠模式的本質,將相似的產品(同一產品族)抽象出公共的方法,統一對外接口。

示例
接下來我們還是以農場種植水果舉例進行說明。為了方便舉例,我們只將水果和農場分為南北兩個品種,比如南方農場生產的蘋果和桔子稱之為南方蘋果和南方桔子,而北方農場生產的蘋果和桔子就稱之為北方蘋果和北方桔子(這里我們需要新建一個 abstractFactory 目錄,相關類創建在 abstractFactory 目錄下)。

  • 新建一個蘋果的接口 IApple.java,定義一個種植蘋果的方法。
package abstractFactory;public interface IApple {void growApple();//種植蘋果 }
  • 新建一個具體產品“南方蘋果”類 SouthApple.java 來實現 IApple 接口。
package abstractFactory;public class SouthApple implements IApple {@Overridepublic void growApple() {System.out.println("種植南方蘋果");} }
  • 新建一個桔子的接口 IOrange.java,定義一個種植桔子的方法。
package abstractFactory;public interface IOrange {void growOrange();//種植桔子 }
  • 新建一個具體產品“南方桔子”類 SouthOrange.java 來實現 IOrange 接口。
package abstractFactory;public class SouthOrange implements IOrange {@Overridepublic void growOrange() {System.out.println("種植南方桔子");} }

以上就是一個將產品抽象化的過程,接下來我們就需要將產品交給工廠進行創建。

  • 新建一個抽象工廠接口 IFactory.java,定義兩個方法:一個用來創建蘋果對象,一個用來創建桔子對象。
package abstractFactory;public interface IFactory {IApple createApple();IOrange createOrange(); }
  • 新建一個具體工廠“南方工廠”類 SouthFarmFactory.java 來實現 IFactory
    接口,并實現其中的兩個抽象方法。
package abstractFactory;public class SouthFarmFactory implements IFactory {@Overridepublic IApple createApple() {return new SouthApple();//南方農場生產南方蘋果}@Overridepublic IOrange createOrange() {return new SouthOrange();//南方農場生產南方桔子} }
  • 現在我們可以新建一個測試類 TestAbstractFactory.java 來進行測試。
package abstractFactory;public class TestAbstractFactory {public static void main(String[] args) {IFactory southFarmFactory = new SouthFarmFactory();//構建南方農場IApple apple = southFarmFactory.createApple();//獲得南方蘋果apple.growApple();//輸出:種植南方蘋果IOrange orange = southFarmFactory.createOrange();//獲得南方桔子orange.growOrange();//輸出:種植南方桔子} }
  • 接下來我們需要先執行 javac abstractFactory/*.java 命令進行編譯。然后再執行 java abstractFactory.TestAbstractFactory 命令運行測試類。

這就是一個抽象工廠的設計模式示例,不過上面我并沒有完成北方農場的示例,這個就作為本次實驗留給大家的作業,大家可以自己把北方農場生產北方蘋果和北方桔子的類完善了并進行測試,自己動手才能加深印象。

假如這時候又有一個新的農場要建立生產一樣的產品,那么就可以再新建一個對應的產品類和對應的工廠類就可以實現了。

抽象工廠模式的適用場景
抽象工廠模式適用于我們有一系列類似的產品(比如上面的南方蘋果和北方蘋果,還有華為手機和小米手機),然后這些產品的實現又有細節上的不同,那么這時候就可以利用抽象工廠模式來將產品進行抽象化。

抽象工廠模式的缺點
根據上面的例子再結合設計模式七大原則,其實我們可以發現抽象工廠有一個很大的缺點,那就是擴展產品相當困難,比如示例中現在農場想種植西瓜,那么我們需要修改工廠的源碼,新增種植西瓜的方法,這樣的話抽象工廠、具體工廠都需要修改,顯然違背了開閉原則。所以抽象工廠模式使用的前提必須是產品比較穩定,不會輕易作出修改,否則后期的維護將會非常困難。

總結

工廠模式只是一個統稱,大部分人都知道工廠模式,但是卻并不是所有人都知道工廠模式也分為了 3 種。在實際開發過程中,當我們需要隱藏對象的創建細節時,可以考慮使用工廠模式,但是卻更應該根據實際業務場景,選擇一種比較合適的工廠模式。
參考資料:https://www.lanqiao.cn/courses/3031

如果您覺得這篇文章對你有幫助就點個贊吧!
關注我們收獲更多編程好課和實用干貨!

總結

以上是生活随笔為你收集整理的干货分享:什么是Java设计工厂模式?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。