什么是簡(jiǎn)單工廠、工廠方法、抽象工廠?相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。
為香格里拉等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及香格里拉網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站制作、做網(wǎng)站、香格里拉網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專(zhuān)業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
簡(jiǎn)單工廠模式
基本上每個(gè)人手機(jī)里都有一款音樂(lè)播放器,目前流行的播放器有:QQ音樂(lè)、酷狗音樂(lè)、酷狗音樂(lè)、網(wǎng)易云音樂(lè)、天天動(dòng)聽(tīng)等。下面是一段關(guān)于播放音樂(lè)的代碼:
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(); // 打開(kāi)播放器 $player->choiceMusic('我不配'); // 選擇歌曲 $player->play(); // 開(kāi)始播放
為了時(shí)代碼的邏輯更加清晰、可讀性更好,我們要善于把功能獨(dú)立的代碼塊封裝成函數(shù)。按照這個(gè)設(shè)計(jì)思路,我們可以將其中的條件分支抽離出來(lái),單獨(dú)放在一個(gè)類(lèi)中的方法中。這個(gè)類(lèi),我們就可以叫做簡(jiǎn)單工廠模式。
簡(jiǎn)單工廠模式的定義:一個(gè)類(lèi)可以根據(jù)不同的參數(shù)來(lái)獲取不同的實(shí)例,一般這些被創(chuàng)建的實(shí)例都具有相同的父類(lèi)。
靜態(tài)工廠模式:一般的,我們將簡(jiǎn)單工廠模式中的用于創(chuàng)建不同實(shí)例的方法設(shè)置為靜態(tài)方法,避免創(chuàng)建多個(gè)相同實(shí)例。
下面我們用簡(jiǎn)單工廠模式改寫(xiě)上面的代碼
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(); // 打開(kāi)播放器 $player->choiceMusic('我不配'); // 選擇歌曲 $player->play(); // 開(kāi)始播放
對(duì)于上面的簡(jiǎn)單工廠模式,如果我們需要添加新的音樂(lè)播放器,就一定會(huì)修改MusicPlayerFactory的create方法,這有點(diǎn)不符合“開(kāi)閉原則”。對(duì)于這種條件分支不是很多,另外類(lèi)的創(chuàng)建也非常的簡(jiǎn)單,使用簡(jiǎn)單工廠模式是完全可以的。如果非要將if分支邏輯去掉,使他符合“開(kāi)閉原則”,那么就可以使用工廠方法來(lái)實(shí)現(xiàn)。對(duì)于工廠方法,也不是一定比簡(jiǎn)單工廠模式要好,雖然它的擴(kuò)展性比較好,但是犧牲了可讀性。
工廠方法模式
定義:在工廠方法模式中,工廠父類(lèi)負(fù)責(zé)定義創(chuàng)建產(chǎn)品對(duì)象的公共接口,而工廠子類(lèi)則負(fù)責(zé)生成具體的產(chǎn)品對(duì)象,這樣做的目的是將產(chǎn)品類(lèi)的實(shí)例化操作延遲到工廠子類(lèi)中完成,即通過(guò)工廠子類(lèi)來(lái)確定究竟應(yīng)該實(shí)例化哪一個(gè)具體產(chǎn)品類(lèi)。
現(xiàn)在我們用“多態(tài)”來(lái)消除掉上面簡(jiǎn)單工廠模式的if分支結(jié)構(gòu)。實(shí)現(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(); // 打開(kāi)播放器 $player->choiceMusic('我不配'); // 選擇歌曲 $player->play(); // 開(kāi)始播放
可以看到,問(wèn)題又回到了原點(diǎn),業(yè)務(wù)代碼里又出現(xiàn)了if條件分支結(jié)構(gòu)。那么怎么去解決該問(wèn)題呢?
我們可以為工廠類(lèi)再創(chuàng)建一個(gè)簡(jiǎn)單工廠,用來(lái)創(chuàng)建工廠類(lèi)對(duì)象。新的簡(jiǎn)單工廠代碼如下:
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(); // 打開(kāi)播放器 $player->choiceMusic('我不配'); // 選擇歌曲 $player->play(); // 開(kāi)始播放
可以看到,使用了工廠模式,結(jié)構(gòu)變的比之前復(fù)雜的多。如果來(lái)的創(chuàng)建實(shí)例過(guò)程復(fù)制,我們才會(huì)推薦使用工廠方法模式。
抽象工廠模式
抽象工廠模式使用場(chǎng)景比較特殊,用的比較少。在工廠方法模式中,具體工廠負(fù)責(zé)生產(chǎn)具體的產(chǎn)品,每一個(gè)工廠對(duì)應(yīng)一個(gè)具體產(chǎn)品。但有時(shí)候,我們需要一個(gè)工廠可以創(chuàng)建多個(gè)產(chǎn)品對(duì)象,而不是一個(gè)單一的產(chǎn)品。
我們用一個(gè)例子來(lái)看看:對(duì)象電腦廠是負(fù)責(zé)生產(chǎn)電腦來(lái)出售的。我們知道,電腦是由主機(jī)、鍵盤(pán)、顯示器以及鼠標(biāo)組成的,目前對(duì)象電腦城只生產(chǎn)3種電腦,低配、中配和高配的,不同配置的電腦使用的主機(jī)品牌、顯示器品牌等都是不同的。
主機(jī)目前有:麒麟主機(jī)、雷霆主機(jī)、冬日主機(jī)
鍵盤(pán)目前有:雷柏、羅技、雷蛇
顯示器目前有:aoc、hkc、BenQ
鼠標(biāo)目前有:羅技、靈蛇、方正
頂配版電腦由麒麟主機(jī)、雷柏鍵盤(pán)、aoc顯示器、羅技鼠標(biāo)組成,中配由……。
關(guān)于主機(jī)的代碼如下:
interface Host { static function createHost (); } class DrHost implements Host { public static function createHost() { echo '創(chuàng)建冬日主機(jī)' . PHP_EOL; } } class QlHost implements Host { public static function createHost() { echo '創(chuàng)建麒麟主機(jī)' . PHP_EOL; } } class LtHost implements Host { public static function createHost() { echo '創(chuàng)建雷霆主機(jī)' . PHP_EOL; } }
類(lèi)似的,去創(chuàng)建鍵盤(pán)、顯示器、鼠標(biāo),代碼這里就不貼了。
現(xiàn)在,我們定義一個(gè)創(chuàng)建電腦的接口。
interface ComputerFactory { static function createHost (); static function createKeyboard (); static function createMonitor (); static function createMouse (); }
然后完成三個(gè)具體工廠用于創(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)在可以來(lái)創(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(); } }
看完上述內(nèi)容,你們掌握什么是簡(jiǎn)單工廠、工廠方法、抽象工廠的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!