Почему обычные PHP-фреймворки используют центральное ядро? - PullRequest
7 голосов
/ 27 декабря 2010

Это просто удобно или есть другие цели иметь основное центральное ядро?

Почему они делают

    $core->A->do();
    $core->B->do();

вместо

    $A->do();
    $B->do();

И оставляют все это классам для удовлетворения их потребностей?Кроме того, не будет большого объекта, как только мы загрузим в него разные классы.

Чтобы решить реальную проблему: я в настоящее время использую паттерн Dependency Injection, чтобы дать классам то, что им нужно, ноЯ также спрашиваю себя, не будет ли лучше, если бы все классы могли иметь доступ к ресурсам (например, к конфигам), не вызывая ядро ​​каждый раз, когда им это нужно.1014 *MyClass

    $myclass->get_configs();    // get my configs
    $myclass->do_stuff($this->my_configs);    // use them

вместо этого

MyCore

    $myclass_configs = $this->config->get('configs_for_myclass');    // get configs
    $this->myclass = new MyClass($myclass_configs);    // call the function and give it the configs

Не будетэто позволяет избежать необходимости большого ядра, а также децентрализовать все?Или это просто чертовски тяжелая мастурбация ума?

Редактировать: исправлена ​​опечатка.

Ответы [ 3 ]

6 голосов
/ 21 января 2011

Я владелец и управляющий Alloy HMVC Framework , и я выбрал базовый объект "Ядро", как вы описываете, по нескольким основным причинам:

Это полезно какФабрика

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

Пользователи предпочитают писать:

$router = $kernel->router();

Чем-то вроде:

$router = new SomeFramework\Http\Router(new SomeFramework\Http\Request());

Или:

$router = SomeFramework\Http\Router::getInstance();

Управление экземплярами

Центральный объект ядра также может гарантировать, что объекты не получатсоздается несколько раз, когда это не нужно.Обычно для таких объектов, как Request, Response, Router, Session и т. Д., Необязательно иметь несколько экземпляров.

Поэтому вызов для извлечения экземпляра Request выглядит следующим образом:

$request = $kernel->request();

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

Упрощает обработку зависимостей

Aцентральное ядро ​​или объект ядра также могут быть полезны для упрощения обработки зависимостей в самой структуре (использование в качестве локатора служб).Вместо того, чтобы заранее знать взаимозависимости объектов, вы просто передаете основной объект и знаете, что все необходимое можно извлечь непосредственно из него.Это особенно полезно в средах, потому что вы никогда не знаете, что пользователи захотят делать в своих контроллерах.Вы просто предоставляете им центральный основной объект, и они могут извлечь из него все, что им нужно.Стоит сказать, что этот подход к стилю локатора сервиса сопровождается известным предостережением о создании зависимостей от самого локатора сервиса всеми объектами, которые его используют.Недостатком является компромисс, с которым вы можете или не хотите жить, но он значительно упрощает код на уровне пользователя, поэтому я выбрал его.

Обеспечивает центральную точку расширения

Oneиз того, что центральный объект существует и может передаваться везде (и доступен в любом контроллере), является то, что он обеспечивает естественную общую точку расширения.Alloy позволяет пользователям добавлять свои собственные методы к объекту ядра, которые проксируются с помощью магической функции __call:

$kernel->addMethod('bark', function() { echo 'Woof!'; });

, которая позволяет использовать его в любом месте приложения, в котором доступно ядро:

$kernel->bark(); // echos 'Woof!'

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

Относительно конфигурации класса

Относительно вашего вопроса о том, почему вы не хотите этого делать:

$myclass->get_configs();    // get my configs
$myclass->do_stuff($this->my_configs);    // use them

Вместо этого:

$myclass_configs = $this->config->get('configs_for_myclass');    // get configs
$this->myclass = new MyClass($myclass_configs);    // call the function and give it the config

Это из-задве основные причины:

(1) Повторяющаяся функциональность во всех классах для get_config.Чтобы код оставался СУХИМЫМ, вам пришлось бы в конечном итоге сделать все ваши классы производными от общего базового класса, что, скорее всего, представляло бы собой злоупотребление наследованием и углубило бы вашу иерархию классов.

(2) Когда вы создаете несколько методовпри вызове объекта было бы утомительно и некрасиво каждый раз передавать конфиги, например:

$myclass->do_stuff($this->my_configs);
$myclass->do_other_stuff($this->my_configs);
$myclass->do_more_stuff($this->my_configs);

Намного приятнее создать экземпляр объекта с конфигурацией один раз:

$myclass = new MyClass($myclass_configs);
$myclass->do_stuff();
$myclass->do_other_stuff();
$myclass->do_more_stuff();

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

3 голосов
/ 27 декабря 2010

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

1 голос
/ 27 декабря 2010

Я думаю, что отчасти причина в том, что если вы делаете $ core-> A, а не $ A, то $ core-> A может быть загружен с отложенной загрузкой только при запросе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...