2017-01-31 7 views
1

Проект, над которым я работаю, требует, чтобы у меня были некоторые объекты, включая диспетчер конфигурации событий (только для чтения) и диспетчер подключаемых модулей, которые доступны повсюду в системе.Каков предпочтительный способ доступа к объекту в PHP?

Я использовал глобальные переменные для них, пока кто-то (с фоном C++) не заметил, что «вы, вероятно, делаете что-то неправильно, если вам нужны глобальные переменные».
Он предложил использовать объект состояния, который передается всем функциям, которые в нем нуждаются.
Так что я сделал:

$state = new State(); 
$state->register('eventManager' , new EventManager()); 
$state->register('configManager', new ConfigManager()); 
$state->register('cacheManager' , new CacheManager()); 
$state->register('pluginManager', new PluginManager()); 

$state->get('pluginManager')->initialize($state); 

В то время как я могу видеть преимущество этого метода в более сохраняющих состояние языков, кажется, вроде бессмысленно мне в (в основном?) Лица без языка, как PHP, где теряется состояние после страницы делается загрузка.

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

+0

Многие хорошие вопросы порождают определенное мнение, основанное на опыте экспертов, но ответы на этот вопрос будут иметь тенденцию почти полностью основываться на мнениях, а не на фактах, ссылках или конкретном опыте. Возможно, вы захотите найти форум для разработки (возможно, [quora] (http://www.quora.com/Computer-Programming)?), Чтобы разобраться в общих чертах. Затем, когда/если у вас есть особые проблемы с кодированием, вернитесь в StackOverflow, и мы будем рады помочь. –

+2

Что вы хотите - это инъекция зависимостей *, а ваш «объект состояния» здесь является чем-то вроде первого удара в контейнере инъекции зависимостей. Независимо от того, имеет ли что-либо состояние состояние или нет, дело не только в отношении * кодовых отношений *. И это полезно на любом языке. – deceze

+2

Кроме того, PHP не является «без гражданства». Он чаще всего используется на веб-сервере для обработки запросов без учета состояния; но может быть так же легко использоваться в очень «stateful» способе. – deceze

ответ

2

Реестр, который вы предлагаете, по-прежнему является глобальной переменной. И если вы хотите получить доступ к глобальной переменной (даже если это объект, хотя и глобальный), вы делаете что-то неправильно.

Правильное приложение имеет только фазу, где глобальное состояние играет определенную роль: при начальной загрузке. Запрос, начинающийся с сценария, является глобальным, любые данные запроса, отправленные с ним, являются глобальными, и любая конфигурация, которая влияет на приложение и хранится в файле или в каком-либо другом соответствующем хранилище, является глобальной.

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

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

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

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

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

+0

В этом случае это будет основой. Это не очень понятно из кода, но я не обращаюсь к $ state как глобальной переменной atm, а передавая его как параметр, как в последней строке. Я немного прочитал об инъекции зависимостей, не значит ли это, что у меня получится множество параметров для определенных функций? То есть функции, которые вызывают другие функции, которые имеют зависимости, получат те же самые зависимости, верно? Разве это не будет очень грязным очень быстро? – SharkWipf

+1

@SharkWipf - это очень хорошо. На ваш вопрос нет ни одного решения - иногда для определенных классов требуются простые решения, такие как одиночные игры; В других случаях решения, подобные предложению Свена, более уместны. Большинство сегодняшних рамок обеспечивают их собственный «вкус» того, как это делать, вместе со своим собственным языком и множеством мнений для загрузки. –

+0

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

2

Один из способов сделать это с одиночек:

class ConfigManager { 
    private static $instance = NULL; 

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

     return self::$instance; 
    } 

    private function __construct(){ 
     // Notice that this is private - only getInstance() can call this. 
    } 
} 

// When you need it: 
$config = ConfigManager::getInstance(); 

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

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

+0

Действительно? Одиночки? На них есть только два мнения: один говорит, что эта картина описана в книге [«Банда четырех»] (https://en.wikipedia.org/wiki/Design_Patterns), так что это хорошо (и, скорее всего, ответ предполагаемых плохих разработчиков в интервью, когда их спрашивают об их знании программных паттернов). Другой говорит, что оригинальные авторы этой книги позже отозвали свое мнение и объявили это антипаттерном, которого следует избегать. – Sven

+0

@Sven - Вопрос был: «Какой предпочтительный способ иметь доступный объект во всем мире?» - на что это один из многих действительных ответов. Я не согласен с тобой - не упоминал ли я и о том, что я не думал, что синглоты всегда лучший способ сделать это? Для чего-то вроде простого глобального класса конфигурации в небольшом приложении это очень хорошо может быть лучшим способом сделать это. Для чего-то большего масштаба, возможно, нет. Вы можете отправить альтернативный метод, если вы чувствуете себя настолько склонным. :-) –