当前位置:首页 > PHP教程 > php高级应用 > 列表

使用注册树及工厂模式来替代使用单例模式实践(附案例)

发布:smiling 来源: PHP粉丝网  添加日期:2022-07-20 17:21:56 浏览: 评论:0 

今天在php中文网和大家介绍下一种结构型设计模式——注册树模式,别名注册器模式或注册模式,它是用来保存程序中经常使用的对象的实例,注册树模式通过将对象实例注册到一棵全局的对象树上,需要的时候从对象树上采摘,但和现实中的采摘不同的是,从对象树上摘下来的果子依旧存在对象树上,下次还可以继续摘。

实现代码

注册器模式非常容易理解和实现。一般会有一个属性用来存放多个对象实例,以及set及get方法。set方法用来将对象实例保存在属性数组中,get方法用来或取想要的对象实例。

  1. class Registry 
  2.  
  3. { 
  4.  
  5.     // 保存实例对象 
  6.  
  7.     private static $objs = []; 
  8.  
  9.       
  10.  
  11.     // get获取实例对象 
  12.  
  13.     public static function get(string $alias) : Object 
  14.  
  15.     { 
  16.  
  17.         if (!isset(self::$objs[$alias])) { 
  18.  
  19.             throw new \Exception($alias . 'not found'); 
  20.  
  21.         } 
  22.  
  23.           
  24.  
  25.         return self::$objs[$alias]; 
  26.  
  27.     } 
  28.  
  29.       
  30.  
  31.     // set将实例对象注册到属性$objs中 
  32.  
  33.     public static function set (string $alias, Object $obj) : void 
  34.  
  35.     { 
  36.  
  37.         if (!isset(self::$objs[$alias])) { 
  38.  
  39.             self::$objs[$alias] = $obj; 
  40.  
  41.         } 
  42.  
  43.     } 
  44.  
  45.       
  46.  
  47.     // 注销实例 
  48.  
  49.     public static function unset (string $alias) :void 
  50.  
  51.     { 
  52.  
  53.         if (isset(self::$objs[$alias])) { 
  54.  
  55.             unset(self::$objs[$alias]); 
  56.  
  57.         } 
  58.  
  59.     } 
  60.  
  61. } 

使用注册树模式和工厂模式来代替单例模式

我们知道,单例是非常有用的,可以避免资源浪费等。但是,单例模式已经被认为是一种反面模式了,认为单例模式不好测试及维护。关于为什么单例模式被认为是反面模式,这里就不细说了,有兴趣的朋友可以自行谷歌。

那么,我们有没有其他的方法用来保证单例,但不使用单例模式呢?有的,我们可以使用注册树模式和工厂模式来替代单例模式。下面是具体代码:

  1. class Registry 
  2.  
  3. { 
  4.  
  5.     // 保存实例对象 
  6.  
  7.     private static $objs = []; 
  8.  
  9.       
  10.  
  11.     // get获取实例对象 
  12.  
  13.     public static function get(string $alias)  
  14.  
  15.     { 
  16.  
  17.         if (!isset(self::$objs[$alias])) { 
  18.  
  19.             return null; 
  20.  
  21.         } 
  22.  
  23.         return self::$objs[$alias]; 
  24.  
  25.     } 
  26.  
  27.       
  28.  
  29.     // set将实例对象注册到属性$objs中 
  30.  
  31.     public static function set (string $alias, Object $obj) : void 
  32.  
  33.     { 
  34.  
  35.         if (!isset(self::$objs[$alias])) { 
  36.  
  37.             self::$objs[$alias] = $obj; 
  38.  
  39.         } 
  40.  
  41.     } 
  42.  
  43.       
  44.  
  45.     // 注销实例 
  46.  
  47.     public static function unset (string $alias) :void 
  48.  
  49.     { 
  50.  
  51.         if (isset(self::$objs[$alias])) { 
  52.  
  53.             unset(self::$objs[$alias]); 
  54.  
  55.         } 
  56.  
  57.     } 
  58.  
  59. } 
  60.  
  61.  
  62.  
  63. class DbFactory 
  64.  
  65. { 
  66.  
  67.     const ALIAS = 'Db'; 
  68.  
  69.       
  70.  
  71.     public static function create () 
  72.  
  73.     { 
  74.  
  75.         $db = Registry::get(self::ALIAS); 
  76.  
  77.         if (!$db) { 
  78.  
  79.             $db = new Db([ 
  80.  
  81.                 'host' => 'localhost', 
  82.  
  83.                 'user' => 'root', 
  84.  
  85.                 'pass' => '', 
  86.  
  87.                 'db_name' => 'test' 
  88.  
  89.             ]); 
  90.  
  91.             Registry::set(self::ALIAS, $db); 
  92.  
  93.         } 
  94.  
  95.           
  96.  
  97.         return $db; 
  98.  
  99.     } 
  100.  
  101. } 

当我们需要Db实例是,只要去调用DbFactory::create即可,该方法保证了单例。下面是测试代码:

$db = DbFactory::create();

var_dump($db);

Tags: php注册树 php单例模式

分享到: