抽象工廠模式 建立型 設計模式(四)
阿新 • • 發佈:2018-11-13
抽象工廠模式是工廠方法模式的進一步抽象
在工廠模式中,客戶端程式依賴(消費)一種抽象產品角色Product
所有的ConcreteCreator的返回型別都是Product,因為抽象工廠角色Creator就是返回Product
但是,如果一個系統需要依賴多個不同的抽象產品角色怎麼辦?
也就是需要Product1 Product2 ... 他們是不同的抽象角色,工廠模式就歇菜了,簡單工廠模式也只是一種型別
此時,就需要抽象工廠模式,抽象工廠模式可以建立多種型別的產品
簡言之,工廠模式只能生產一種產品,比如青島啤酒廠生產各式樣的啤酒,他不可能生產大米
抽象工廠角色就可以生產啤酒和大米
我們舉例說明
比如實際專案中,DAO(資料庫訪問層)都有CRUD 操作(增查改刪)
但是有不同的資料庫,假設使用MYSQL和ORACLE兩種資料庫
那麼對於CRUD操作都有兩種型別 MYSQL和ORACLE
產品的等級結構如下圖所示
CRUD操作四個操作對應四個等級產品(簡單理解就是四種類型產品)
四個等級中的MYSQL 就組成了一個產品族
四個等級中的ORACLE 也組成了一個產品族
再比如 快餐店經常都有銷售雞腿和漢堡(兩種產品)
但是有不同的快餐店,比如KFC和Mcdonalds
產品的等級結構如下圖
雞腿和漢堡對應兩個產品等級體系結構
兩個等級結構中的KFC組成了一個產品族
兩個等級結構中的Mcdonalds組成了一個產品族
再比如,計算機中有文書處理軟體和影象處理軟體
但是計算機有不同的作業系統平臺,比如Windows和Linux
有文書處理和影象處理兩種產品等級結構
兩個等級結構中的windows平臺下軟體組成了一個產品族
兩個等級結構中的Linux平臺下軟體組成了一個產品族
所以說,不同型別的產品,就是不同的等級結構
水果是一個等級,蔬菜是一個等級,PC是一個等級
不同等級結構中,相關聯的一組功能就是一個產品族
相關聯的含義是有一些公共的限制約束或者特性
水果是一個等級,蔬菜是一個等級
熱帶水果和熱帶蔬菜,產地都是南方屬於熱帶地區 , 這就是一個產品族
主機板是一個等級,有多種廠家生產,比如華碩 戴爾
顯示器是一個等級,有多種廠家生產,比如華碩 戴爾
主機板和顯式器可以組成電腦的一部分
華碩主機板和華碩顯示器都是華碩品牌的,是一個產品族
簡單理解就是:每個型別來一個,就構成了一個產品族
想要使用工廠模式,首先就是要理清楚產品的等級結構
簡單工廠和工廠方法模式都只能建立一種等級結構的產品
如果想要建立多個等級結構的產品,你可以藉助於多個工廠方法模式
另外,如果有產品族的概念,你可以考慮抽象工廠模式
需要特別關注是否有關聯和共同約束限制條件,也就是是否能夠成為產品族
產品族與產品等級
想要理解抽象工廠的本質,需要先介紹兩個概念 產品族和產品等級結構產品等級結構指的是產品的分類劃分結構 功能相關聯的不同產品(位於不同的等級結構)就組成了一個產品族 |
一個產品族中,有多少個產品,跟產品等級結構的個數是一致的 也就是說有多少種產品,一個產品族就有多少個 有CRUD四個產品等級,一個mysql產品族就有四個產品 有雞腿漢堡兩個產品等級,KFC產品族就有兩種產品 |
產品族就是一個產品類別中拿出來一個 所以就是一個型別有多少種,就是有多少個產品族 |
意圖
提供一個建立一系列相關或者相互依賴物件的介面,而無需指定他們具體的類。 其實就是工廠方法模式中一個方法,建立一個型別,此處多個方法,建立多個型別,簡單理解就是這樣結構
說完了產品等級結構和產品族的概念 我們看下抽象工廠模式的結構產品等級結構product ProductA和ProductB 他們分別有對應的兩種型別的產品 ConcreteProductA1 和 ConcreteProductA2 ConcreteProductB1 和 ConcreteProductB2 |
抽象工廠角色Creator Creator可以建立ProductA和ProductB兩種抽象型別 他有兩個實現類工廠ConcreteCreator1和 ConcreteCreator2 |
具體的工廠ConcreteCreator 每一個ConcreteCreator都可以生產一個產品族的產品 也就是ConcreteCreator1可以生產ConcreteProductA1 和 ConcreteProductB1 |
角色介紹
抽象工廠角色(Abstract Factory) 工廠方法的核心,與系統具體邏輯無關,通常是java介面或者抽象類 所有的具體的工廠都需要實現它,也就是上圖中的Creator 具體工廠角色(Concrete Factory) 直接接受客戶端程式請求,建立產品的例項,它可以建立一個產品族的例項物件 抽象產品角色(Abstract Product) 為一類產品物件宣告一個抽象表示 具體產品角色(Concrete Product) 定義一個被建立的具體的物件的型別,實現Abstract Product介面 類似工廠模式,具體的工廠角色可以有多個,分別對應不同的產品族 有幾個產品族就會有幾個具體的工廠示例程式碼
有兩個產品等級結構 Fruit和Vegetable 也就是有水果和蔬菜兩種商品 假設有兩個商店,他們都提供水果和蔬菜 第一個商店提供的水果和蔬菜是蘋果和土豆 第二個商店提供的水果和蔬菜是橘子和白菜 也就是蘋果Apple和土豆Potato是一個產品族,由一個店鋪在賣 橘子Orange和大白菜Cabbage是一個產品族,由一個店鋪在賣 產品類Fruit以及Apple和Orange與工廠模式中示例程式碼一樣 Vegetable表示蔬菜的抽象角色 Potato和Cabbage為具體的蔬菜 有抽象工廠角色Factory 以及具體的工廠ConcreteFactory1 和 ConcreteFactory2 Fruit產品結構體系package abstractFactory; /** * Created by noteless on 2018/10/9. * Description: */ public interface Fruit { String description(); }
package abstractFactory; /** * Created by noteless on 2018/10/9. * Description: */ public class Apple implements Fruit { @Override public String description() { return "apple"; } }
package abstractFactory; /** * Created by noteless on 2018/10/9. * Description: */ public class Orange implements Fruit { @Override public String description() { return "Orange"; } }蔬菜產品結構體系
package abstractFactory; /** * Created by noteless on 2018/10/10. * Description: */ public interface Vegetable { String description(); }
package abstractFactory; /** * Created by noteless on 2018/10/10. * Description: */ public class Potato implements Vegetable { @Override public String description() { return "potato"; } }
package abstractFactory; /** * Created by noteless on 2018/10/10. * Description: */ public class Cabbage implements Vegetable { @Override public String description() { return "cabbage"; } }工廠體系
package abstractFactory; /** * Created by noteless on 2018/10/9. * Description: */ public interface Factory { Fruit createFruit(); Vegetable createVegetable(); }
package abstractFactory; /** * Created by noteless on 2018/10/10. * Description: */ public class ConcreateFactory1 implements Factory { @Override public Fruit createFruit() { return new Apple(); } @Override public Vegetable createVegetable() { return new Potato(); } }
package abstractFactory; /** * Created by noteless on 2018/10/10. * Description: */ public class ConcreateFactory2 implements Factory { @Override public Fruit createFruit() { return new Orange(); } @Override public Vegetable createVegetable() { return new Cabbage(); } }測試程式碼 可以看得出來,下圖的形式中 只需要修改一行程式碼,就可以做到整個產品族的切換