Подгрузка классов и использование в них данных другого класса через конструктор.

Flyer

Новичок
Здравствуйте. Решил поглубже изучить ООП и начали вылезать различные вопросы о подходах в применении.

Есть класс конфигурации который экземпляр которого создается сразу. Задача этого класса выудить данные из ини файла конфигурации проекта при помощи конструктора. Сокращенно это выглядит так:

PHP:
<?php
class GlobalConfig {

    var $applicationPath;

    function __construct(){
        // Бла бла бла
        $this->applicationPath = "../application/";
    }
}

// Далее скажем в Index.php
$_GlobalConfig    =   new GlobalConfig();
?>
После этого у меня скрипт сразу инклудит папку содержащую основные классы проекта. В одном из этих классов мне допустим нужны данные из первого, в частности путь и самое главное сделать это через конструкторы как бы в автоматическом режиме:

PHP:
<?php
class SomeClass {

    function __construct() {
        global $_GlobalConfig;        
        // Что то нужно сделать с путем.
        $_GlobalConfig->applicationPathClasses;
    }   
}

$_SomeClass    =   new SomeClass();
?>
Для этого я во втором классе объявил глобально: global $_GlobalConfig;

Ну и собственно сам вопрос, верно ли действую в таком случае или это идет в разрез с религией ООП? В какую сторону мне в таком случае нужно копать для реализации такого же функционала?

Заранее спасибо за ответы.
 

Flyer

Новичок
Опс, какие таги для пхп кода? При создании темы нет легенды =( на бум писал...
 

AmdY

Пью пиво
Команда форума
смотри, глобальные переменные, одиночка и реестр - это такие патчи, которые портят архитектуру, но помогают легко и элегантно разруливать некоторые моменты. нужно стараться писать без них. тот же конфиг ты можешь передавать в конструктор. То же касается $_SomeClass, зачем ты гадишь в общее пространство
PHP:
new SomeClass(new GlobalConfig());
 

Духовность™

Продвинутый новичок
Ну и собственно сам вопрос, верно ли действую в таком случае или это идет в разрез с религией ООП?
Очень интересный вопрос на самом деле.

Конструкция global - это плохо. Концептуально, с точки зрения более-менее правильного ОО-проектирования, паттерн Singelton правильнее, чем global, хотя чисто по результату - одно и тоже.

Мне самому интересно, как это лучше делать. Ведь кроме объекта Config у нас может быть объект Session, Request, Response и ещё какие-то объекты-одиночки.

Сейчас я работаю с системой, которая передает (впрыскивает) в "клиентские" классы-контролеры объект, называемый Контекст. Это просто хранилище для всех "звёздных" объектов типа Config, Request, Response. Все это грубо говоря так происходит:

PHP:
// где-ото в bootstrap... 
$context = new Context();
$context->addResponse(Response::getInstance());
$context->addRequest(Request::getInstance());
$context->addSession(Session::getInstance());

// и впрыскиваем в клиентский код...

$controller = new My_Controller($context);
// ...
и в контроллере My_Controller:
PHP:
class My_Controller {
    public function foo()
    {
        echo $this->context->getRequest()->getParam('ID');
        // .....
Лично я не вижу особого смысла в таком объекте-контексте. С точки зрения гибкости сингелтоны тут будут куда более удачным решением.

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

флоппик

promotor fidei
Команда форума
Партнер клуба
Ты придумал Dependency Container. Если посмотреть неплохую реализацию в Symfony Components(http://components.symfony-project.org/dependency-injection/), или например, Phemto, то видно, что она как раз более гибкая, но синглтоны требуют меньше абстрагирующего синтаксиса, и в целом, быстрее в использовании (быстрее не в контексте производительности, а скорости разработки)
 

флоппик

promotor fidei
Команда форума
Партнер клуба
А мы это в чем обсуждаем, в практике?

Не надо задавать вопросы, на которые тебе не нужен ответ.
 

tz-lom

Продвинутый новичок
сейчас я использую статический класс в который вписываю инициализаторы для глобальных классов (а это роутер,база и шаблонизатор) , инициализация происходит при первом обращении и объект кладётся в этот синглет
однако есть мысль попробовать другой способ - наследовать класс от целевого допустим соединения,перегружая конструктор инициализацией класса и размещать его под таким же именем в другом пространстве имён,это уже больше похоже на dependency injection
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
вы считаете статический класс с конфигурационными параметрами плохим элементом архитектуры?
мне он удобен - выполняет функцию пространства имен для переменных

Вот в синглтонах смысла не вижу, особенно при работе с базой.
Не вижу ситуации, когда мне в случайном месте надо магически выудить из астрала объект с хендлером к базе, который сделает мне запрос.
Я довольно четко отделяю получение данных от их обработки.
 

Духовность™

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

вы считаете статический класс с конфигурационными параметрами плохим элементом архитектуры?
кто это класс заполняет и на каком этапе? и что он содержит? специфические методы типа setObject/getObject или это просто регистр?
 

tz-lom

Продвинутый новичок
tz-lom
я описался,там именно статический класс а не синглтон,а для базы вообще не синглтон а именно сохранённый инстанс ,причём в нём хранится только подключение к БД но ни как не данные
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
кто это класс заполняет и на каком этапе? и что он содержит? специфические методы типа setObject/getObject или это просто регистр?
заполняю я руками на этапе настройки сервера, некоторые параметры вычисляются на этапе инициализации приложения
содержит параметры системы, базы, общие настройки приложения, почты, пути, тип вызова, etc

http://pastebin.com/1jNbu87N

использование:
PHP:
try {
   	$DB = new DB();
}catch(gksException $E){
    _Config::DEBUG_MODE && print $E->getHtmlMessage();
}
 

Koc

Новичок
Ты придумал Dependency Container. Если посмотреть неплохую реализацию в Symfony Components(http://components.symfony-project.org/dependency-injection/), или например, Phemto, то видно, что она как раз более гибкая, но синглтоны требуют меньше абстрагирующего синтаксиса, и в целом, быстрее в использовании (быстрее не в контексте производительности, а скорости разработки)
ву-ха-ха, такой же контекст когда-то и я придумал, хотя на тот момент уже слышал о DI и IoC-контейнере от sf
http://www.php.ru/forum/viewtopic.php?t=26150&highlight=context
 

fixxxer

К.О.
Партнер клуба
Да все подряд его придумывали - вариация на тему $GLOBALS же.

Смысл DI/IoC в том, что зависимости определяются интерфейсами, а не чем-то там левым. Соответственно, доступно в конкретном классе только то, что явно объявлено и явно нужно, а не все что захочется - это важно. Плюс, и это не менее важно, всегда можно вместо использования инстанциирования через factory-метод контейнера установить все зависимости вручную, что важно для тестирования и запуска в специально подготовленной среде - например, при запусках крон-скриптов, разборах очередей итд. Вариации на тему globals в этом случае ничем не помогают, а только мешают.
 

Flyer

Новичок
Спасибо всем за ответы и наводку на паттерны. Остановился пока на регистре, пока освоюсь.

Но тут вылезла не приятная фигулина с IDE, столь горячо любимая мною автоподстановка перестала работать для моих звездных классов. =(

Те тут в примере мне IDE не предложит вариант someAction()
PHP:
Registry::set('Susanin',new SomeClass());		
Registry::get('Susanin')->someAction();
Уверен что многие столкнулись с этим, не поделитесь опытом? Работаю в Зенде, уверен там ребята не дураки, если патерны популярны то что то придумали.
 
Сверху