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

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

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

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

实现代码

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

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

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

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

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

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

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

$db = DbFactory::create();

var_dump($db);

Tags: php注册树 php单例模式

分享到: