今天在php中文網和大家介紹下一個結構型設計模式-註冊樹模式,別名註冊器模式或註冊模式,它是用來保存程式中常用的物件的實例。註冊樹模式透過將物件實例註冊到一棵全域的物件樹上,需要的時候從物件樹上採摘。但和現實中的採摘不同的是,從對象樹上摘下來的果子依舊存在對象樹上,下次還可以繼續摘。
實作程式碼
註冊器模式非常容易理解和實作。一般會有一個屬性用來存放多個物件實例,以及set及get方法。 set方法用來將物件實例保存在屬性陣列中,get方法用來或取想要的物件實例。
class Registry { // 保存实例对象 private static $objs = []; // get获取实例对象 public static function get(string $alias) : Object { if (!isset(self::$objs[$alias])) { throw new \Exception($alias . 'not found'); } return self::$objs[$alias]; } // set将实例对象注册到属性$objs中 public static function set (string $alias, Object $obj) : void { if (!isset(self::$objs[$alias])) { self::$objs[$alias] = $obj; } } // 注销实例 public static function unset (string $alias) :void { if (isset(self::$objs[$alias])) { unset(self::$objs[$alias]); } } }
使用註冊樹模式和工廠模式來取代單例模式
我們知道,單例是非常有用的,可以避免資源浪費等。但是,單例模式已經被認為是一種反面模式了,認為單例模式不好測試及維護。關於為什麼單例模式被認為是反面模式,這裡就不細說了,有興趣的朋友可以自行谷歌。
那麼,我們有沒有其他的方法可以保證單例,但不使用單例模式呢?有的,我們可以使用註冊樹模式和工廠模式來取代單例模式。以下是具體程式碼:
class Registry { // 保存实例对象 private static $objs = []; // get获取实例对象 public static function get(string $alias) { if (!isset(self::$objs[$alias])) { return null; } return self::$objs[$alias]; } // set将实例对象注册到属性$objs中 public static function set (string $alias, Object $obj) : void { if (!isset(self::$objs[$alias])) { self::$objs[$alias] = $obj; } } // 注销实例 public static function unset (string $alias) :void { if (isset(self::$objs[$alias])) { unset(self::$objs[$alias]); } } } class DbFactory { const ALIAS = 'Db'; public static function create () { $db = Registry::get(self::ALIAS); if (!$db) { $db = new Db([ 'host' => 'localhost', 'user' => 'root', 'pass' => '', 'db_name' => 'test' ]); Registry::set(self::ALIAS, $db); } return $db; } }
當我們需要Db實例是,只要去呼叫DbFactory::create即可,該方法保證了單例。以下是測試程式碼:
$db = DbFactory::create(); var_dump($db);
#相關推薦:
以上是使用註冊樹及工廠模式來取代使用單例模式實踐(附案例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!