PHP設(shè)計(jì)模式之工廠模式實(shí)例總結(jié)
本文實(shí)例講述了PHP設(shè)計(jì)模式之工廠模式。分享給大家供大家參考,具體如下:
使用工廠模式的目的或目標(biāo)?
工廠模式的最大優(yōu)點(diǎn)在于創(chuàng)建對(duì)象上面,就是把創(chuàng)建對(duì)象的過(guò)程封裝起來(lái),這樣隨時(shí)可以產(chǎn)生一個(gè)新的對(duì)象。
減少代碼進(jìn)行復(fù)制粘帖,耦合關(guān)系重,牽一發(fā)動(dòng)其他部分代碼。
通俗的說(shuō),以前創(chuàng)建一個(gè)對(duì)象要使用new,現(xiàn)在把這個(gè)過(guò)程封裝起來(lái)了。
假設(shè)不使用工廠模式:那么很多地方調(diào)用類a,代碼就會(huì)這樣子創(chuàng)建一個(gè)實(shí)例:new a(),假設(shè)某天需要把a(bǔ)類的名稱修改,意味著很多調(diào)用的代碼都要修改。
工廠模式的優(yōu)點(diǎn)就在創(chuàng)建對(duì)象上。
工廠模式的優(yōu)點(diǎn)就在創(chuàng)建對(duì)象上。建立一個(gè)工廠(一個(gè)函數(shù)或一個(gè)類方法)來(lái)制造新的對(duì)象,它的任務(wù)就是把對(duì)象的創(chuàng)建過(guò)程都封裝起來(lái),
創(chuàng)建對(duì)象不是使用new的形式了。而是定義一個(gè)方法,用于創(chuàng)建對(duì)象實(shí)例。
每個(gè)類可能會(huì)需要連接數(shù)據(jù)庫(kù)。那么就將連接數(shù)據(jù)庫(kù)封裝在一個(gè)類中。以后在其他類中通過(guò)類名:
為什么引入抽象的概念?
想一想,在現(xiàn)實(shí)生活中,當(dāng)我們無(wú)法確定某個(gè)具體的東西的時(shí)候,往往把一類東西歸于抽象類別。
工廠方法:
比如你的工廠叫做“香煙工廠”,那么可以有“七匹狼工廠”“中華工廠”等,但是,這個(gè)工廠只生廠一種商品:香煙;
抽象工廠:無(wú)法描述它到底生產(chǎn)什么產(chǎn)品,它生產(chǎn)很多類型的產(chǎn)品(所以抽象工廠就會(huì)生成子工廠)。
你的工廠是綜合型的,是生產(chǎn)“一系列”產(chǎn)品,而不是“一個(gè)”,比如:生產(chǎn)“香煙”,還有“啤酒”等。然后它也可以有派生出來(lái)的具體的工廠,但這些工廠都是生產(chǎn)這一系列產(chǎn)品,只是可能因?yàn)榈赜虿灰粯樱瑸榱诉m應(yīng)當(dāng)?shù)厝丝谖?,味道也不太一樣?/p>
工廠模式:理解成只生成一種產(chǎn)品的工廠。比如生產(chǎn)香煙的。
工廠方法:工廠的一種產(chǎn)品生產(chǎn)線 。比如鍵盤的生成過(guò)程。
別人會(huì)反駁:吃飽了沒(méi)事干,一定要修改類名稱呢?這個(gè)說(shuō)不定。一般都不會(huì)去修改類名稱。
其實(shí)工廠模式有很多變體,抓住精髓才是關(guān)鍵:只要是可以根據(jù)不同的參數(shù)生成不同的類實(shí)例,那么就符合工廠模式的設(shè)計(jì)思想。
這樣子讓我聯(lián)想到框架中經(jīng)常會(huì)有負(fù)責(zé)生成具體類實(shí)例的方法供調(diào)用。
由于前面使用過(guò)phpcms,用phpcms的來(lái)幫助理解,更加好,如下:
pc_base:load_app_class("order"');//參數(shù)名稱就是類名稱。
將會(huì)生成得到order這個(gè)實(shí)例。傳遞不同的參數(shù)得到不同的類實(shí)例,這個(gè)就符合工廠模式。
pc_base:load_app_class("comment"');//生成一個(gè)comment類實(shí)例
當(dāng)然load_app_class這個(gè)方法里面還會(huì)結(jié)合了單件模式的思想。避免調(diào)用n次,就重復(fù)創(chuàng)建n個(gè)相同的實(shí)例
工廠模式我想到的一個(gè)典型的應(yīng)用就是:php可能要鏈接mysql,也可能要鏈接sqlserver,還有其他什么數(shù)據(jù)庫(kù)。那么做一個(gè)抽象的數(shù)據(jù)庫(kù)類,
這個(gè)類就是一個(gè)工廠類,專門負(fù)責(zé)產(chǎn)生不同的對(duì)象。
這樣子做很方便擴(kuò)展。我們?cè)谥苯渔溄訑?shù)據(jù)庫(kù)的時(shí)候,不是使用代碼
new Mysql($host,$username,$password,$dbname)
的形式
而可以動(dòng)態(tài)生成一個(gè)連接數(shù)據(jù)庫(kù)的實(shí)例??梢允莔ysql,也可以是連接oracle的。
class DbFactory
{
function static factory($db_class_name)
{
$db_class_name = strtolower($db_class_name);
if (include_once 'Drivers/' . $db_class_name . '.php') {
$classname = 'Driver_' . $db_class_name;
return new $db_class_name;
} else {
throw new Exception ('對(duì)應(yīng)的數(shù)據(jù)庫(kù)類沒(méi)找到');
}
}
}
DbFactory::factory("mysql");
DbFactory::factory("oracle");
在thinkphp框架中也有對(duì)應(yīng)的實(shí)現(xiàn):
Db.class.php就是一個(gè)工廠類(也可以叫做數(shù)據(jù)庫(kù)中間層,之所以叫做中間層,是因?yàn)榭梢圆僮鱩ysql、oracle等各數(shù)據(jù)庫(kù)。而這個(gè)類就是中間層作用,屏蔽掉具體的實(shí)現(xiàn)。讓程序員可以不改動(dòng)原來(lái)的查詢代碼。中間層來(lái)對(duì)接mysql、oracle等數(shù)據(jù)庫(kù)。
Db.class.php中有個(gè)factory()方法來(lái)創(chuàng)建不同的數(shù)據(jù)庫(kù)實(shí)例
public function factory($db_config='') {
// 讀取數(shù)據(jù)庫(kù)配置
$db_config = $this->parseConfig($db_config);
if(empty($db_config['dbms']))
throw_exception(L('_NO_DB_CONFIG_'));
// 數(shù)據(jù)庫(kù)類型
$this->dbType = ucwords(strtolower($db_config['dbms']));
$class = 'Db'. $this->dbType;
if(is_file(CORE_PATH.'Driver/Db/'.$class.'.class.php')) {
// 內(nèi)置驅(qū)動(dòng)
$path = CORE_PATH;
}else{ // 擴(kuò)展驅(qū)動(dòng)
$path = EXTEND_PATH;
}
// 檢查驅(qū)動(dòng)類
if(require_cache($path.'Driver/Db/'.$class.'.class.php')) {
$db = new $class($db_config);
// 獲取當(dāng)前的數(shù)據(jù)庫(kù)類型
if( 'pdo' != strtolower($db_config['dbms']) )
$db->dbType = strtoupper($this->dbType);
else
$db->dbType = $this->_getDsnType($db_config['dsn']);
if(APP_DEBUG) $db->debug = true;
}else {
// 類沒(méi)有定義
throw_exception(L('_NOT_SUPPORT_DB_').': ' . $db_config['dbms']);
}
return $db;
}
還有做支付接口的時(shí)候,未來(lái)可能對(duì)應(yīng)不同的支付網(wǎng)關(guān):支付寶、財(cái)付通、網(wǎng)銀在線等。方便未來(lái)擴(kuò)展,設(shè)計(jì)成工廠模式。定一個(gè)專門生產(chǎn)網(wǎng)關(guān)接口的工廠,抽象出來(lái),做成接口形式,讓所有的子類都要實(shí)現(xiàn)它的接口。以后加一個(gè)支付方式,要使用哪一種支付方式,改變一下參數(shù)即可。
書籍<php權(quán)威編程>(英文名稱為PHP 5 Power Programming)也提到一個(gè)工廠模式的例子,學(xué)到一招:在為用戶注冊(cè)的時(shí)候,分為很多種角色的用戶。比如冊(cè)用戶,匿名用戶、管理員用戶等。完全使用可以使用工廠的思想來(lái)實(shí)現(xiàn),代碼也容易維護(hù),為每種角色可以生成操作的類。
定義以下幾個(gè)類:
UserFactory 用戶工廠類,負(fù)責(zé)生成不同的用戶類
User:用戶類的基類,所有用戶類都是繼承這個(gè)類
不同角色的類:注冊(cè)用戶類、匿名用戶類、管理員用戶類
總結(jié)結(jié)束,歡迎指正!
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門教程》、《PHP基本語(yǔ)法入門教程》、《PHP數(shù)組(Array)操作技巧大全》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫(kù)操作入門教程》及《php常見(jiàn)數(shù)據(jù)庫(kù)操作技巧匯總》
希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。
相關(guān)文章
詳解PHP中數(shù)組函數(shù)的知識(shí)點(diǎn)
PHP 的數(shù)組是一種很強(qiáng)大的數(shù)據(jù)類型,與此同時(shí) PHP 內(nèi)置了一系列與數(shù)組相關(guān)的函數(shù)可以很輕易的實(shí)現(xiàn)日常開發(fā)的功能。所以本文便總結(jié)了一些在常見(jiàn)場(chǎng)景中利用 PHP 內(nèi)置函數(shù)的實(shí)現(xiàn)方法,希望對(duì)你有所幫助2022-11-11
PHP截取漢字亂碼問(wèn)題解決方法mb_substr函數(shù)的應(yīng)用
利用mb_substr截取字符串不會(huì)出現(xiàn)亂碼問(wèn)題,高手可以飛過(guò)......2008-03-03
php使用Jpgraph繪制復(fù)雜X-Y坐標(biāo)圖的方法
這篇文章主要介紹了php使用Jpgraph繪制復(fù)雜X-Y坐標(biāo)圖的方法,通過(guò)設(shè)置圖像陰影、邊距、字體、顏色、曲線等實(shí)現(xiàn)Jpgraph繪制復(fù)雜坐標(biāo)圖的功能,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-06-06
php實(shí)現(xiàn)將任意進(jìn)制數(shù)轉(zhuǎn)換成10進(jìn)制的方法
這篇文章主要介紹了php實(shí)現(xiàn)將任意進(jìn)制數(shù)轉(zhuǎn)換成10進(jìn)制的方法,涉及php數(shù)制轉(zhuǎn)換的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
php獲取今日開始時(shí)間和結(jié)束時(shí)間的方法
本篇文章實(shí)例講述了php獲取今日開始時(shí)間和結(jié)束時(shí)間的方法,具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-02-02

