Шаблон дизайна реестра... хорошо или плохо?
Следующий код взят из учебника ( 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 ответа
В статье утверждается, что она использует "шаблон проектирования реестра"; это универсальное название для этого дизайна в отрасли?
Да, но реализация, очевидно, может отличаться. По сути, реестр - это контейнер для общих объектов. В действительно базовой версии вы можете использовать массив. Таким образом, переменная $GLOBALS
можно назвать реестром.
Есть ли другой подобный шаблон, который был бы лучшим вариантом?
Есть два варианта реестра. Существует глобальный реестр (который является наиболее распространенным и примером которого является). И есть локальный реестр. Локальный реестр передается объектам, которые в нем нуждаются, а не через глобальный символ (статический класс, синглтон и т. Д.). Локальный реестр имеет более низкую степень связности, но также немного более абстрактен, поэтому здесь есть компромисс.
Вы также можете пойти еще дальше и использовать полную инъекцию зависимостей, где вы явно передаете всю зависимость объектам, которые в них нуждаются. Это может быть немного утомительно в больших приложениях. Вы можете связать это с контейнером внедрения зависимостей, который представляет собой фрагмент кода, который "знает", какие зависимости есть у классов. Это даже более сложно, чем локальный реестр, но имеет очень низкую степень связи.
Считается ли этот шаблон хорошей практикой для реализации в контексте инфраструктуры MVC?
Это обычная практика. Хорошо это или плохо - это суждение. Лично я готов принять некоторую сложность взамен развязки, но ммм.
Я придерживаюсь мнения, что, вообще говоря, не существует такого понятия, как "плохая модель". Тем не менее, некоторые методы должны использоваться более экономно, чем другие, и понятие глобального реестра часто не элегантно. Проблема с этим заключается в том, что зависимости между данными объектами обрабатываются с помощью адресации на основе имен, что сродни простому использованию глобальных переменных, а не косвенному стратегическому подходу с предоставлением зависимостей - что обычно называют внедрением зависимостей.
Как это может повлиять на повторное использование и гибкость программного обеспечения, на самом деле очень ясно. Рассмотрим своего рода обработчик запросов, который интегрируется с поставщиком OAuth2 для аутентификации. Если вы определяете объект с четко определенным интерфейсом для отправки запросов этому поставщику OAuth2, у вас есть возможность сменить поставщика в будущем, создав другой объект, который реализует тот же интерфейс.
Теперь, скажем, ради обсуждения вашей первой реализации необходимо получить доступ к Facebook. Но затем на следующей неделе вы принимаете решение о том, что вам также следует поддержать Yahoo, которая реализует OAuth2 способом, который более точно следует спецификации, чем Facebook, фактически используя JSON в запросе токена авторизации, а не пары имя-значение. И в довершение всего, есть разные пары URL-адресов и ключей и еще много чего, что необходимо сохранить.
Хорошо, если вы искали своего провайдера аутентификации по имени, используя шаблон реестра или шаблоны поиска служб, у вас сейчас есть проблема. Вам нужно либо скопировать код и внести в него незначительные изменения, чтобы вы могли поддерживать оба сразу, либо найти другое решение, такое как передача ключей и добавление хеш-таблиц во всех местах, чтобы найти все эти элементы и обнаружить эти отклонения. Между тем, если вы использовали внедрение зависимостей, вы можете просто создать другую реализацию вашего провайдера аутентификации, которая реализует небольшую разницу в разборе токена аутентификации, и создать новый экземпляр вашего обработчика запросов, который использует этот объект и уже был протестирован, а затем развернуть это на новое место.
Эта косвенность избавила вас от работы, сократила объем необходимого кода и, в конечном итоге, сделала ваше программное обеспечение дешевле, лучше и быстрее.
С учетом сказанного, бывают случаи, когда эти две модели не являются взаимозаменяемыми. Допустим, например, что вы создаете своего рода структуру, которая присоединяет обработчики событий к узлам XML-документа. Вы описываете расположение узлов в XML-документе, используя реализацию селекторов CSS в XPath или JQuery. Но для того, чтобы прикрепить обработчик события, вам также нужно обратиться к некоторому коду. Предпочтительно, вы будете ссылаться на некоторый метод некоторого объекта - ну, нет никакого способа найти этот "некоторый объект", не дав ему имя, поэтому теперь вам нужен локатор службы, чтобы вы могли искать вещи по имени. Но имейте в виду, что даже в этом примере ничто не указывает на то, что имя должно быть глобальным.
Создание локального локатора службы или локального реестра, как вы его здесь называете, является разумным решением проблемы такого рода. Если в одном и том же приложении может быть два экземпляра реестра, некоторые из вышеупомянутых проблем повторного использования могут иногда быть смягчены.