1. 程式人生 > 其它 >設計模式專題(十一)——抽象工廠模式

設計模式專題(十一)——抽象工廠模式

設計模式專題(十一)——抽象工廠模式

(原創內容,轉載請註明來源,謝謝)

一、概述

抽象工廠模式(AbstractFactory),提供建立一系列相關或者相互依賴的介面,不需要指定他們具體的類。

抽象工廠模式是在工廠方法模式的基礎上,將工廠類進行擴充,當有多種不同的工廠,且每個工廠都有很多的子工廠時,就可以使用此模式。在工廠抽象類的基礎上,根據不同的工廠建多個抽象類,這樣當需要切換工廠時,只需要切換抽象類的宣告即可。

二、特點

1、便於交換產品

一個應用中,只需要在初始化的時候出現一次,使得改變一個工廠很容易,相當於把工廠當作配置檔案,供客戶端使用。

2、解耦與靈活性

抽象工廠模式,讓建立例項的過程與客戶端分離,客戶端通過抽象介面操縱例項,產品的具體類名也被具體的工廠實現分離,不會直接出現在程式碼中。

3、缺點——涉及的類多

由於大量的用到了抽象,因此需要建立的類很多,每新增一個工廠時,需要增加好幾個類,且當有方法需要變動時,改動的地方也較多。

因此,常常結合簡單工廠模式和抽象工廠模式,將抽象工廠模式不是在工廠方法模式中去抽象,而是將簡單工廠模式進行抽象。

三、類圖

四、業務場景

1、業務分析

現有兩個業務系統,使用的資料庫不一樣,用不同的方式進行報表統計,一個是分割槽域進行統計,一個是分產品型別進行統計。由於不同的系統由不同的人員進行開發,因此確實可能存在不同的資料庫。

此時,需要開發一個比對系統,比較兩個系統的統計結果的一致性,則需要在兩個資料庫中進行切換,假設兩個資料庫是mysql和oracle,且操作的表較多,現假設比對的是order和stock兩個表。則抽象工廠模式可以解決此問題。

2、專案分析

現需要設計以下內容:

1)抽象介面OrderInterface,定義實現countByDate、countByArea等方法。

2)兩個具體類,MysqlOrder和OracleOrder,分別繼承OrderInterface,用Mysql和Oracle的方法去實現。

3)抽象介面StockInterface,定義實現stockAnalysis、stockRemain等方法。

4)兩個具體類,MysqlStock和OracleStock,分別基礎StockInterface。

5)資料庫操作類DataAccessObject(很多地方稱為DAO),其接收使用者傳入的引數,判斷如果是mysql就載入mysql相關的類,如果是oracle則載入oracle相關的類。

6)客戶端,呼叫DataAccessObject,傳入引數,並獲取返回的結果。

3、具體實現

         interfaceOrderInterface{
         public functioncountByDate($start, $end){}
         public functioncountByArea($xRadio, $yRadio){}
}
class MysqlOrder implements OrderInterface{
         public functioncountByDate($start, $end){
                   //...mysql的方式處理
         }
         public functioncountByArea($xRadio, $yRadio){
                   //...mysql的方式處理
         }
}
class OracleOrder implements OrderInterface{
         public functioncountByDate($start, $end){
                   //...oracle的方式處理
         }
         public functioncountByArea($xRadio, $yRadio){
                   //...oracle的方式處理
         }
}
//stockinterface以及兩個類類似,省略
//dataAccessObject
class DataAccessObject{
         private $dbType;
         public function__construct($dbType){
                   $this->dbType= $dbType;
         }
         public function__set($prop, $val){
                   $this->$prop= $val;
         }
         public function__get($prop){
                   return$this->$prop;
         }
         public functiongetData(){
                   $classOrder= ucfirst(strtolower($this->dbType)) . 'Order';//轉換成Mysql格式,即首字母大寫,其他小寫
                   $objOrder =new $classOrder();
                   $classStock= ucfirst(strtolower($this->dbType)) . 'Stock';//轉換成Mysql格式,即首字母大寫,其他小寫
                   $objStock =new $classStock();                 
                   return array(
                            $objOrder->countByDate($start,$end),
                            $objOrder->countByArea($xRadio,$yRadio),
                            //$objStock->xxxx,
                            //$objStock->yyyy
                   );
         }
}
//客戶端呼叫
$dao = new DataAccessObject)('mysql');
$res = $dao->getData();

—written by linhxx 2017.08.03

相關閱讀:

設計模式專題(十)——觀察者模式

設計模式專題(九) ——外觀模式

設計模式專題(八) ——模板方法模式

設計模式專題(七)——建造者模式

設計模式專題(六)——原型模式

設計模式專題(五)——工廠方法模式

設計模式專題(四)——代理模式

設計模式專題(三)——裝飾模式

設計模式專題(二)——策略模式

設計模式專題(一)——面向物件的設計原則