Шаблон дизайна реестра ... хорошо или плохо? - PullRequest
16 голосов
/ 20 июля 2009

Следующий код взят из учебника (http://net.tutsplus.com/php/creating-a-php5-framework-part-1/), не мой.

У меня есть несколько вопросов об этом коде ...

  • В статье утверждается, что она использует "шаблон дизайна реестра"; это универсальное название для этого дизайна в отрасли?
  • Есть ли другой подобный шаблон, который был бы лучшим вариантом?
  • Считается ли этот шаблон хорошей практикой для реализации в контексте инфраструктуры MVC?

Я просто хочу выяснить, должен ли я использовать этот шаблон проектирования в моей собственной реализации инфраструктуры MVC. Спасибо!

<?php
/**
 * The PCARegistry object
 * Implements the Registry and Singleton design patterns
 * @version 0.1
 * @author Michael Peacock
 */
class PCARegistry {

/**
 * Our array of objects
 * @access private
 */
private static $objects = array();

/**
 * Our array of settings
 * @access private
 */
private static $settings = array();

/**
 * The frameworks human readable name
 * @access private
 */
private static $frameworkName = 'PCA Framework version 0.1';

/**
 * The instance of the registry
 * @access private
 */
private static $instance;

/**
 * Private constructor to prevent it being created directly
 * @access private
 */
private function __construct()
{

}

/**
 * singleton method used to access the object
 * @access public
 * @return 
 */
public static function singleton()
{
    if( !isset( self::$instance ) )
    {
        $obj = __CLASS__;
        self::$instance = new $obj;
    }

    return self::$instance;
}

/**
 * prevent cloning of the object: issues an E_USER_ERROR if this is attempted
 */
public function __clone()
{
    trigger_error( 'Cloning the registry is not permitted', E_USER_ERROR );
}

/**
 * Stores an object in the registry
 * @param String $object the name of the object
 * @param String $key the key for the array
 * @return void
 */
public function storeObject( $object, $key )
{
    require_once('objects/' . $object . '.class.php');
    self::$objects[ $key ] = new $object( self::$instance );
}

/**
 * Gets an object from the registry
 * @param String $key the array key
 * @return object
 */
public function getObject( $key )
{
    if( is_object ( self::$objects[ $key ] ) )
    {
        return self::$objects[ $key ];
    }
}

/**
 * Stores settings in the registry
 * @param String $data
 * @param String $key the key for the array
 * @return void
 */
public function storeSetting( $data, $key )
{
    self::$settings[ $key ] = $data;


}

/**
 * Gets a setting from the registry
 * @param String $key the key in the array
 * @return void
 */
public function getSetting( $key )
{
    return self::$settings[ $key ];
}

/**
 * Gets the frameworks name
 * @return String
 */
public function getFrameworkName()
{
    return self::$frameworkName;
}


}

?>

Ответы [ 2 ]

25 голосов
/ 20 июля 2009

В статье утверждается, что она использует «шаблон проектирования реестра»; это универсальное название для этого дизайна в отрасли?

Да, но реализация, очевидно, может отличаться. По сути, реестр - это контейнер для общих объектов. В действительно базовой версии вы можете использовать массив. Таким образом, переменная $GLOBALS может называться реестром.

Есть ли другой подобный шаблон, который был бы лучшим вариантом?

Существует два варианта реестра. Существует глобальный реестр (который является наиболее распространенным и примером которого является). И есть локальный реестр. Локальный реестр передается объектам, которые в нем нуждаются, а не через глобальный символ (статический класс, singleton и т. Д.). Локальный реестр имеет более низкую степень связи, но также немного более абстрактен, поэтому здесь есть компромисс.

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

Считается ли этот шаблон хорошей практикой для реализации в контексте инфраструктуры MVC?

Это обычная практика. Хорошо это или плохо - это суждение. Лично я готов принять некоторую сложность взамен развязки, но мммм.

5 голосов
/ 02 марта 2011

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

Как это может повлиять на повторное использование и гибкость программного обеспечения, на самом деле очень ясно. Рассмотрим своего рода обработчик запросов, который интегрируется с поставщиком OAuth2 для аутентификации. Если вы определяете объект с четко определенным интерфейсом для отправки запросов этому поставщику OAuth2, у вас есть возможность сменить поставщика в будущем, создав другой объект, который реализует тот же интерфейс.

Теперь, скажем, для обсуждения, ваша первая реализация должна получить доступ к Facebook. Но затем на следующей неделе вы принимаете решение о том, что вам также следует поддержать Yahoo, которая реализует OAuth2 способом, который более точно следует спецификации, чем Facebook, фактически используя JSON в запросе токена авторизации, а не пары имя-значение. И, кроме того, есть разные пары URL-адресов и ключей, и тому подобное, которые необходимо сохранить.

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

Переадресация спасла вашу работу, сократила объем необходимого кода и в конечном итоге сделала ваше программное обеспечение дешевле, лучше и быстрее.

С учетом сказанного, бывают случаи, когда эти два шаблона не являются непосредственно взаимозаменяемыми. Допустим, например, что вы создаете некий каркас, который присоединяет обработчики событий к узлам XML-документа. Вы описываете расположение узлов в XML-документе с помощью реализации CSS-селекторов в XPath или JQuery. Но для того, чтобы прикрепить обработчик события, вам также нужно обратиться к некоторому коду. Предпочтительно, вы будете ссылаться на некоторый метод некоторого объекта - ну, нет никакого способа найти этот «некоторый объект», не дав ему имя, поэтому теперь вам нужен локатор службы, чтобы вы могли искать вещи по имени. Но имейте в виду, что даже в этом примере ничто не указывает на то, что имя должно быть global .

Создание локального локатора службы или локального реестра, как вы его здесь называете, является разумным решением проблемы такого рода. Если в одном и том же приложении может быть два экземпляра реестра, некоторые из вышеупомянутых проблем повторного использования иногда могут быть смягчены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...