簡單工廠模式
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:域名與空間、網(wǎng)站空間、營銷軟件、網(wǎng)站建設(shè)、新都網(wǎng)站維護、網(wǎng)站推廣。基本上每個人手機里都有一款音樂播放器,目前流行的播放器有:QQ音樂、酷狗音樂、酷狗音樂、網(wǎng)易云音樂、天天動聽等。下面是一段關(guān)于播放音樂的代碼:
if ($type == 'QQ') { $player = new QQPlayer(); } else if ($type == 'Wy') { $player = new WyPlayer(); } else if ($type == 'KG') { $player = new KGPlayer(); } else { $palyer = null; } $player->on(); // 打開播放器 $player->choiceMusic('我不配'); // 選擇歌曲 $player->play(); // 開始播放
為了時代碼的邏輯更加清晰、可讀性更好,我們要善于把功能獨立的代碼塊封裝成函數(shù)。按照這個設(shè)計思路,我們可以將其中的條件分支抽離出來,單獨放在一個類中的方法中。這個類,我們就可以叫做簡單工廠模式。
簡單工廠模式的定義:一個類可以根據(jù)不同的參數(shù)來獲取不同的實例,一般這些被創(chuàng)建的實例都具有相同的父類。
靜態(tài)工廠模式:一般的,我們將簡單工廠模式中的用于創(chuàng)建不同實例的方法設(shè)置為靜態(tài)方法,避免創(chuàng)建多個相同實例。
下面我們用簡單工廠模式改寫上面的代碼
class MusicPlayerFactory { public static function create ($type) { if ($type == 'QQ') { $player = new QQPlayer(); } else if ($type == 'Wy') { $player = new WyPlayer(); } else if ($type == 'KG') { $player = new KGPlayer(); } else { $player = null; } return $player; } } // 業(yè)務(wù)代碼修改如下 $player = MusicPlayerFactory:create('QQ'); $player->on(); // 打開播放器 $player->choiceMusic('我不配'); // 選擇歌曲 $player->play(); // 開始播放
對于上面的簡單工廠模式,如果我們需要添加新的音樂播放器,就一定會修改MusicPlayerFactory的create方法,這有點不符合“開閉原則”。對于這種條件分支不是很多,另外類的創(chuàng)建也非常的簡單,使用簡單工廠模式是完全可以的。如果非要將if分支邏輯去掉,使他符合“開閉原則”,那么就可以使用工廠方法來實現(xiàn)。對于工廠方法,也不是一定比簡單工廠模式要好,雖然它的擴展性比較好,但是犧牲了可讀性。
工廠方法模式
定義:在工廠方法模式中,工廠父類負責(zé)定義創(chuàng)建產(chǎn)品對象的公共接口,而工廠子類則負責(zé)生成具體的產(chǎn)品對象,這樣做的目的是將產(chǎn)品類的實例化操作延遲到工廠子類中完成,即通過工廠子類來確定究竟應(yīng)該實例化哪一個具體產(chǎn)品類。
現(xiàn)在我們用“多態(tài)”來消除掉上面簡單工廠模式的if分支結(jié)構(gòu)。實現(xiàn)的代碼如下所示:
interface IMusicPlayerFactory { static function create (); } class QQPlayerFactory implements IMusicPlayerFactory { public static function create () { return new QQPlayer(); } } class WyPlayerFactory implements IMusicPlayerFactory { public static function create () { return new WyPlayer(); } } class KGPlayerFactory implements IMusicPlayerFactory { public static function create () { return new KGPlayer(); } } // 業(yè)務(wù)代碼修改如下 if ($type == 'QQ') { $player = QQPlayerFactory::create(); } else if ($type == 'Wy') { $player = WyPlayerFactory::create(); } else if ($type == 'KG') { $player = KGPlayerFactory::create(); } else { throw new \\Exception('...'); } $player->on(); // 打開播放器 $player->choiceMusic('我不配'); // 選擇歌曲 $player->play(); // 開始播放
可以看到,問題又回到了原點,業(yè)務(wù)代碼里又出現(xiàn)了if條件分支結(jié)構(gòu)。那么怎么去解決該問題呢?
我們可以為工廠類再創(chuàng)建一個簡單工廠,用來創(chuàng)建工廠類對象。新的簡單工廠代碼如下:
class MusicPlayerFactoryMap { const Players = [ 'QQ' => 'QQPlayerFactory', 'Wy' => 'WyPlayerFactory', 'KG' => 'KGPlayerFactory' ]; public static function getPlayerFactory (string $type) { if (empty($type)) { return null; } return (self::Players[$type])::create(); } } // 業(yè)務(wù)代碼修改如下 $palyer = MusicPlayerFactoryMap::getPlayerFactory('QQ') $player->on(); // 打開播放器 $player->choiceMusic('我不配'); // 選擇歌曲 $player->play(); // 開始播放
可以看到,使用了工廠模式,結(jié)構(gòu)變的比之前復(fù)雜的多。如果來的創(chuàng)建實例過程復(fù)制,我們才會推薦使用工廠方法模式。
抽象工廠模式
抽象工廠模式使用場景比較特殊,用的比較少。在工廠方法模式中,具體工廠負責(zé)生產(chǎn)具體的產(chǎn)品,每一個工廠對應(yīng)一個具體產(chǎn)品。但有時候,我們需要一個工廠可以創(chuàng)建多個產(chǎn)品對象,而不是一個單一的產(chǎn)品。
我們用一個例子來看看:對象電腦廠是負責(zé)生產(chǎn)電腦來出售的。我們知道,電腦是由主機、鍵盤、顯示器以及鼠標(biāo)組成的,目前對象電腦城只生產(chǎn)3種電腦,低配、中配和高配的,不同配置的電腦使用的主機品牌、顯示器品牌等都是不同的。
主機目前有:麒麟主機、雷霆主機、冬日主機
鍵盤目前有:雷柏、羅技、雷蛇
顯示器目前有:aoc、hkc、BenQ
鼠標(biāo)目前有:羅技、靈蛇、方正
頂配版電腦由麒麟主機、雷柏鍵盤、aoc顯示器、羅技鼠標(biāo)組成,中配由……。
關(guān)于主機的代碼如下:
interface Host { static function createHost (); } class DrHost implements Host { public static function createHost() { echo '創(chuàng)建冬日主機' . PHP_EOL; } } class QlHost implements Host { public static function createHost() { echo '創(chuàng)建麒麟主機' . PHP_EOL; } } class LtHost implements Host { public static function createHost() { echo '創(chuàng)建雷霆主機' . PHP_EOL; } }
類似的,去創(chuàng)建鍵盤、顯示器、鼠標(biāo),代碼這里就不貼了。
現(xiàn)在,我們定義一個創(chuàng)建電腦的接口。
interface ComputerFactory { static function createHost (); static function createKeyboard (); static function createMonitor (); static function createMouse (); }
然后完成三個具體工廠用于創(chuàng)建低配、中配以及高配版電腦。
class GreatComputerFactory implements ComputerFactory { public static function createHost() { QlHost::createHost(); } public static function createKeyboard() { LbKeyboard::createKeyboard(); } public static function createMonitor() { AocMonitor::createMonitor(); } public static function createMouse() { LjMouse::createMouse(); } } class GoodComputerFactory implements ComputerFactory { public static function createHost() { LtHost::createHost(); } public static function createKeyboard() { LjKeyboard::createKeyboard(); } public static function createMonitor() { HkcMonitor::createMonitor(); } public static function createMouse() { LsMouse::createMouse(); } } class NormalComputerFactory implements ComputerFactory { public static function createHost() { DrHost::createHost(); } public static function createKeyboard() { LsKeyboard::createKeyboard(); } public static function createMonitor() { BenqMonitor::createMonitor(); } public static function createMouse() { FzMouse::createMouse(); } }
現(xiàn)在可以來創(chuàng)建具體的電腦了
class GreatComputer { public function __construct() { echo '高配電腦' . PHP_EOL; GreatComputerFactory::createHost(); GreatComputerFactory::createKeyboard(); GreatComputerFactory::createMonitor(); GreatComputerFactory::createMouse(); } } class GoodComputer { public function __construct() { echo '中配電腦' . PHP_EOL; GoodComputerFactory::createHost(); GoodComputerFactory::createKeyboard(); GoodComputerFactory::createMonitor(); GoodComputerFactory::createMouse(); } } class NormalComputer { public function __construct() { echo '低配電腦' . PHP_EOL; NormalComputerFactory::createHost(); NormalComputerFactory::createKeyboard(); NormalComputerFactory::createMonitor(); NormalComputerFactory::createMouse(); } }
本文名稱:一文讀懂簡單工廠、工廠方法、抽象工廠
標(biāo)題網(wǎng)址:http://www.rwnh.cn/article18/cgchdp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計、網(wǎng)站內(nèi)鏈、域名注冊、定制網(wǎng)站、建站公司、移動網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)