2010-09-16 1 views
2

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

$settings = new Settings(); 
$settings->loadSettings(); 

Тогда, когда мне нужно кода в некоторой случайной функции в другом классе, я что-то вроде этого:

function abc() { 
    global $settings; 
    $variable = $settings->a; 
} 

Я болен и устал от случайного вызова глобальных параметров $ всего место, чтобы вытащить этот объект настроек. Я не хочу использовать массив $ _GLOBALS (я не знаю, почему, я просто не хочу).

Я думаю, что хочу переключиться на переменную статического класса, называемую $ настройками внутри настроек. Код будет выглядеть следующим образом:

Settings::$settings = new Settings(); 
Settings::$settings->loadSettings(); 

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

function abc() { 
    $variable = Settings::$settings->a; 
} 

Хорошая идея или плохая идея?

+0

Возможный дубликат [Лучший способ доступа к глобальным объектам (например, к базе данных или журналу) из классов и скриптов?] (Http://stackoverflow.com/questions/1967548/best-way-to-access-global-objects- like-database-or-log-from-classes-and-scripts) – Wrikken

ответ

8

Ну, это, вероятно, улучшение на глобальном уровне, потому что оно решает все уродливые проблемы, связанные с глобальными причинами. Как избавиться от глобального оператора, как правило, хорошо! То, что вы делаете, не отличается от одноэлементного шаблона, хотя оно значительно проще. (См. Раздел «Синглтон» по адресу http://php.net/manual/en/language.oop5.patterns.php для получения дополнительной информации о шаблоне.) Ваше решение почти наверняка прекрасно подходит для ваших целей.

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

class ABC { 
    private $settings; 

    public function __construct($settings) { 
     $this->settings = $settings; 
    } 

    public function someMethod() { 
     $variable = $this->settings->a; 
    } 
} 

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

Этот процесс, в котором вы «вводите» объект в другой объект, который зависит от него, называется инъекцией зависимостей. Существуют и другие, более сложные способы сделать это, включая сложные контейнеры. См. http://fabien.potencier.org/article/11/what-is-dependency-injection для интересного набора руководств по этому вопросу. Вероятно, они связаны с вашими текущими потребностями, но могут помочь либо сейчас, либо в будущем.

+0

Спасибо за замечательный ответ. –

+0

Однако, делая это, нам нужно больше кода с глобальным экземпляром, вот '$ setting', вместо использования' $ settings', правильно? Я не вижу в этом преимущества, почему люди избегают использования ключевого слова 'global'?Вы можете глобально на '__construct' получать' $ settings' вместо передачи объекта при объявлении экземпляра, и использование ссылки будет лучше в этом случае? '$ this-> settings = & $ settings' поможет ли это уменьшить использование памяти? – TomSawyer

1

Кажется, вы ищете Singleton. В основном идея состоит в том, чтобы иметь класс, который имеет открытый статический метод getInstance(), который возвращает экземпляр самого класса. При первом вызове метода он хранит экземпляр в частном свойстве, и все позже он возвращает сохраненный экземпляр. Таким образом, всякий раз, когда вы вызываете Settings :: getInstance(), вы гарантированно получаете копию того же объекта. Затем вы можете сохранить настройки в этом объекте.

+0

-1: в этом случае различий между статическим классом и singleton нет. –

+0

Да, есть один, и это тот факт, что один (возможно, другой программист) не может создать другой экземпляр настроек по ошибке, вместо использования настроек :: $ settings. Все, что делает одноэлементный шаблон, обеспечивает соблюдение этого соглашения. – Andrea

+0

Синглтон является анти-шаблон и не должен использоваться. http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/ –