ITDumka
Вариант реализации паттерна Registry или глобальная фабрика

Вот набросал вариант глобального реестра. Это стандартная реализация паттерна Registry в виде единственного экземпляра, но еще и с некоторыми фишками. Одна из них, если это можно назвать фишкой, - возможность обращения к защищенным свойствам из статических методов. Не знаю на сколько это круто, но меня почему-то пропёрло.

Думаю, неплохо получилось, так что комментировать мне уже нечего. Но вы можете это сделать в комментариях.



Listing №1 (PHP)
  1. <?php
  2.  
  3. //интерфейс базы данных
  4. interface Db {
  5.   function foo();
  6. }
  7.  
  8. //база данных
  9. class RealDb implements Db {
  10.  
  11.   function foo()
  12.   {
  13.     echo 'real db';
  14.   }
  15. }
  16.  
  17. //фиктивная служба базы данных
  18. class TestDb implements Db {
  19.   function foo()
  20.   {
  21.     echo 'test db';
  22.   }
  23. }
  24.  
  25. //Реестр
  26. class Registry {
  27.  
  28.   private static $_instance = null;
  29.  
  30.   protected $_db;
  31.  
  32.   public static function init($instance)
  33.   {
  34.     self::$_instance = new $instance();
  35.     if (!self::$_instance instanceof Registry) {
  36.       throw new Exception('');
  37.     }
  38.   }
  39.  
  40.   private static function getInstance()
  41.   {
  42.     if (!self::$_instance) {
  43.       self::init('Registry');
  44.     }
  45.    
  46.     return self::$_instance;
  47.   }
  48.  
  49.   public static function getDb()
  50.   {
  51.     return self::getInstance()->_db;
  52.   }
  53.    
  54.   protected function __construct() {
  55.     $this->_db = new RealDb();
  56.   }
  57.  
  58.   private function __clone() {}
  59. }
  60.  
  61. //Реестр для тестирования
  62. class TestRegistry extends Registry {
  63.  
  64.   protected function __construct() {
  65.     $this->_db = new TestDb();
  66.   }
  67. }
  68.  
  69. ////Пример
  70.  
  71. //Инициализация для тестирования
  72. //Registry::init('TestRegistry');
  73.  
  74. $db = Registry::getDb();
  75. $db->foo();


Раскомментируйте 72 строчку для инициализации другого варианта реестра. Можно заметить, что это похоже на глобальную фабрику.

Comments
By   Andipas
Published   14.08.2010

Спасибо за класс! Попробую использовать.

Листинги из блога копировать неудобно, куча лишнего копируется.

А капча жжет, я сначала думал предыдущий символ на клавиатуре, но наверное в алфавите, сейчас проверю...

Published   14.08.2010

Да, с листингами полная хрень в этом смысле.

А класс надо использовать такой, какой нужен, так что не за что.

By   Andipas
Published   15.08.2010

Ломаю голову, как сделать так -


Чтобы в конструкторе не создавать кучу классов, только необходимые. К примеру метод getTopic смотрел бы существует уже такой объект, если существует отдаем его, если нет то загружаем класс, создаем объект и отдаем.


Тем самым, подгружаются только необходимые классы и создаются только необходимые объекты. Выгода очевидна. Как так сделать?

Published   15.08.2010

Очевидно что ленивой инициализацией:


Listing №1 (PHP)
  1. <?php
  2.  
  3. __construct()
  4. {
  5.   $this->_topic = null;
  6. }
  7.  
  8. getTopic()
  9. {
  10.   if ($this->_topic === null) {
  11.     $this->_topic = new Topic();
  12.   }
  13.  
  14.   return $this->_topic;
  15. }

By   Andipas
Published   15.08.2010

Спасибо, но - вот такая ошибка:

Fatal error: Using $this when not in object context in Z:\home\rex\www\classes\Registry.class.php on line 33

Published   15.08.2010

Я думаю тебе стоит почитать книги по ООП в PHP да и синтаксис языка подтянуть...

Published   15.08.2010

Естественно getTopic() надо сделать статическим методом типа getDb, я же так по шурику набросал...

By   Andipas
Published   15.08.2010

Все супер, работает! Это действительно здорово, то что мне нужно было, спасибо! :)


Listing №1 ()
  1.  
  2.   public static function getTopic() {
  3.     if (self::getInstance()->_oTopic === NULL) {
  4.       self::getInstance()->_oTopic = new Tac('topic');
  5.     }
  6.     return self::getInstance()->_oTopic;
  7.   }
  8.  

By   Andipas
Published   15.08.2010

Книжки читаю конечно, но без практики, все быстро забывается, поэтому учусь практикуясь

Published   15.08.2010

Читай, читай, эффективнее будешь практиковаться...

By   Andipas
Published   15.08.2010

Еще дополню, классы автоматом подгружаются, об этой замечательной фиче, ток сегодня узнал:

Listing №1 ()
  1.  
  2. function __autoload($class_name) {
  3.     require_once HOMEPATH . '/classes/' . $class_name . '.class.php';
  4. }
  5.  

Published   15.08.2010

Ну что ж, поздравляю ))

Create comment
 
Formatting
Comment can not be edited. Please, use the button "Preview"
By
  (Enter prev char)
Comment
Categories
PHP
12
articles
Прочее
4
articles
Delphi
0
article
C/C++
0
article
C#
0
article
Java
0
article
Perl
0
article
Python
0
article
Enter
Cookie must be "ON"
Login
Password
 
Popular tags
PHP
9
articles
паттерн
5
articles
framework
5
articles
шаблон
5
articles
Template View
3
articles
Facade
3
articles
Service Stub
3
articles
Page Controller
2
articles
Singleton
2
articles
Gateway
2
articles
MySQL
2
articles
Registry
2
articles
Command
2
articles
Front Controller
2
articles
Action
2
articles
Abstract Factory
2
articles
типовое решение
2
articles
шаблоны проектирования
2
articles
Iterator
2
articles
Transaction Script
2
articles
Rambler's Top100 Правильный CSS!