Я вижу совет от многих людей учить не использовать глобальная переменная / синглтон / статический класс и перейти к использованию контейнера iOC, например, в PHP Larvel Framework, это
App::bind('foo', function($app)
{
return new FooBar;
});
$value = App::make('foo');
вместо
$value = new FooBar;
Но для меня App::bind
сам по себе является статическим методом и не может быть легко заменен.
Итак, можно сказать, что iOC (по крайней мере, в PHP) просто удаляет количество жестко закодированных переменных и сводится к one
, который является сервисным локатором, и он не может быть далее уменьшен, верно?
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/
,
Говард, я думаю, что контекст, который ты можешь упустить, — это то, почему люди говорят
глобальная переменная / синглтон / статический класс
плохие». Причины, по которым вам не нужны глобальные переменные в вашем приложении, — это то, что полагаться на глобальное состояние может привести к боли. Когда вы изменяете значения, к которым другие части программы также имеют доступ, вероятно, две части программы получат доступ к той же самой переменной, и произойдут неожиданные «плохие» вещи. Синглтоны и статические классы часто смешиваются с глобальным состоянием, потому что они глобально доступны.
Так что да, ваш статус
просто удалить количество жестко закодированной переменной и свести к минимуму единицу, которая является локатором службы, и она не может быть дополнительно уменьшена, верно
является точным, но более того, контейнер сервисов (если сервисы создаются правильно) дает вам глобальный доступ к тому, что нужно делать, но затрудняет / делает невозможным использование этой глобальной вещи, которая делает -a-работа для хранения глобального состояния приложения.
Итак, могу ли я сказать, что iOC (по крайней мере, в PHP) просто удаляет количество жестко закодированных переменных и сводит их к единице, которая является локатором службы, и она не может быть дополнительно уменьшена, верно?
Вы видите это правильно, но вы можете уменьшить количество жестко закодированных переменных до 0.
Проблема здесь не в App::bind()
потому что это конфигурация. Конфигурация должна быть связана с какой-то системой, потому что именно здесь вы устанавливаете все детали. Здесь все в порядке.
Но имея App::make()
во всем вашей кодовой базе проблема. Вы хотите написать повторно используемый код. Например, вы не хотите, чтобы ваша модель была связана с Laravel. Факт вызов контейнера называется шаблон локатора службы (потому что вы находите службы с IoC).
Это анти-шаблон, потому что, как я уже сказал, вы связываете свой код с контейнером.
С другой стороны, есть схема внедрения зависимостей что лучше. Зависимости вводятся в ваших классах, но вам все равно, как. Это просто чистый PHP, полностью отделенный от любого контейнера.
Я приглашаю вас прочитать материал на эту тему, Laravel можно использовать с полным внедрением зависимостей (без статических вызовов фасадов). Вот статья на эту тему: Использование Dependency Injection и IoC в контроллерах Laravel 4