上篇文章,我们说过了单例模式,有童鞋会问:有单例,是不是有多例?答案:是的,这篇文章,我们来聊一下多例模式。
多例模式,就是一个类有多个实例,而且该实例都是该类本身。这样的类叫做多例类,具有以下:
- 多例类可以有多个实例。
- 多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。
简单啰嗦一句,跟普通我们 new 对象不一样,我们可以多次 new 对象,但是每次 new 的对象都是一个新的对象;而多例类里面所有的实例都是该类本身。
下面我们来看一下具体的代码实现:
逻辑:CD 工厂要不不同的内容授权给不同的工厂去生产:把 CD1 的内容让工厂 1 生产;CD2 的内容让工厂 2 生产。这样可以减少 CD 工厂的数量,增加 CD 工厂的扩展性。
class CDFactory
{
/**
* 实例对象数组
*
* @var array
*/
private static $_instances = [];
/**
* 构造函数私有,防止类可以通过 new 实例化
*
* @access private
* @return void
*/
private function __construct ()
{ }
/**
* 私有化复制克隆方法,防止类别复制和克隆
*
* @access private
* @return void
*/
private function __clone ()
{ }
/**
* 阻止实例被序列化
*
* @access private
* @return void
*/
private function __wakeup ()
{ }
/**
* 定义获取对象实例的入口,返回该实例
*
* @access public
* @param string $name 实例化名字
* @return self
*/
public static function getInstance (string $name)
{
// 判断是否已经存在实例化对象
if (!isset(self::$_instances[$name]))
{p('new intance:' . __CLASS__);
// 不存在,则实例化一个
self::$_instances[$name] = new self();}
return self::$_instances[$name];
}
/**
* 此接口用来测试单例模式 - 改变 string 的值
*
* @access public
* @param string $string 值
* @return void
*/
public function setContent($string)
{$this->string = $string;}
/**
* 此接口用来测试单例模式 - 输出 string 的值
*
* @access public
* @return void
*/
public function getContent()
{p('$this->string',$this->string);
}
}
调用的代码:
class Client
{static public function factory1Produce()
{$cd = CDFactory::getInstance('CD1');
$cd->setContent('CD 1 内容~');
return $cd;
}
static public function factory2Produce()
{$cd = CDFactory::getInstance('CD2');
$cd->setContent('CD 2 内容~');
return $cd;
}
/**
* 主函数
*/
static public function main()
{
// 工厂 1 生产
$cd_1 = static::factory1Produce();
$cd_1->getContent();
// 工厂 2 生产
$cd_2 = static::factory2Produce();
$cd_2->getContent();}
}
执行结果:
new intance:CDFactory
$this->string=
string(12) "CD 1 内容~"
new intance:CDFactory
$this->string=
string(12) "CD 2 内容~"
执行结果里面我们可以看到,new intance:CDFactory 调用了两次,实现了一个类有多个实例,因为我们的实例是存在 $_instances 数组中,所以每次 new intance 又都是 CD 类本身。
在实际应用中,多例模式可以用在处理多个数据库连接器等相似功能,但是不同实例的情况。
多例模式和单例模式是比较简单的设计模式,同时也是被经常使用的设计模式,尤其是单例模式,比如 ThinkPHP 中的 Cache 就是用的多例模式,但是 Redis 连接的处理就是用的单例模式。