一文读懂简略工厂、工厂办法、抽象工厂
简便工厂模式
根本上每个人手机里都有一款音乐播放器,当前流行的播放器有:QQ音乐、酷狗音乐、搜狗音乐、网易云音乐、每天动听等。下面是一段关于播放音乐的代码:
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(); // 开端播放
为了时代码的逻辑愈加清楚、可读性更好,我们要擅长把功效独立的代码块封装成函数。依照这个设计思绪,我们可以将其中的前提分支抽离出来,独自放在一个类中的办法中。这个类,我们就可以叫做简便工厂模式。
简便工厂模式的定义:一个类可以按照不一样的参数来猎取不一样的实例,一样这些被创立的实例都具有雷同的父类。
静态工厂模式:一样的,我们将简便工厂模式中的用于创立不一样实例的办法设定为静态办法,幸免创立多个雷同实例。
下面我们用简便工厂模式改写上面的代码
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; } } // 业务代码修改如下 $player = MusicPlayerFactory:create('QQ'); $player->on(); // 翻开播放器 $player->choiceMusic('我不配'); // 选中歌曲 $player->play(); // 开端播放
关于上面的简便工厂模式,假如我们需要增加新的音乐播放器,就必然会修改MusicPlayerFactory的create办法,这有点不相符“开闭原则”。关于这种前提分支不是许多,别的类的创立也非常的简便,使用简便工厂模式是完全可以的。假如非要将if分支逻辑去除,使他相符“开闭原则”,那么就可以使用工厂办法来实现。关于工厂办法,也不是必然比简便工厂模式要好,虽然它的扩展性比力好,但是牺牲了可读性。
工厂办法模式
定义:在工厂办法模式中,工厂父类负责定义创立产品对象的公共接口,而工厂子类则负责生成详细的产品对象,这样做的目的是将产品类的实例化操纵延迟到工厂子类中完成,即通过工厂子类来肯定毕竟应当实例化哪一个详细产品类。
此刻我们用“多态”来消弭掉上面简便工厂模式的if分支构造。实现的代码如下所示:
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(); } } // 业务代码修改如下 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(); // 开端播放
可以看到,问题又回到了原点,业务代码里又显现了if前提分支构造。那么如何去解决该问题呢?
我们可认为工厂类再创立一个简便工厂,用来创立工厂类对象。新的简便工厂代码如下:
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(); } } // 业务代码修改如下 $palyer = MusicPlayerFactoryMap::getPlayerFactory('QQ') $player->on(); // 翻开播放器 $player->choiceMusic('我不配'); // 选中歌曲 $player->play(); // 开端播放
可以看到,使用了工厂模式,构造变的比此前复杂的多。假如来的创立实例历程复制,我们才会引荐使用工厂办法模式。
抽象工厂模式
抽象工厂模式使用处景比力非凡,用的比力少。在工厂办法模式中,详细工厂负责生产详细的产品,每一个工厂对应一个详细产品。但有时候,我们需要一个工厂可以创立多个产品对象,而不是一个简单的产品。
我们用一个例子来看看:对象电脑厂是负责生产电脑来出售的。我们知道,电脑是由主机、键盘、显示器乃至鼠标组成的,当前对象电脑城只生产3种电脑,低配、中配和高配的,不一样配置的电脑使用的主机品牌、显示器品牌等都是不一样的。
主机当前有:麒麟主机、雷霆主机、冬日主机
键盘当前有:雷柏、罗技、雷蛇
显示器当前有:aoc、hkc、BenQ
鼠标当前有:罗技、灵蛇、方正
顶配版电脑由麒麟主机、雷柏键盘、aoc显示器、罗技鼠标组成,中配由……。
关于主机的代码如下:
interface Host { static function createHost (); } class DrHost implements Host { public static function createHost() { echo '创立冬日主机' . PHP_EOL; } } class QlHost implements Host { public static function createHost() { echo '创立麒麟主机' . PHP_EOL; } } class LtHost implements Host { public static function createHost() { echo '创立雷霆主机' . PHP_EOL; } }
相似的,去创立键盘、显示器、鼠标,代码这里就不贴了。
此刻,我们定义一个创立电脑的接口。
interface ComputerFactory { static function createHost (); static function createKeyboard (); static function createMonitor (); static function createMouse (); }
然后完成三个详细工厂用于创立低配、中配乃至高配版电脑。
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(); } }
此刻可以来创立详细的电脑了
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(); } }
以上就是一文读懂简便工厂、工厂办法、抽象工厂的具体内容,更多请关注百分百源码网其它相关文章!