抽象工廠模式


💛原文地址爲http://www.javashuo.com/article/p-zwuxyrfj-bb.html,轉載請註明出處!java

簡介

工廠方法模式中考慮的是一類產品的生產,如畜牧場只養動物、電視機廠只生產電視機、計算機軟件學院只培養計算機軟件專業的學生等。mysql

同種類稱爲同等級,也就是說:工廠方法模式只考慮生產同等級的產品,可是在現實生活中許多工廠是綜合型的工廠,能生產多等級(種類) 的產品,如農場裏既養動物又種植物,電器廠既生產電視機又生產洗衣機或空調,大學既有軟件專業又有生物專業等。redis

本節要介紹的抽象工廠模式將考慮多等級產品的生產,將同一個具體工廠所生產的位於不一樣等級的一組產品稱爲一個產品族,sql

抽象工廠模式(Abstract Factory Pattern)是圍繞一個超級工廠建立其餘工廠。該超級工廠又稱爲其餘工廠的工廠。這種類型的設計模式屬於建立型模式,它提供了一種建立對象的最佳方式。數據庫

在抽象工廠模式中,接口是負責建立一個相關對象的工廠,不須要顯式指定它們的類。每一個生成的工廠都能按照工廠模式提供對象。設計模式

優缺點

  • 產品易擴展(例如後面案例中擴展新的Mq、數據庫、緩存)緩存

  • 產品族擴展很是困難(例如後面案例中新增Server產品族),要增長一個系列的某一產品,既要在抽象工廠里加代碼,又要在具體的工廠類裏面加代碼。架構

使用場景

  1. 當須要建立的對象是一系列相互關聯或相互依賴的產品族時,如電器工廠中的電視機、洗衣機、空調等。
  2. 系統中有多個產品族,但每次只使用其中的某一族產品。若有人只喜歡穿某一個品牌的衣服和鞋。
  3. 系統中提供了產品的類庫,且全部產品的接口相同,客戶端不依賴產品實例的建立細節和內部結構。

具體案例

一個完整成熟的系統能夠採用不一樣的技術來解決業務層面的問題,例如數據庫能夠用Mysql也能夠用Oracle。本例中提供了三個產品,分別是消息隊列Mq、數據庫DataBase以及緩存Mycache三個接口,每一個接口下都有本身的具體實現類,也就是工廠的產品。AbstractSystemFac做爲抽象工廠類,調用了上述的三個接口,來組裝三個不一樣的產品。SimpleSystemFacHugeSystemFac是兩個具體的工廠類,SimpleSystemFac是一個技術解決方案,選用MySQL數據庫、MemCache、RabbitMQ三種產品來實現本身的技術架構。而HugeSystemFac採用Oracle數據庫、Redis、Kafka三種產品,這兩個工廠類的方法一致,只不過具體調用的產品類型不一樣。oracle

數據庫接口及實現類

/**
 * 數據庫類型
 * @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,以下圖所示

相關文章
相關標籤/搜索