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