重温设计模式之 Factory
簡介:?創建型模式的核心干將,工廠、簡單工廠、抽象工廠,還記得清么,一文回顧和對比下。
作者 | 彌高
來源 | 阿里技術公眾號
前言
創建型模式的核心干將,工廠、簡單工廠、抽象工廠,還記得清么,一文回顧和對比下。
一 為什么需要工廠
系統中總是需要創建對象的,一般使用new()來創建對象。創建對象可以是簡單的new(),也可以有復雜的加工邏輯,如果在主程序中創建對象,那么就是將主干邏輯和創建對象的非主干邏輯耦合在了一起,工廠模式要做的就是將非核心的對象創建邏輯與主干邏輯解耦,通過調用工廠的創建方法直接獲取到一個對象。
二 工廠模式中的角色劃分
- 抽象產品角色(都有)
- 具體產品角色(都有)
- 抽象工廠角色(工廠方法模式和抽象工廠模式有)
- 具體工廠角色(都有)
- 上下文角色(都有)——調用工廠獲取對象
三 對工廠的基本認知
工廠方法總是基于一定的入參,返回對應的產品對象,即工廠是用來生產產品的。
工廠方法可能根據不同條件創建不同的具體產品實體,因此工廠方法的返回類型是抽象產品類型。
四 工廠模式的簡單劃分
1 簡單工廠模式
產品有抽象層,但是工廠沒有抽象層,在一個工廠中根據傳參創建相應的產品類型。
如果需要新增產品族(例如在A_cpu,B_cpu之外新增C_cpu),那么需要在工廠方法中進行邏輯修改,沒有做到開閉原則——對擴展開放,對修改封閉。
簡單工廠模式就是靜態工廠模式,不屬于GOF23中的模式,就是一個簡單的封裝,在靜態工廠模式中,工廠方法是靜態的,所以叫做靜態工廠方法。
2 工廠方法模式
產品有抽象層,工廠也有抽象層,一個工廠對應一個產品(即一個工廠只能創建一個產品類別)。
如果新增產品,只需要新增工廠,不需要對原有工廠邏輯進行修改,符合開閉原則。
3 抽象工廠模式
產品有抽象層,工廠有抽象層,一個工廠對應多個產品(即一個工廠可以創建多個產品類別)。
用于解決有多有產品類別(芯片、主板、顯卡)情況下,產品族(A產品族、B產品族)的切換替代問題。
五 簡單工廠模式詳解
簡單工廠模式下,只有一個工廠類,工廠角色沒有抽象層次。
使用這一個工廠生產出不同的產品實現,例如使用CpuFactory這一個產品類中會生產出ACpu、BCpu等具體的產品實現。
如果要新增產品實現,例如CCpu,需要修改該工廠方法的代碼。
簡單工廠模式中,決定生成哪個產品的邏輯在工廠內實現。
1 DEMO:抽象產品接口
2 DEMO:具體產品實現
3 DEMO:具體產品實現
4 DEMO:簡單工廠類
5 DEMO:測試類——調用工廠創建對象的客戶端代碼
六 工廠方法模式詳解
工廠方法模式中,對工廠也進行了抽象,一個抽象工廠還是對應一個產品類別,例如CpuFacroy接口對應生產Cpu產品,但是具體生產的時候,將具體的產品實現交給每個具體的工廠實現去生產;即在CpuFactory接口下,有ACpuFactory和BCpuFactory,分別來生產ACpu和BCpu這2中具體的產品。
工廠方法模式中具體的工廠負責創建具體的產品,工廠內部的邏輯只負責創建對應對象,決定生成什么產品的邏輯在外部客戶端,客戶端通過選擇使用具體工廠,間接決定了生成什么產品。
1 DEMO:產品抽象接口
2 DEMO:具體產品實現
3 DEMO:具體產品實現
4 DEMO:抽象工廠
5 DEMO:具體工廠實現
6 DEMO:具體工廠實現
7 DEMO:測試類——上下文
七 THINK:簡單工廠&工廠方法模式的區別
簡單工廠模式中工廠類沒有抽象層,而工廠方法模式中工廠類有抽象工廠。
決定生成具體什么產品的邏輯在哪里實現?
- 簡單工廠模式中,客戶端決定傳遞什么類型的參數,在工廠中根據不同的參數決定創建不同的對象,即工廠內部有決策創建產品的邏輯。
- 工廠方法模式中,具體工廠內部很純凈,什么類型的工廠就負責創建對應的產品,決策的邏輯全部在客戶端中實現。
當需要新增產品實現時,簡單工廠模式需要修改工廠邏輯,工廠方法模式只需要新增具體工廠實現,不需要修改工廠內部邏輯。
八 THINK:工廠方法 & 抽象工廠模式的區別
1 工廠方法模式
工廠方法模式用于解決一個產品(Cpu),有多個產品族(ACpu,BCpu)的情況,以抽象產品作為工廠,例如CpuFactory,每個產品族對應一個具體工廠,例如ACpuFactory,BCpuFactory,即工廠方法模式以產品維度來建廠。
工廠方式模式中,多一個新的抽象產品的話需要新建立一個抽象工廠,例如新建MainboardFactory等。即如果需要新增產品線(XianKa),則需要新增抽象工廠(XianKaFactory);如果需要在某個產品(Cpu)下新增具體產品,則需要新增具體工廠(CCpuFactory)。
工廠方法模式中以抽象產品維度建廠,每個抽象產品一個工廠,當產品族(A,B,C……)增加的時候,需要為每個產品的抽象工廠新增具體工廠(CCpuFactory,CMainboardFactory,CXianKaFactory)。
2 抽象工廠模式
在工廠方法模式下,當產品線(品類:cpu/主板/顯卡)和產品族(A/B/C)水平擴展后,如果要新增產品族,那么需要在所有工廠下面新增新產品族的所有產品,即在cpu工廠、主板工廠、顯卡工廠……都新增C的具體工廠,這樣顯然改動太大,此時就要考慮使用抽象工廠模式。
抽象工廠模式下,以產品族維度來建廠,一個廠里有多個創建方法,每個創建方法負責創建一個產品線,例如有A工廠、B工廠,每個工廠里面有創建cpu的方法、創建主板的方法、創建顯卡的方法,當需要新增一個產品族的時候,只需要新增一個工廠,例如C工廠,在該工廠中創建各個產品即可。
3 總結
工廠方法模式和抽象工廠模式的最大區別是工廠方法模式針對的是一個產品等級結構,而抽象工廠模式針對的是多個產品等級結構。
九 抽象工廠模式詳解
1 抽象工廠模式角色
- 抽象產品
- 具體產品
- 抽象工廠:以產品族維度建工廠類,類中含有多個抽象方法,每個方法對應創建一個產品。
- 具體工廠:具體工廠實現抽象工廠,并實現里面的所有產品創建方法,創建屬于當前具體產品對象。
- 環境類:持有抽象工廠,并可以在運行時注入具體工廠。
2 DEMO:抽象產品
3 DEMO:具體產品
4 DEMO:抽象工廠
5 DEMO:具體工廠
6 DEMO:測試類——類似程序上下文
十 THINK:工廠模式中的方法一定是靜態的嗎?
在簡單工廠中,工廠方法沒有對應的抽象,可以定義為靜態的。
在工廠方法模式和抽象工廠模式中,工廠都有對應的抽象接口,而接口中的抽象方法不能定義為靜態,所以工廠方法也不能是靜態的。
十一 THINK:對于接口中static的理解
接口interface以及接口中的方法都是public abstract的。
接口中的方法都是抽象方法,沒有方法體,因此也不允許使用static來修飾(static方法表示可以被類調用,接口因為沒有功能體,所以沒有人調用,所以不允許聲明為static)。
但是從JDK8開始,接口中方法可以有static,此時的方法必須有方法體,即接口中可以含有非抽象的方法,和抽象類一樣了,接口中非抽象的方法不需要被實現,抽象的方法必須要求子類實現。
十二 工廠模式 & 抽象工廠的使用場景
一個系統不應當依賴于產品類實例如何被創建、組合、表達的細節,這是所有工廠模式都要關注解決的問題。
當系統中的產品有多個產品族,雖然對于任何一個具體請求只屬于其中一個產品族,但是對于系統而言,應當面向產品族設計,即使用抽象工廠模式。
當系統中有多個產品族,并且這個產品族中的產品通常是在一起使用,一起創建的,如果這種約束需要在系統設計中體現出來,那么應當使用抽象工廠模式(例如:不管是A產品族,還是B產品族中的芯片、主板、磁盤這些產品通常需要一起創建)。
十三 抽象工廠模式的優缺點
1 抽象工廠的優點
分離了接口和實現
客戶端使用抽象工廠來創建需要的對象,而客戶端根本就不知道具體的實現是誰,客戶端只是面向產品的接口,也就是說客戶端從具體的產品中實現了解耦。
使切換產品族變得容易
因為一個具體的工廠代表的是一個產品族,比如上面例子中的A系列到B系列只需要切換一下具體的工廠。
2 抽象工廠的缺點
不太容易擴展新的產品
如果需要給這個產品族添加一個新的產品,那么就需要修改抽象工廠,需要在抽象工廠中添加新產品創建方法,同時需要給所有的具體工廠增加接口。
十四 最佳實踐
都使用抽象工廠模式,按照產品族維度來建立工廠,如果只有一個產品那么工廠中就一個方法,如果有多個產品就多個方法。
原文鏈接
本文為阿里云原創內容,未經允許不得轉載。
總結
以上是生活随笔為你收集整理的重温设计模式之 Factory的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 点货网 x mPaaS | 仅 2 位
- 下一篇: 如何用Netty写一个高性能的分布式服务