Реестр или шаблон Singleton в PHP? - PullRequest
10 голосов
/ 20 января 2010

Я сейчас работаю с PHP-классами и объектами. В этом вопросе имена полей и методов составлены именно для того, чтобы вы поняли, о чем я говорю.

Это связано с использованием шаблонов синглтона и реестра.

Теперь допустим, что мне нужен доступ к объекту базы данных, объекту кэша, объекту основных настроек, объекту сеанса почти во всех других классах, к которым мне потребуется доступ. Так что я бы использовал реестр для хранения всех 4 из этих объектов в 1 объект класса реестра. Затем я мог бы просто передать свой 1 объект в любой другой объект, который должен получить к ним доступ. Пока это звучит замечательно, но что если у меня есть некоторые классы, которым не нужны все 4 из этих объектов, что если мне ТОЛЬКО нужно получить доступ к объекту Database или объекту Session в некоторых других моих классах? Для исполнения было бы лучше всего использовать синглтон внутри этих других объектов, или это было бы то же самое, чтобы пойти дальше и использовать мой реестр в них?

Я не знаю достаточно хорошо, как объекты работают в PHP, чтобы знать, будет ли какое-либо увеличение производительности (меньшее использование памяти, использование процессора, время загрузки).

Так что любой, кто имеет опыт в этом, может быть, может сказать мне, будет ли какая-либо выгода при использовании того или другого, я нахожусь на стадии, где я могу идти по пути эфира, не влияя на время производства или что-то еще. Я хотел бы использовать лучший метод, если я могу сейчас.

Ответы [ 3 ]

4 голосов
/ 20 января 2010

Вы можете реализовать отложенную загрузку, чтобы загружать только те объекты, которые вам действительно нужны:

class Registry
{
    private static $database = null;

    private static function connectDatabase($key)
    {
        [... do connection stuff ...]
    }

    public static function getDatabase($key)
    {
        if (Registry::$database == null)
        {
            Registry::connectDatabase($key);
        }
        return Registry::$database;
    }
}

Код для регистрации параметров подключения к базе данных оставлен читателю в качестве упражнения.

3 голосов
/ 20 января 2010

Это зависит от вашего приложения. Если вам все еще нужны 3 из 4 классов, то было бы лучше использовать реестр, чем обрабатывать 3 независимо только потому, что четвертый вам не нужен. Загрузка классов лениво была бы одним из способов уменьшить объем памяти, но тогда вам нужно указать реестру, когда создавать объекты, и это не сильно отличается от обработки одиночных кодов. В качестве альтернативы, вы можете создать конструктор с n-параметрами или использовать массив, чтобы указать вашему Реестру, какие классы создавать в процессе создания.

class Registry {
    public $class1;
    public $class2;

    function __construct($uses) {
        foreach($uses as $class) {
            $this->{$class} = new {$class}();
        }
    }

}

Затем создайте экземпляр своего реестра, указав, какие классы следует создать.

$reg = new Registry(array('class1'));

Вы, очевидно, хотели бы, чтобы ваш конструктор обрабатывал нулевые параметры для учета создания экземпляров всех классов по умолчанию.

1 голос
/ 16 июня 2013

Возможно, это правильный шаблон Singleton-Registry. OFC, вы можете реализовать разные вещи, SplFixedArray, интерфейс ArrayAccess и другие. Также неплохо добавить разрушение и уничтожить внутренние объекты, чтобы гарантировать невозможность утечки.

class oRegistry{
   private static $instance = null;

   private $storage = array();

   private function __construct(){}

   private function __clone(){}

   public static function getInstance(){
      if( self::$instance === null ){
         self::$instance = new self();
      }
      return self::$instance;
   }

   public function attach($name, $o) {
      if( true === isset($this->storage[$name]) ) {
          throw new Exception('The instance with name '.$name.' already exists in registry.');
      }
      if( !empty( $name ) ) {
          $this->storage[ $name ] = $o;
      }
   }

   public function detach( $name ){
       if( isset( $this->storage[ $name ] ) ) {
           $this->storage[ $name ] = null;
           unset( $this->storage[ $name ] );
       }
   }

   public function get( $name ){
       if( false === isset( $this->storage[$name] ) ) {
           throw new Exception('Invalid instance requested');
       }
       return $this->storage[ $name ];
   }
}

// usage example
$storage = oRegistry::getInstance();
$obj = new stdClass;
$obj2 = new stdClass;
$obj->test1 = 'test';
$obj2->test2 = 't2';

$storage->attach( 'test1', $obj );
$storage->attach( 'test2', $obj2 );

$got = $storage->get( 'test2' );
var_dump($got); // object(stdClass)#3 (1) { ["test2"]=> string(2) "t2" }

$storage->detach( 'test2' );
$got = $storage->get( 'test2' );
var_dump($got); // bool(false)
...