Контейнер IoC и глобальная переменная

Я вижу совет от многих людей учить не использовать глобальная переменная / синглтон / статический класс и перейти к использованию контейнера iOC, например, в PHP Larvel Framework, это

App::bind('foo', function($app)
{
return new FooBar;
});

$value = App::make('foo');

вместо

$value = new FooBar;

Но для меня App::bind сам по себе является статическим методом и не может быть легко заменен.

Итак, можно сказать, что iOC (по крайней мере, в PHP) просто удаляет количество жестко закодированных переменных и сводится к one, который является сервисным локатором, и он не может быть далее уменьшен, верно?

2

Решение

App::bind это не статический метод, это его подпись:

public function bind($abstract, $concrete = null, $shared = false)

(нашел в /vendor/laravel/framework/src/Illuminate/Container/Container.php)

Laravel использует Фасады, которые, в то время как они выглядят так, как будто они вызывают метод статически, фактически создают экземпляр объекта под капотом, а затем вызывают метод экземпляра для этого объекта. В то время как Laravel действительно использует немного статические методы в своих моделях, App Сам объект на самом деле является фасадом. Вы можете увидеть список встроенных фасадов, если вы посмотрите в /vendor/laravel/framework/src/Illuminate/Support/Facades/,

2

Другие решения

Говард, я думаю, что контекст, который ты можешь упустить, — это то, почему люди говорят

глобальная переменная / синглтон / статический класс

плохие». Причины, по которым вам не нужны глобальные переменные в вашем приложении, — это то, что полагаться на глобальное состояние может привести к боли. Когда вы изменяете значения, к которым другие части программы также имеют доступ, вероятно, две части программы получат доступ к той же самой переменной, и произойдут неожиданные «плохие» вещи. Синглтоны и статические классы часто смешиваются с глобальным состоянием, потому что они глобально доступны.

Так что да, ваш статус

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

является точным, но более того, контейнер сервисов (если сервисы создаются правильно) дает вам глобальный доступ к тому, что нужно делать, но затрудняет / делает невозможным использование этой глобальной вещи, которая делает -a-работа для хранения глобального состояния приложения.

1

Итак, могу ли я сказать, что iOC (по крайней мере, в PHP) просто удаляет количество жестко закодированных переменных и сводит их к единице, которая является локатором службы, и она не может быть дополнительно уменьшена, верно?

Вы видите это правильно, но вы можете уменьшить количество жестко закодированных переменных до 0.

Проблема здесь не в App::bind() потому что это конфигурация. Конфигурация должна быть связана с какой-то системой, потому что именно здесь вы устанавливаете все детали. Здесь все в порядке.

Но имея App::make() во всем вашей кодовой базе проблема. Вы хотите написать повторно используемый код. Например, вы не хотите, чтобы ваша модель была связана с Laravel. Факт вызов контейнера называется шаблон локатора службы (потому что вы находите службы с IoC).

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

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

Я приглашаю вас прочитать материал на эту тему, Laravel можно использовать с полным внедрением зависимостей (без статических вызовов фасадов). Вот статья на эту тему: Использование Dependency Injection и IoC в контроллерах Laravel 4

1
По вопросам рекламы [email protected]