以下內容摘自
http://www.runoob.com/design-pattern/abstract-factory-pattern.html
https://blog.csdn.net/jason0539/article/details/23020989
在此權作爲筆記
抽象工廠模式
上一章我們分析了簡單工廠模式與工廠方法模式,這一章我們來探討一下抽象工廠模式。先看菜鳥教程上給的定義。
概念
意圖:提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
主要解決:主要解決接口選擇的問題。
何時使用:系統的產品有多於一個的產品族,而系統只消費其中某一族的產品。
如何解決:在一個產品族裏面,定義多個產品。
關鍵代碼:在一個工廠裏聚合多個同類產品。
應用實例:工作了,爲了參加一些聚會,肯定有兩套或多套衣服吧,比如說有商務裝(成套,一系列具體產品)、時尚裝(成套,一系列具體產品),甚至對於一個家庭來說,可能有商務女裝、商務男裝、時尚女裝、時尚男裝,這些也都是成套的,即一系列具體產品。假設一種情況(現實中是不存在的,要不然,沒法進入共產主義了,但有利於說明抽象工廠模式),在您的家中,某一個衣櫃(具體工廠)只能存放某一種這樣的衣服(成套,一系列具體產品),每次拿這種成套的衣服時也自然要從這個衣櫃中取出了。用 OO 的思想去理解,所有的衣櫃(具體工廠)都是衣櫃類的(抽象工廠)某一個,而每一件成套的衣服又包括具體的上衣(某一具體產品),褲子(某一具體產品),這些具體的上衣其實也都是上衣(抽象產品),具體的褲子也都是褲子(另一個抽象產品)。
優點:當一個產品族中的多個對象被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的對象。
缺點:產品族擴展非常困難,要增加一個系列的某一產品,既要在抽象的 Creator 里加代碼,又要在具體的裏面加代碼。
使用場景: 1、QQ 換皮膚,一整套一起換。 2、生成不同操作系統的程序。
注意事項:產品族難擴展,產品等級易擴展。
實現
我們現在有這樣一個場景,已知地產商蓋樓房,房子存在室廳區別,如一室一廳,二室二廳,三室三廳,2室0廳等。
產品接口-室
public interface Room {
/**
* 返回臥室數
* @return void
* 時間:2018年4月24日
*/
public void getRoom();
}
具體實現-一室,二室
public class OneRoom implements Room{
@Override
public void getRoom() {
System.out.println("one room");
}
}
產品接口-廳
public interface LivingRoom {
/**
* 返回客廳數
* @return void
* 時間:2018年4月24日
*/
public void getLivingRoom();
}
具體實現-0廳,一廳
public class OneLivingRoom implements LivingRoom{
@Override
public void getLivingRoom() {
System.out.println("one living room");
}
}
抽象工廠-生產室和廳
public interface HomeAbstractFactory {
/**
* 獲取室
* @return Room
* @return
* 時間:2018年4月24日
*/
public Room getRoom(String roomType);
/**
* 獲取廳
* @return LivingRoom
* @return
* 時間:2018年4月24日
*/
public LivingRoom getLivingRoom(String livingType);
}
具體工廠-室工廠
public class RoomFactory implements HomeAbstractFactory{
@Override
public Room getRoom(String roomType) {
if (null == roomType || 0 == roomType.length()) {
return null;
}
if ("one".equalsIgnoreCase(roomType)) {
return new OneRoom();
}
return null;
}
@Override
public LivingRoom getLivingRoom(String livingType) {
// TODO Auto-generated method stub
return null;
}
}
具體工廠-廳工廠
public class LivingRoomFactory implements HomeAbstractFactory{
@Override
public Room getRoom(String roomType) {
// TODO Auto-generated method stub
return null;
}
@Override
public LivingRoom getLivingRoom(String livingType) {
if (null == livingType || 0 == livingType.length()) {
return null;
}
if ("one".equalsIgnoreCase(livingType)) {
return new OneLivingRoom();
}
return null;
}
}
工廠創造器
public class HomeFactoryProducer {
public static HomeAbstractFactory getFactory(String type) {
if ("room".equalsIgnoreCase(type)) {
return new RoomFactory();
}
if ("living".equalsIgnoreCase(type)) {
return new LivingRoomFactory();
}
return null;
}
}
客戶類
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {
HomeAbstractFactory factory = HomeFactoryProducer.getFactory("room");
Room room = factory.getRoom("one");
room.getRoom();
HomeAbstractFactory factory2 = HomeFactoryProducer.getFactory("living");
LivingRoom livingRoom = factory2.getLivingRoom("one");
livingRoom.getLivingRoom();
}
}
在這,我們可以發現一點問題,如抽象工廠模式和簡單工廠模式與工廠方法模式有很大的相似之處,同時我們也會發現,如果要添加新的產品,工廠實現類就需要修改。在這裏,我們可以通過上一章工廠方法模式中的方法來解決——既給每一個產品創建相對應的工廠類
抽象工廠模式與工廠方法模式區別
工廠模式:
- 一個產品接口,多個具體產品實現
- 一個工廠接口,多個具體工廠實現
- 每個具體工廠實現只能創建相對應的具體產品
抽象工廠模式:
- 多個產品接口,每個產品接口有相應的產品實現
- 一個抽象工廠類,有多個具體工廠實現
- 每個具體工廠可以創建多個具體產品類的實例
區別:
- 工廠方法模式只有一個抽象產品類,而抽象工廠有多個
- 工廠方法模式的具體工廠類智能創建一個具體產品類的實例,而抽象工廠模式可以創建多個