为什么要工厂模式
- 有些类很常用,我们会在很多地方进行实例化。假如有一天这个类名突然有天要修改,是不是惆怅?
- 我想根据参数条件来调用对应的对象。有点像
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' => 'Alidayu',
'56' => 'SMS56'
];
/**
* 生成对象
* @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);
}
}