設計模式實戰---抽象工廠模式(Abstract-Factory-Pattern)

0 導讀

工廠方法模式人是造出來了,可都是清一色的類型,缺乏關愛、仇恨、喜怒哀樂等情緒,人類的生命太平淡了,忘記給人類定義性別了,那怎麼辦?
從頭開始創建全部的事物也是不可能的,那就想在現有的條件下從新造人,儘量舊物利用嘛
人種(Product產品類)應該怎麼改造呢?怎麼才能讓人類有愛有恨呢?定義互斥的性別,而後在每一個個體中埋下一顆種子:異性相吸,成熟後就必定會去找個異性
從設計角度來看,一個具體的對象經過兩個座標就能夠肯定:膚色和性別
膚色性別座標圖sql

  • 產品類分析完,生產的工廠類(八卦爐)該怎麼改造呢?

只有一個生產設備,要麼生產出來的全都是男性,要麼都是女性,何以解憂?
把目前已經有的生產設備—八卦爐拆開,因而女媧就使用了「八卦複製術」,把原先的八卦爐一個變兩個,而且略加修改,就成了女性八卦爐(只生產女性人種)和男性八卦爐(只生產男性人種),因而就開始準備生產
從新生產人類
一個接口,多個抽象類,而後是N個實現類,每一個人種都是一個抽象類,性別是在各個實現類中實現的
特別須要說明的是HumanFactory接口,在這個接口中定義了三個方法,分別用來生產三個不一樣膚色的人種,也就是咱們在座標圖的Y座標,它的兩個實現類分別是性別,也就是座標圖的X座標
經過X座標(性別)和Y座標(膚色)惟一肯定了一個生產出來的對象segmentfault

  • Human接口如代碼

  • 人種有三個抽象類,負責人種的抽象屬性定義

膚色和語言,白色人種、黑色人種、黃色人種


session

每一個抽象類都有兩個實現類,分別實現公共的最細節、最具體的事物:膚色和語言
具體的實現類實現膚色、性別定義編輯器

  • 以黃色女性人種爲例

  • 黃色男性人種

剩下的工做就是怎麼製造人類ide

  • 接口HumanFactory


在接口中,看到八卦爐是能夠生產出不一樣膚色人種的,有多少個八卦爐呢?
兩個,分別生產女性和男性,女性和男性八卦爐


人種有了,八卦爐也有了,咱們就來重現一下造人的光景


各類膚色的男性、女性都製造出來了
回頭來想一想咱們的設計,不知道你們有沒有去過工廠,每一個工廠分不少車間,每一個車間又分多條生產線,分別生產不一樣的產品
咱們能夠把八卦爐比喻爲車間,把八卦爐生產的工藝(生產白人、黑人仍是黃人)稱爲生產線,如此來看就是一個女性生產車間,專門生產各類膚色的女性,一個是男性生產車間,專門生產各類膚色男性
在這樣的設計下,各個車間和各條生產線的職責很是明確,在車間內各個生產出來的產品能夠有耦合關係,你要知道世界上黑、黃、白人種的比例是:1∶4∶6,那這就須要女媧娘娘在燒製的時候就要作比如例分配,在一個車間內協調好
這就是抽象工廠模式spa

1 定義

  • 官方定義

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.


抽象工廠模式的通用類圖
抽象工廠模式是工廠方法模式的升級版本
在有多個業務品種、業務分類時,經過抽象工廠模式產生須要的對象是一種很是好的解決方式
咱們來看看抽象工廠的通用源代碼,首先有兩個互相影響的產品線(產品族),例如製造汽車的左側門和右側門,這兩個應該是數量相等的——兩個對象之間的約束,每一個型號的車門都是不同的,這是產品等級結構約束的,咱們先看看兩個產品族的類圖
抽象工廠模式的通用源碼類圖
注意類圖上的圈圈、框框相對應,兩個抽象的產品類能夠有關係,例如共同繼承或實現一個抽象類或接口操作系統

  • 抽象產品類

  • 產品A1的實現類

  • 產品A2的實現類


產品B與此相似,再也不贅述線程

  • 抽象工廠類

抽象工廠類AbstractCreator的職責是定義每一個工廠要實現的功能,在通用代碼中,抽象工廠類定義了兩個產品族的產品建立

有N個產品族,在抽象工廠類中就應該有N個建立方法設計

如何建立一個產品,則是由具體的實現類來完成的3d

  • 產品等級1的實現類

  • 產品等級2的實現類

有M個產品等級就應該有M個實現工廠類,在每一個實現工廠中,實現不一樣產品族的生產任務

在具體的業務中如何產生一個與實現無關的對象呢?

在場景類中,沒有任何一個方法與實現類有關係,對於一個產品來講,咱們只要知道它的工廠方法就能夠直接產生一個產品對象,無須關心它的實現類

2 適用場景

一個對象族(或是一組沒有任何關係的對象)都有相同的約束

例如一個文本編輯器和一個圖片處理器,都是軟件實體,可是*nix下的文本編輯器和Windows下的文本編輯器雖然功能和界面都相同,可是代碼實現是不一樣的,圖片處理器也有相似狀況。也就是具備了共同的約束條件:操做系統類型。因而咱們可使用抽象工廠模式,產生不一樣操做系統下的編輯器和圖片處理器

3 優勢

封裝性

每一個產品的實現類不是高層模塊要關心的
它要關心的是什麼?是接口,是抽象,它不關心對象是如何建立出來,這由誰負責呢?工廠類,只要知道工廠類是誰,我就能建立出一個須要的對象,省時省力,優秀設計就應該如此

產品族內的約束爲非公開狀態

例如生產男女比例的問題上,確定有本身的打算,不能讓女盛男衰,不然女性的優勢不就體現不出來了嗎?
那在抽象工廠模式,就應該有這樣的一個約束:每生產1個女性,就同時生產出1.2個男性,這樣的生產過程對調用工廠類的高層模塊來講是透明的,它不須要知道這個約束,我就是要一個黃色女性產品就能夠了,具體的產品族內的約束是在工廠內實現的

4 缺點

產品族擴展很是困難

以通用代碼爲例,若是要增長一個產品C,也就是說產品家族由原來的2個增長到3個,看看咱們的程序有多大改動吧!
抽象類AbstractCreator要增長一個方法createProductC(),而後兩個實現類都要修改,想一想看,這嚴重違反了開閉原則,並且咱們一直說明抽象類和接口是一個契約
改變契約,全部與契約有關係的代碼都要修改,那麼這段代碼叫什麼?叫「有毒代碼」,——只要與這段代碼有關係,就可能產生侵害的危險!

是產品族擴展困難,而不是產品等級
在該模式下,產品等級是很是容易擴展的,增長一個產品等級,只要增長一個工廠類負責新增長出來的產品生產任務便可。也就是說橫向擴展容易,縱向擴展困難。以人類爲例子,產品等級中只有男、女兩個性別,現實世界還有一種性別:雙性人,那咱們要擴展這個產品等級也是很是容易的,增長三個產品類,分別對應不一樣的膚色,而後再建立一個工廠類,專門負責不一樣膚色人的雙性人的建立任務,徹底經過擴展來實現需求的變動,從這一點上看,抽象工廠模式是符合開閉原則的

產品等級結構與產品族



當一個工廠能夠建立出分屬於不一樣產品等級結構的一個產品族中的全部對象時
抽象工廠比工廠方法更適合!!!

5 實踐 coding




Java 類相關



Python相關




工廠方法關注產品等級結構
抽象工廠關注產品族

6 源碼應用


獲取的都是 MySQL 的 db 鏈接,爲一個產品族
Mybatis工廠應用

默認實現

首先從配置中獲取環境變量
初始化事務工廠,並對其賦值
再從事務工廠中獲取事務實例對象
再以之爲參數獲得執行線程池
最後再生成返回默認 sqlsession 實例

7 最佳實踐

抽象工廠模式是一個簡單的模式,使用的場景很是多,你們在軟件產品開發過程當中,涉及不一樣操做系統的時候,均可以考慮使用抽象工廠模式,例如一個應用,須要在三個不一樣平臺上運行,你會怎麼設計?分別設計三套不一樣的應用?
非也,經過抽象工廠模式屏蔽掉操做系統對應用的影響。三個不一樣操做系統上的軟件功能、應用邏輯、UI都應該是很是相似的,惟一不一樣的是調用不一樣的工廠方法,由不一樣的產品類去處理與操做系統交互的信息

本文由博客一文多發平臺 OpenWrite 發佈!
相關文章
相關標籤/搜索