??原文地址為https://www.cnblogs.com/haixiang/p/12055272.html,轉載請注明出處!
簡介
工廠方法模式中考慮的是一類產品的生產,如畜牧場只養動物、電視機廠只生產電視機、計算機軟體學院只培養計算機軟體專業的學生等,
同種類稱為同等級,也就是說:工廠方法模式只考慮生產同等級的產品,但是在現實生活中許多工廠是綜合型的工廠,能生產多等級(種類) 的產品,如農場里既養動物又種植物,電器廠既生產電視機又生產洗衣機或空調,大學既有軟體專業又有生物專業等,
本節要介紹的抽象工廠模式將考慮多等級產品的生產,將同一個具體工廠所生產的位于不同等級的一組產品稱為一個產品族,
抽象工廠模式(Abstract Factory Pattern)是圍繞一個超級工廠創建其他工廠,該超級工廠又稱為其他工廠的工廠,這種型別的設計模式屬于創建型模式,它提供了一種創建物件的最佳方式,
在抽象工廠模式中,介面是負責創建一個相關物件的工廠,不需要顯式指定它們的類,每個生成的工廠都能按照工廠模式提供物件,
優缺點
-
產品易擴展(例如后面案例中擴展新的Mq、資料庫、快取)
-
產品族擴展非常困難(例如后面案例中新增Server產品族),要增加一個系列的某一產品,既要在抽象工廠里加代碼,又要在具體的工廠類里面加代碼,
使用場景
- 當需要創建的物件是一系列相互關聯或相互依賴的產品族時,如電器工廠中的電視機、洗衣機、空調等,
- 系統中有多個產品族,但每次只使用其中的某一族產品,如有人只喜歡穿某一個品牌的衣服和鞋,
- 系統中提供了產品的類別庫,且所有產品的介面相同,客戶端不依賴產品實體的創建細節和內部結構,
具體案例
一個完整成熟的系統可以采用不同的技術來解決業務層面的問題,例如資料庫可以用Mysql也可以用Oracle,本例中提供了三個產品,分別是訊息佇列Mq、資料庫DataBase以及快取Mycache三個介面,每個介面下都有自己的具體實作類,也就是工廠的產品,AbstractSystemFac作為抽象工廠類,呼叫了上述的三個介面,來組裝三個不同的產品,SimpleSystemFac與HugeSystemFac是兩個具體的工廠類,SimpleSystemFac是一個技術解決方案,選用MySQL資料庫、MemCache、RabbitMQ三種產品來實作自己的技術架構,而HugeSystemFac采用Oracle資料庫、Redis、Kafka三種產品,這兩個工廠類的方法一致,只不過具體呼叫的產品型別不同,

資料庫介面及實作類
/**
* 資料庫型別
* @author anqi
*/
public interface DataBase {
/** 初始化資料庫 */
void init();
}
public class Mysql implements DataBase {
@Override
public void init() {
System.out.println("MySQL初始化");
}
}
public class Oracle implements DataBase{
@Override
public void init() {
System.out.println("Oracle初始化");
}
}
public class OceanBase implements DataBase{
@Override
public void init() {
System.out.println("OceanBase初始化");
}
}
訊息佇列介面及實作類
/**
* 訊息佇列型別
* @author anqi
*/
public interface Mq {
/** 發送訊息 */
void sendMessage();
}
public class RabbitMQ implements Mq {
@Override
public void sendMessage() {
System.out.println("使用RabbitMQ發送訊息");
}
}
public class KafkaMQ implements Mq {
@Override
public void sendMessage() {
System.out.println("使用kafka發送訊息");
}
}
快取介面及實作類
/**
* 快取型別
* @author anqi
*/
public interface MyCache{
/** 快取資料 */
void cacheData();
}
public class MemCache implements MyCache {
@Override
public void cacheData() {
System.out.println("使用MemCache快取");
}
}
public class RedisCache implements MyCache {
@Override
public void cacheData() {
System.out.println("使用redis快取");
}
}
抽象工廠類
/**
* 抽象工廠類
*/
public abstract class AbstractSystemFac {
public abstract MyCache useCache();
public abstract Mq useMq();
public abstract DataBase useDataBase();
}
具體工廠
public class SimpleSystemFac extends AbstractSystemFac {
@Override
public MyCache useCache() {
return new MemCache();
}
@Override
public Mq useMq() {
return new RabbitMQ();
}
@Override
public DataBase useDataBase() {
return new Mysql();
}
}
具體工廠
public class HugeSystemFac extends AbstractSystemFac {
@Override
public MyCache useCache() {
return new RedisCache();
}
@Override
public Mq useMq() {
return new KafkaMQ();
}
@Override
public DataBase useDataBase() {
return new Oracle();
}
}
測驗類
public class TestDemo {
public static void main(String[] args) {
AbstractSystemFac simpleFac = new SimpleSystemFac();
MyCache memcache = simpleFac.useCache();
DataBase mysql = simpleFac.useDataBase();
Mq rabbitmq = simpleFac.useMq();
memcache.cacheData();;
mysql.init();
rabbitmq.sendMessage();
AbstractSystemFac hugeFac = new HugeSystemFac();
MyCache redis = hugeFac.useCache();
DataBase oracle = hugeFac.useDataBase();
Mq kafka = hugeFac.useMq();
redis.cacheData();
oracle.init();
kafka.sendMessage();
}
}
使用MemCache快取
MySQL初始化
使用RabbitMQ發送訊息
使用redis快取
Oracle初始化
使用kafka發送訊息
我們可以靈活地擴充一個新的產品RocketMQ,或者一個新的工廠類NewSystemFac,如下圖所示

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/32501.html
標籤:設計模式
