设计模式之工厂模式
为什么要工厂模式
- 有些类很常用,我们会在很多地方进行实例化。假如有一天这个类名突然有天要修改,是不是惆怅?
- 我想根据参数条件来调用对应的对象。有点像
switch
干的活。这样就简化了逻辑,统一控制,代码也比较简化。
一、简单工厂
namespace DesignPatterns\SimpleFactory; /** * 短信发送组件 * @author jack */ abstract class Message { abstract public function send($mobile,$message); } Class Alidayu extends Message { public function send($mobile,$message){} } Class SMS56 extends Message { public function send($mobile,$message){} }
简单工厂封装
namespace DesignPatterns\SimpleFactory; /** * @author Jack */ class MessageFactory { protected $msgType = [ 'alidayu' => '***', '56' => 'SMS' ]; /** * 生成对象 * @param string $name * @throws \Exception * @return Object */ public function createMessage( $name ) { if (! array_key_exists($name, $this->msgType)) { throw new \Exception("$name not exist"); } return new $this->msgType[$name]; } }
客户端使用
$mf = new MessageFactory(); $message = $mf->createMessage('56'); var_dump($message);
如果你想增加一个新的短信组件,比如它叫 onesmser
,我们只需要先继承我们的 Message 类,然后在工厂类中加上,只需要在我们的 msgType
中添加就可以了
二、静态工厂方法模式
静态工厂和之前的简单工厂有些类似,两者的区别在于 静态工厂中有一个静态方法用来实例化它所能实例化的所有对象
产品类:
namespace DesignPatterns\SimpleFactory; /** * 抽象产品,定义具体产品继承的父类或者实现的接口 * @author jack */ abstract class Message { abstract public function send($mobile,$message); } /** * 具体产品 */ Class Alidayu extends Message { public function send($mobile,$message){} } Class SMS56 extends Message { public function send($mobile,$message){} }
工厂类
namespace DesignPatterns\SimpleFactory; /** * 工厂类 */ class Factory { static function createMessage($type) { switch ($type) { case 'alidayu': return new Alidayu(); break; case '56': return new SMS56(); break; } } }
客户端代码:
namespace DesignPatterns\SimpleFactory; class Test { private $msg; function getMessage($type) { $this->msg = Factory::createMessage($type); } }