設計模式專題(十一)——抽象工廠模式
設計模式專題(十一)——抽象工廠模式
(原創內容,轉載請註明來源,謝謝)
一、概述
抽象工廠模式(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
相關閱讀: