一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - PHP教程 - Zend Framework中的簡單工廠模式 圖文

Zend Framework中的簡單工廠模式 圖文

2020-01-04 19:25PHP教程網(wǎng) PHP教程

某天又然后想到好久沒復(fù)習(xí)設(shè)計模式了。綜合一下,復(fù)習(xí)一個設(shè)計模式之后在ZF中找一下使用這模式的源碼吧,不讀所有源碼,讀讀比較”高級”的部分吧,要說模式,暫時不知道是不是所有模式ZF里面都有,但是應(yīng)該有足夠的模式

前段時間用來ZF,把他當(dāng)黑盒感覺不是很好,一直有看其源碼的沖動,但是。。。如果一點一點點看的話,挑戰(zhàn)確實有些大了。某天又然后想到好久沒復(fù)習(xí)設(shè)計模式了。綜合一下,復(fù)習(xí)一個設(shè)計模式之后在ZF中找一下使用這模式的源碼吧,不讀所有源碼,讀讀比較”高級”的部分吧,要說模式,暫時不知道是不是所有模式ZF里面都有,但是應(yīng)該有足夠的模式夠我最近看了,在說可以找找其他開源的軟件來找模式。這段時間被各種筆試神馬亂七八糟的把生活搞得稍微有點亂,但是不管怎樣,復(fù)習(xí)還是必須的吧。再說一下ZF吧,ZF一個好處就是各個component比較獨立,component之間沒有過多的依賴,這樣一來,為使用者提供了方便,當(dāng)然也為我這樣無聊且懶的想看源碼的人提供了方便。 

今天看看簡單工廠,ZF里面不缺模式,更不缺工廠模式,大名鼎鼎的的 Zend_Db就毫不吝嗇的使用簡單工廠,再ctrl+h(zend studio下)一下會發(fā)現(xiàn)factory特別多,如果沒猜錯應(yīng)該大多應(yīng)該也是簡單工廠。由于Zend_Db 最常用,我也就自然的會比較想看一下他的實現(xiàn)。在查看源碼之前先復(fù)習(xí)一下怎么用Zend_Db和簡單工廠(這里是一個stack,先復(fù)習(xí)簡單工廠)。 

復(fù)習(xí)簡單工廠模式 
用類圖回憶一下,簡單工廠類圖: 

Zend Framework中的簡單工廠模式 圖文

借用《研磨設(shè)計模式》作者的一張圖,可以看到Client通過factory來獲取對象,通過Api結(jié)構(gòu)來調(diào)用。用factory把具體的Api的創(chuàng)建隱藏起來。而其他所有使用者在使用時,只需要知道用factory創(chuàng)建,通過Api結(jié)構(gòu)調(diào)用即可,簡單復(fù)習(xí)完成。看到類圖應(yīng)該能想起簡單工廠了,因為他本身確實很簡單。復(fù)習(xí)完簡單工廠,思維稍微跳躍一下,直接來看看Zend_Db的使用。 
1.復(fù)習(xí)Zend_Db的使用 
如果不知道如何使用,準(zhǔn)備看XXX的源碼卻不知道怎么用XXX,這有點囧,所以先小小的看一下Zend_Db的使用,下面這段是在ZF官方文檔里面的(個人不是很喜歡ZF文檔,沒Yii易讀) 
/public/index.php 

復(fù)制代碼代碼如下:


$db = Zend_Db::factory('Pdo_Mysql', array( 
'host' => '127.0.0.1', 
'username' => 'webuser', 
'password' => 'xxxxxxxx', 
'dbname' => 'test' 
)); 


這里是把數(shù)據(jù)庫配置也放到代碼里面,看起來最簡單(實際上其他也不難,只是數(shù)據(jù)庫放置的位置不同,便于管理罷了),但這樣在正常情況下不是最好的方式,但是為了突出重點,這里選用這中最簡單的方式。注意里面的Zend_Db::factory(‘Pdo_Mysql'…這段 
上面生成了一個$db(一個Zend_Db對象),使用上面的$db進(jìn)行查詢?nèi)缦拢?nbsp;

復(fù)制代碼代碼如下:


$db->setFetchMode(Zend_Db::FETCH_OBJ); 
$result = $db->fetchAssoc( 
'SELECT bug_id, bug_description, bug_status FROM bugs' 
); 


繼續(xù)來自官網(wǎng)文檔,這是取記錄的模式為Object,再fetch,一切目前看起來都自然而然,但是至今還是把它Zend_Db當(dāng)作一個黑盒使用。下面可以進(jìn)入正題。 
首先,查看一下zend/Db.php的代碼摘要: 

復(fù)制代碼代碼如下:


< ?php 
class Zend_Db 

/** 
設(shè)定一些常量和默認(rèn)值 
*/ 
/** 
* Factory for Zend_Db_Adapter_Abstract classes. 

* First argument may be a string containing the base of the adapter class 
* name, e.g. 'Mysqli' corresponds to class Zend_Db_Adapter_Mysqli. This 
* name is currently case-insensitive, but is not ideal to rely on this behavior. 
* If your class is named 'My_Company_Pdo_Mysql', where 'My_Company' is the namespace 
* and 'Pdo_Mysql' is the adapter name, it is best to use the name exactly as it 
* is defined in the class. This will ensure proper use of the factory API. 

* First argument may alternatively be an object of type Zend_Config. 
* The adapter class base name is read from the 'adapter' property. 
* The adapter config parameters are read from the 'params' property. 

* Second argument is optional and may be an associative array of key-value 
* pairs. This is used as the argument to the adapter constructor. 

* If the first argument is of type Zend_Config, it is assumed to contain 
* all parameters, and the second argument is ignored. 

* @param mixed $adapter String name of base adapter class, or Zend_Config object. 
* @param mixed $config OPTIONAL; an array or Zend_Config object with adapter parameters. 
* @return Zend_Db_Adapter_Abstract 
* @throws Zend_Db_Exception 
*/ 
public static function factory ($adapter, $config = array()) 

//使用Zend_Config對象,上述方式?jīng)]有使用,直接使用Array 
if ($config instanceof Zend_Config) { 
$config = $config->toArray(); 

/* 
* Convert Zend_Config argument to plain string 
* adapter name and separate config object. 
*/ 
if ($adapter instanceof Zend_Config) { 
if (isset($adapter->params)) { 
$config = $adapter->params->toArray(); 

if (isset($adapter->adapter)) { 
$adapter = (string) $adapter->adapter; 
} else { 
$adapter = null; 


/* 
* Verify that adapter parameters are in an array. 
*/ 
if (! is_array($config)) { 
/** 
* @see Zend_Db_Exception 
*/ 
require_once 'Zend/Db/Exception.php'; 
throw new Zend_Db_Exception( 
'Adapter parameters must be in an array or a Zend_Config object'); 

/* 
* Verify that an adapter name has been specified. 
*/ 
if (! is_string($adapter) || empty($adapter)) { 
/** 
* @see Zend_Db_Exception 
*/ 
require_once 'Zend/Db/Exception.php'; 
throw new Zend_Db_Exception( 
'Adapter name must be specified in a string'); 

/* 
* Form full adapter class name 
*/ 
$adapterNamespace = 'Zend_Db_Adapter'; 
if (isset($config['adapterNamespace'])) { 
if ($config['adapterNamespace'] != '') { 
$adapterNamespace = $config['adapterNamespace']; 

unset($config['adapterNamespace']); 

// Adapter no longer normalized- see http://framework.zend.com/issues/browse/ZF-5606 
$adapterName = $adapterNamespace . '_'; 
$adapterName .= str_replace(' ', '_', 
ucwords(str_replace('_', ' ', strtolower($adapter)))); 
/* 
* Load the adapter class. This throws an exception 
* if the specified class cannot be loaded. 
*/ 
if (! class_exists($adapterName)) { 
require_once 'Zend/Loader.php'; 
Zend_Loader::loadClass($adapterName); 

/* 
* Create an instance of the adapter class. 
* Pass the config to the adapter class constructor. 
*/ 
$dbAdapter = new $adapterName($config); 
/* 
* Verify that the object created is a descendent of the abstract adapter type. 
*/ 
if (! $dbAdapter instanceof Zend_Db_Adapter_Abstract) { 
/** 
* @see Zend_Db_Exception 
*/ 
require_once 'Zend/Db/Exception.php'; 
throw new Zend_Db_Exception( 
"Adapter class '$adapterName' does not extend Zend_Db_Adapter_Abstract"); 

return $dbAdapter; 


最上方的注釋非常值得看,它清楚的說明了這個工廠,另外一段比較重要的幾段代碼(忽略其中的異常處理)是: 

復(fù)制代碼代碼如下:


//factory有一個參數(shù)叫做$adapter 
public static function factory($adapter, $config = array()) 

//確定namespace 
$adapterNamespace = 'Zend_Db_Adapter'; 

//用namespace和上面?zhèn)魅氲?adapter構(gòu)造類名 
$adapterName = $adapterNamespace . '_'; 
$adapterName .= str_replace(' ', '_', ucwords(str_replace('_', ' ', strtolower($adapter)))); 

//用上面生成的類名new出obj,看起來PHP比java方便那么一點點哈(Class.forName(‘XXX').newInstance()) 
$dbAdapter = new $adapterName($config); 


在回想上面使用Zend_Db::factory生成$db的地方: 

復(fù)制代碼代碼如下:


$db = Zend_Db::factory('Pdo_Mysql', array( 
'host' => '127.0.0.1', 
'username' => 'webuser', 
'password' => 'xxxxxxxx', 
'dbname' => 'test' 
)); 


factory方法的第一個參數(shù)即是$adapter為Pdo_Mysql,記住這里是Pdo_Mysql,再跳躍一下,根據(jù)上面的$adapterNamespace = ‘Zend_Db_Adapter';可以看到生成的找到$dbAdapter的值最終必為:Zend_Db_Adapter_Pdo_Mysql,ok,根據(jù)此名字找到zend/db/adapter/pdo目錄下,哈,這么多熟悉的面孔,看到了熟悉的MySql、Mssql、Sqlite這些老面孔了。 
Zend Framework中的簡單工廠模式 圖文

注意,注意,里面還有個低調(diào)的Abstract.php,里面他們的父類Zend_Db_Adapter_Pdo_Abstract。打開Mysql.php可以看到 
class Zend_Db_Adapter_Pdo_Mysql extends Zend_Db_Adapter_Pdo_Abstract 

嗯,類名Zend_Db_Adapter_Pdo_Mysql和上面生成的名字一樣滴,在看看其他幾個文件里面的類,他們都繼承自Zend_Db_Adapter_Pdo_Abstract,如果要畫類圖,那就應(yīng)該會有如下這么一張類圖: 
Zend Framework中的簡單工廠模式 圖文
接著再加入調(diào)用著Client和工廠函數(shù)所在的位置Zend_Db,這張簡單的類圖就應(yīng)該是, 
Zend Framework中的簡單工廠模式 圖文
一個非常非常純凈的簡單工廠就這么出來了(不像簡單工廠類圖嗎?那只是因為類的位置沒放好)。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 免费港剧在线观看港剧 | 天天做天天爽 | 国产亚洲福利一区二区免费看 | 双性受合不垅腿攻np | 免费二区 | 黄 在线播放 | 麻豆网站视频国产在线观看 | 日本黄视频在线播放 | 青青青在线观看国产精品 | 国产一及毛片 | 黑帮少爷爱上我第8集在线观看 | a男人的天堂久久a毛片 | 日本午夜大片免费观看视频 | 国产51社区精品视频资源 | 青青草99久久精品国产综合 | 免费国产高清视频 | 亚洲AV蜜桃永久无码精品无码网 | hezyo加勒比一区二区三区 | 精品91一区二区三区 | 国产精品久久久久这里只有精品 | 午夜影院在线免费观看 | 亚洲国产99在线精品一区69堂 | pregnantxxx孕交 | 俄罗斯性高清完整版 | 黑人巨荃大战乌克兰美女 | 国产卡一卡二卡3卡乱码免费 | 特级淫片大乳女子高清视频 | 俺去俺也在线www色官网 | 成人欧美一区二区三区 | 国产手机在线αⅴ片无码观看 | bl双性肉文| 日本不卡视频免费的 | 好大好粗好爽 | 欧美视频黑鬼大战白妞 | 色v在线 | 小夫妻天天恶战 | 成人免费淫片95视频观看网站 | 男人添女人 | 精品国语对白精品自拍视 | 视频免费观看在线播放高清 | 4444www免费看 |