PHP設(shè)計(jì)模式中工廠模式深入詳解
簡(jiǎn)介
工廠模式屬于創(chuàng)建型模式,可以分為三種:簡(jiǎn)單工廠、工廠模式、抽象工廠。
通俗講就是用于如何優(yōu)雅的創(chuàng)建對(duì)象而設(shè)計(jì)。當(dāng)開(kāi)發(fā)者不知道建什么對(duì)象,或者創(chuàng)建方式過(guò)于復(fù)雜的時(shí)候去使用(比如引入一個(gè)大composer項(xiàng)目或大型sdk,有些時(shí)候確實(shí)不知道需要使用那些對(duì)象,此時(shí)就需要參考官方文檔,通過(guò)包里或sdk里提供的工廠方法,傳入指定參數(shù)去生成指定對(duì)象。比如easyWechat項(xiàng)目。),適用于具有服務(wù)端和調(diào)用端的場(chǎng)景,既能優(yōu)化調(diào)用端的使用體感,也能隱藏服務(wù)端創(chuàng)建對(duì)象的細(xì)節(jié)。
簡(jiǎn)單工廠
作用
幫忙創(chuàng)建對(duì)象(核心方法可以使用靜態(tài)方法,稱之為靜態(tài)工廠)。
適用場(chǎng)景
- 當(dāng)不知道創(chuàng)建什么對(duì)象的時(shí)候去使用
- 創(chuàng)建對(duì)象過(guò)于復(fù)雜的時(shí)候去使用。
優(yōu)點(diǎn)
簡(jiǎn)單工廠是工廠模式中創(chuàng)建對(duì)象最簡(jiǎn)單的方式,通俗容易理解。
缺點(diǎn)
當(dāng)要生產(chǎn)對(duì)象的模塊發(fā)生了需求變更,此時(shí)要被實(shí)例化的類(lèi)可能會(huì)增加或者減少,此時(shí)就需要改工廠模式的核心代碼,違背了開(kāi)閉原則。
代碼
class Keyboard{
public function run() {
return '我能打字';
}
}
class Mouse {
public function run() {
return '我能控制光標(biāo)';
}
}
class Factory {
public static function build($key) {
if($key == 'mouse') {
return new Mouse();
} else if ($key == 'keyboard') {
return new Keyboard();
}
}
}
//----------調(diào)用端----------
$res = Factory::build('mouse')->run();
/*
筆者認(rèn)為,簡(jiǎn)單工廠可以簡(jiǎn)化為以下寫(xiě)法
但是這會(huì)有三個(gè)缺陷:
1. 能否做到類(lèi)名寫(xiě)法一致?不一定能做到
2. 缺少白名單機(jī)制,不安全,指不定new那個(gè)類(lèi),特別是這個(gè)參數(shù)守用戶傳參影響的場(chǎng)景,不過(guò)這個(gè)可以讓需要實(shí)例化的類(lèi)實(shí)現(xiàn)一個(gè)接口,工廠方法添加typehint (類(lèi)型約束)限制。
3. 如果修改白名單,又違背了開(kāi)閉原則。
*/
class Factory {
public static function build($class) {
return ucfirst($class);
}
}工廠模式
作用
解決了簡(jiǎn)單工廠模式中違背開(kāi)閉原則的問(wèn)題。
適用場(chǎng)景
- 并解決了簡(jiǎn)單工廠模式下,一旦類(lèi)發(fā)生變化,就需要修改核心模塊的作用,遵循開(kāi)閉原則。
- 產(chǎn)品層變化較大的的場(chǎng)景
優(yōu)點(diǎn)
- 將創(chuàng)建對(duì)象的過(guò)程推遲的子類(lèi)去實(shí)現(xiàn),職責(zé)清晰,比較符合開(kāi)閉原則。
- 并解決了簡(jiǎn)單工廠模式下,一旦類(lèi)發(fā)生變化,就需要修改核心模塊的作。
缺點(diǎn)
額外增加設(shè)計(jì)復(fù)雜度,每增加一個(gè)類(lèi),就需要增加一個(gè)子工廠。增加了系統(tǒng)抽象性。
代碼
interface Usb {
public function run();
}
class Keyboard implements USb {
public function run() {
return '我能打字';
}
}
class Mouse implements USb {
public function run() {
return '我能控制光標(biāo)';
}
}
interFace Factory {
public static function build();
}
class KeyboardFactory implements Factory {
public static function build() :Keyboard {
return new Keyboard();
}
}
class MouseFactory implements Factory {
public static function build() :Mouse {
return new Mouse();
}
}
//----------調(diào)用端----------
$res = MouseFactory::build()->run();抽象工廠
作用
- 抽象工廠相比于工廠模式,可以創(chuàng)建一堆互有關(guān)聯(lián)對(duì)象。
- 抽象工廠的實(shí)現(xiàn)由4部分構(gòu)成:抽象工廠,具體工廠,抽象產(chǎn)品,具體產(chǎn)品。
適用場(chǎng)景
對(duì)象創(chuàng)建過(guò)程復(fù)雜,并且類(lèi)與類(lèi)之間有關(guān)聯(lián)的時(shí)候。
優(yōu)點(diǎn)
抽象工廠可以用一個(gè)類(lèi)的不同方法返回不同對(duì)象,(工廠模式一個(gè)子類(lèi)生產(chǎn)一個(gè)對(duì)象,抽象工廠可以生產(chǎn)出多個(gè)對(duì)象),替代系統(tǒng)中存在大量的工廠類(lèi)。
缺點(diǎn)
會(huì)產(chǎn)生較大的變動(dòng),需要添加指定的方法去維護(hù)抽象工廠的完整性。
代碼
interface Talk {
public function say();
}
class EnglishTalk implements Talk {
public function say() {
return 'I can speak English';
}
}
class ChineseTalk implements Talk {
public function say() {
return '我會(huì)說(shuō)中文';
}
}
interface Write {
public function writeWord();
}
class EnglishWrite implements Write {
public function writeWord() {
return 'I can write English words';
}
}
class ChineseWrite implements Write {
public function writeWord() {
return '我會(huì)寫(xiě)漢字';
}
}
interface Factory {
public static function buildSay();
public static function buildWriteWord();
}
class EnglishFactory implements Factory {
public static function buildSay() :EnglishTalk {
return new EnglishTalk();
}
public static function buildWriteWord() :EnglishWrite {
return new EnglishWrite();
}
}
class ChineseFactory implements Factory {
public static function buildSay() :ChineseTalk {
return new ChineseTalk();
}
public static function buildWriteWord():ChineseWrite {
return new ChineseWrite();
}
}
//----------調(diào)用端----------
//中國(guó)人對(duì)應(yīng)會(huì)說(shuō)漢語(yǔ),或?qū)憹h字,這就是有關(guān)聯(lián),
$chinese_say = ChineseFactory::buildSay()->say();
$chinese_write_word = ChineseFactory::buildWriteWord()->writeWord();
三者對(duì)比
| 簡(jiǎn)單工廠 | 工廠模式 | 抽象工廠 | |
|---|---|---|---|
| 實(shí)現(xiàn)難度 | 相對(duì)簡(jiǎn)單 | 相對(duì)復(fù)雜 | 相對(duì)復(fù)雜 |
| 實(shí)現(xiàn)細(xì)節(jié) | 通過(guò)方法生產(chǎn)對(duì)象(不需要子類(lèi)) | 通過(guò)子類(lèi)方法去生產(chǎn)對(duì)象 | 通過(guò)子類(lèi)方法去生產(chǎn)有關(guān)聯(lián)的對(duì)象 |
| 優(yōu)點(diǎn) | 實(shí)現(xiàn)簡(jiǎn)單 | 解決了簡(jiǎn)單工廠違背開(kāi)閉原則的問(wèn)題 | 可以制造一堆有關(guān)聯(lián)的對(duì)象,減少工廠模式下工廠子類(lèi)的數(shù)量 |
| 缺點(diǎn) | 違背開(kāi)閉原則,不適用修改產(chǎn)品 | 更加抽象,類(lèi)數(shù)量增加,不方便維護(hù) | 更加抽象,類(lèi)數(shù)量增加,不方便維護(hù) |
| 適用場(chǎng)景 | 簡(jiǎn)單場(chǎng)景,類(lèi)之間無(wú)關(guān)聯(lián)且不經(jīng)常變動(dòng) | 需要實(shí)例化的產(chǎn)品容易有變動(dòng) | 類(lèi)之間有關(guān)聯(lián),且不經(jīng)常變動(dòng) |
到此這篇關(guān)于PHP設(shè)計(jì)模式中工廠模式深入詳解的文章就介紹到這了,更多相關(guān)PHP工廠模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PHP的explode和implode的使用說(shuō)明
下里說(shuō)道php中的explode 和implode的用法,芭蕾舞鞋,盼望對(duì)于友朋們有所輔助!2011-07-07
php+mysqli使用面向?qū)ο蠓绞讲樵償?shù)據(jù)庫(kù)實(shí)例
這篇文章主要介紹了php+mysqli使用面向?qū)ο蠓绞讲樵償?shù)據(jù)庫(kù)的方法,實(shí)例分析了mysqli對(duì)象的創(chuàng)建、連接、查詢及返回結(jié)果、釋放資源等技巧,需要的朋友可以參考下2015-01-01
php生成的html meta和link標(biāo)記在body標(biāo)簽里 頂部有個(gè)空行
php生成的html meta和link標(biāo)記在body標(biāo)簽里 瀏覽器頂部有個(gè)空行的解決方法。2010-05-05
php命名空間設(shè)計(jì)思想、用法與缺點(diǎn)分析
這篇文章主要介紹了php命名空間設(shè)計(jì)思想、用法與缺點(diǎn),結(jié)合實(shí)例形式分析了php命名空間的概念、用法及相關(guān)的操作注意事項(xiàng),并給出了使用建議,需要的朋友可以參考下2019-07-07
php實(shí)現(xiàn)獲取文章內(nèi)容第一張圖片的方法
這篇文章主要介紹了php實(shí)現(xiàn)獲取文章內(nèi)容第一張圖片的方法,涉及對(duì)正則表達(dá)式的操作,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-11-11

