Zend Framework — таблица базы данных Singleton

Я обнаружил, что делаю это в своем коде, чтобы «кэшировать» работу, проделанную при создании экземпляров моих моделей Zend_Db_Table:

if (Zend_Registry::isRegistered('x_table')) {
    $x_table = Zend_Registry::get('x_table');
} else {
    $x_table = new Default_Model_DbTable_X;
    Zend_Registry::set('x_table', $x_table);
}

Меня беспокоило, что этот метод не очень СУХОЙ, и сегодня меня осенило, что одноэлементный шаблон, вероятно, был бы лучшим способом сделать это. Проблема в том, что я никогда не писал одноэлементный класс. Когда я провел поиск в Интернете, я нашел несколько небрежных комментариев о Zend_Db_Table синглтонах, но не нашел реальных примеров.

У меня уже настроено кэширование метаданных.

  1. Как мне сделать мои Zend_Db_Table модели синглтонами?
  2. Есть ли подводные камни или недостатки?

Редактировать: Причина, по которой я решил, что ответом является синглтон, заключается в том, что я думал, что могу просто иметь следующие вызовы в своем коде $x_table = new Default_Model_DbTable_X;, и единственный экземпляр будет возвращен, если он существует. Если это возможно, я бы предпочел это решение.


person Sonny    schedule 14.04.2010    source источник
comment
Что вы делаете в своем коде, что вам нужно создать несколько экземпляров одной и той же таблицы в одном запросе?   -  person Gordon    schedule 15.04.2010
comment
(ссылка) sourcemaking.com/design_patterns/singleton   -  person Gordon    schedule 15.04.2010
comment
Я создаю CMS, и таблицы содержат контент. Блоки контента могут быть помещены на страницу, и на странице может быть несколько блоков одного типа. Спасибо за ссылку!   -  person Sonny    schedule 15.04.2010
comment
Пожалуйста, но я до сих пор не понимаю, зачем вам нужно несколько экземпляров одной и той же таблицы вместо того, чтобы просто передавать первый экземпляр и выполнять к нему несколько запросов.   -  person Gordon    schedule 15.04.2010
comment
@Gordon - Извините, я не правильно ответил на ваш вопрос. Мне не нужно несколько экземпляров, это то, что мой код выше пытается смягчить. Я (проверяю | храню) экземпляр в реестре, который может быть там, а может и не быть. Мой пост в основном просит лучшего способа.   -  person Sonny    schedule 15.04.2010


Ответы (1)


Почему бы просто не управлять таблицами DbTable в каком-нибудь разумном месте? Если толкового места нет, создайте класс DbTableManager. Что-то типа:

<?PHP
class DbTableMgr {

  protected $_tables;

  public function getTable($classname){
    if ( empty($this->_tables[$name]) ){
      //assuming some things about class names for the sake of brevity elsewhere...
      $classname = 'Default_Model_DbTable_',ucfirst(strtolower($classname));

      $this->_tables[$name] = new $classname; 
    }
    return $this->_tables[$name];  
  }
}

Инициализируйте менеджер в своем бутстрапе и вставьте его в реестр.

Потом:

<?PHP
//in a galaxy far, far, away
$dbtFoo = Zend_Registry::get('dbtMgr')->getTable('Foo');

Итак, вы лениво загружаете объекты dbTable и применяете поведение, подобное синглтону.

Вы можете сделать это статическим различными способами, если хотите.

person timdev    schedule 14.04.2010
comment
Ваш метод Zend_Registry выглядит хорошо, но я заинтригован тем, что вы имели в виду под разумным местом. Похоже, вы подразумеваете, что Zend_Registry является вторым лучшим решением. - person Sonny; 15.04.2010
comment
Zend_Registry отлично подходит для таких вещей. Я просто имел в виду, что, в зависимости от дизайна приложения, может быть более разумное место для реализации материала dbTableManager. Но если вы не уверены, нет ничего плохого в том, чтобы просто создать класс, как я показал, и вставить его в реестр во время начальной загрузки вашей базы данных. - person timdev; 15.04.2010
comment
хорошо, это старый вопрос, но мне любопытно. Почему бы просто не сделать его сигнальным. По крайней мере, это добавляет удобства. UserTable::getInstance()->getUsers() - person SoWhat; 11.06.2013
comment
@ Somesh Mukherjee - вы тоже можете это сделать, но в этом случае вам нужно будет добавить еще один уровень в иерархию классов, чтобы обеспечить одноэлементное поведение для всех классов * Table. Zend_Registry уже существует и делает то же самое. - person timdev; 12.06.2013
comment
хорошо, это правда. но я все еще думаю, что именно такими должны были быть Zend Tables. Шаблон синглетон имеет больше смысла, чем наличие нового объекта - person SoWhat; 13.06.2013