04
02月
2020
多例模式
模式定义
多例模式和单例模式类似,但可以返回多个实例。比如我们有多个数据库连接,MySQL、SQLite、Postgres,又或者我们有多个日志记录器,分别用于记录调试信息和错误信息,这些都可以使用多例模式实现。
代码示例
Multion\Multion.class.php
<?php
namespace Multion;
abstract class Multion
{
private static $instances = array();
public static function getInstance()
{
$key = get_called_class() . serialize(func_get_args());
if(!isset(self::$instances[$key])){
$rc = new \ReflectionClass(get_called_class());
self::$instances[$key] = $rc->newInstanceArgs(func_get_args());
}
return self::$instances[$key];
}
}Multion\Mysql.class.php
<?php
namespace Multion;
class Mysql extends Multion
{
public function __construct($cfg)
{
echo serialize($cfg);
}
}Multion\Redis.class.php
<?php
namespace Multion;
class Redis extends Multion
{
public function __construct($cfg)
{
echo serialize($cfg);
}
}Multion\MultionTest.php
<?php
spl_autoload_register(function ($className){
$className = str_replace("\\", "/", $className);
include $className . ".class.php";
});
use Multion\Mysql;
use Multion\Redis;
$instance1 = Mysql::getInstance(["db" => 'mysql', 'username' => 'test1', 'password' => 'secret']);
$instance2 = Mysql::getInstance(["db" => 'mysql', 'username' => 'test2', 'password' => 'secret']);
$instance3 = Mysql::getInstance(["db" => 'mysql', 'username' => 'test1', 'password' => 'secret']);
$instance4 = Redis::getInstance(["db" => 'Redis', 'username' => 'test4', 'password' => 'secret']);
echo "\n" . ($instance1 === $instance2 ? '相同' : '不同');
echo "\n" . ($instance1 === $instance3 ? '相同' : '不同');
echo "\n" . ($instance1 === $instance4 ? '相同' : '不同');测试示例:
php Multion/MultionTest.php 输出: 不同 相同 不同
代码地址:https://github.com/798256478/design-patterns/tree/master/Multion