Следующий код из учебника ( http://net.tutsplus.com/php/creating-a-php5-framework-part-1/ ), а не моего.
У меня есть несколько вопросов об этом коде …
Я просто хочу выяснить, должен ли я использовать этот шаблон дизайна в моей собственной реализации структуры 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; } } ?>
В статье утверждается, что используется «шаблон оформления реестра»; что универсальное название этого дизайна в отрасли?
Да, но реализация, очевидно, может отличаться. В основном, реестр представляет собой контейнер для общих объектов. В действительно базовой версии вы можете использовать массив. Таким образом, переменную $GLOBALS
можно назвать реестром.
Есть ли еще один подобный вариант, который будет лучшим вариантом?
Существует два варианта реестра. Существует глобальный реестр (который является самым распространенным, и это пример). И есть локальный реестр. Локальный реестр передается объектам, которые в нем нуждаются, а не получается через глобальный символ (статический класс, singleton и т. Д.). Локальный реестр имеет более низкую степень сцепления, но также немного более абстрактен, поэтому существует компромисс.
Вы также можете пойти еще дальше и использовать полную инъекцию зависимостей, где вы явно передаете всю зависимость от объектов, которые в них нуждаются. Это может быть немного утомительно в больших приложениях. Вы можете связать это с контейнером инъекции зависимостей, который представляет собой фрагмент кода, который «знает», какие зависимости имеют классы. Это еще сложнее, чем локальный реестр, но имеет очень низкую степень сцепления.
Является ли эта модель считающейся эффективной практикой для реализации в контексте структуры MVC?
Это обычная практика. Если это хорошо или плохо, это решение. Лично я готов принять некоторую сложность взамен развязки, но ymmv.
Я придерживаюсь мнения, что в целом говоря, на самом деле не так уж и плохо, как «плохая модель». При этом некоторые методы следует использовать более экономно, чем другие, и понятие глобального реестра – это тот, который часто бывает менее элегантным. Проблема заключается в том, что зависимости между заданными объектами обрабатываются посредством адресной адресации, которая сродни простому использованию глобальных переменных, а не косвенной стратегией, предоставляя зависимости, что обычно называется инъекцией зависимостей .
Как это может повлиять на повторное использование и гибкость программного обеспечения на самом деле очень ясно. Рассмотрим обработчик запросов, который интегрируется с поставщиком OAuth2 для аутентификации. Если вы определяете объект с четко определенным интерфейсом для запросов к этому провайдеру OAuth2, у вас есть возможность изменить поставщика в будущем, создав еще один объект, который реализует один и тот же интерфейс.
Теперь скажем, для обсуждения, для вашей первой реализации необходимо получить доступ к Facebook. Но затем на следующей неделе вы принимаете решение о том, что вы также должны поддерживать Yahoo, который реализует OAuth2 таким образом, который следует за спецификацией более тесно, чем Facebook, фактически использует JSON в запросе токена авторизации, а не в парах значений имени. И, кроме того, существуют разные пары URL-адресов и ключей, а также то, что нужно сохранить.
Хорошо, если вы искали своего провайдера аутентификации по имени с помощью шаблона реестра или шаблонов локализации службы, у вас теперь есть проблема. Вам нужно либо скопировать код, либо внести незначительные изменения в него, чтобы вы могли сразу поддерживать его, либо найти другое решение, например, прохождение ключей и добавление хэш-таблиц во всех местах, чтобы найти все эти элементы и обнаружить эти отклонения. Между тем, если вы использовали инъекцию зависимостей, вы можете просто создать другую реализацию своего провайдера проверки подлинности, которая реализует незначительную дисперсию разбора маркера аутентификации и создаст новый экземпляр вашего обработчика запросов, который использует этот объект и уже был протестирован, а затем развертывает это в новое место.
Косвенность спасла вас, уменьшила количество необходимого кода и в конечном итоге сделала ваше программное обеспечение более дешевым, лучшим и быстрым.
С учетом сказанного, бывают случаи, когда два шаблона не являются непосредственно взаимозаменяемыми. Скажем, например, вы создаете структуру, которая привязывает обработчики событий к узлам XML-документа. Вы описываете расположение узлов в XML-документе, используя XPath или реализацию JQuery селекторов CSS. Но для присоединения обработчика событий вам также необходимо обратиться к некоторому коду. Предпочтительно, вы будете ссылаться на какой-то метод какого-либо объекта – ну, нет никакого способа найти этот «некоторый объект», не указывая ему имя, поэтому теперь вам нужен локатор сервисов, поэтому вы можете искать вещи по имени. Но имейте в виду, что даже в этом примере нет ничего, что указывало бы на то, что имя должно быть глобальным .
Создание локального локатора служб или локального реестра, поскольку вы вызываете его здесь, является разумным решением проблемы такого рода. Если в одном приложении могут быть два экземпляра реестра, некоторые из вышеупомянутых проблем повторного использования иногда могут быть смягчены.