Создание Класса контроллера с Внедрением зависимости в PHP

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

  • легко тестируемый путем использования Внедрения зависимости,
  • предоставьте общие объекты программисту конца
  • позвольте загружать новые пользовательские библиотеки

Посмотрите вниз для инстанцирования контроллера с платформой Внедрения зависимости


Проблема, который произошел, Контроллеры могут использовать любые ресурсы, которые программист хочет к (например, платформа обеспечивает). Как создать единый доступ к совместно используемым ресурсам (DB, Пользователь, устройство хранения данных, Кэш, Помощники), определяемые пользователем Классы или другой библиотеки?

Изящное решение?

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

  • Попытаться передать все общие объекты конструктором? (может создать конструктора даже с 10 заполнителями),
  • Создать методы считывания, методы set? (чрезмерно увеличенный в размерах код) $controller->setApplication($app)
  • Применить одиночные элементы на совместно используемые ресурсы? User::getInstance() или Database::getInstance()
  • Используйте контейнер Внедрения зависимости в качестве одиночного элемента для совместного использования объекта в контроллере?
  • обеспечить один глобальный одиночный элемент приложения как фабрику? (эти взгляды, очень используемые в php платформах, hovewer это, идет сильно против принципов DI и закона Demeter),

Я понимаю, тому созданию решительно двойных классов препятствуют и высылают для :), однако я не знаю, как эта парадигма относится к начальной точке за других программистов (Класс контроллера), в котором они должны смочь получить доступ к совместно используемым ресурсам, предоставленным архитектуре MVC. Я полагаю, что разбивание класса контроллера в меньшие классы так или иначе уничтожило бы практическое значение MVC.


Платформа внедрения зависимости

Платформа DI похожа на жизнеспособный выбор. Однако проблема все еще сохраняется. Класс как Контроллер не находится на Прикладном уровне, но на уровне RequestHandler/Response.

Как этот слой должен инстанцировать контроллера?

  • передать инжектор DI на этот слой?
  • Платформа DI как одиночный элемент?
  • поместите изолировал конфигурацию платформы DI только для этого слоя, и создайте отдельный экземпляр инжектора DI?
20
задан 18 revs 14 February 2010 в 18:51
поделиться

3 ответа

Вы сами разрабатываете фреймворк? В противном случае ваш вопрос неприменим, потому что вам нужно выбрать из уже существующих фреймворков и их существующих решений. В этом случае ваш вопрос должен быть переформулирован как «как выполнить модульное тестирование / внедрение зависимостей в фреймворке X».

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

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

Синглтоны - изящное решение, но опять же, вы должны спросить себя, применимо ли оно в вашем случае? Если вам нужно иметь разные экземпляры одного и того же типа объекта в вашем приложении, вы не можете использовать его (например, если вы хотите имитировать класс только в половине вашего приложения).

Конечно, иметь все возможности - это здорово. У вас могут быть геттеры / сеттеры, конструкторы, и когда инициализация опущена, значения по умолчанию берутся из одноэлементной фабрики.Но иметь слишком много опций, когда они не нужны, - это не здорово, это беспокоит, поскольку программист должен выяснить, какое соглашение, вариант и шаблон использовать. Я определенно не хочу принимать десятки дизайнерских решений только для того, чтобы запустить простой CRUD.

Если вы посмотрите на другие фреймворки, вы увидите, что серебряной пули нет. Часто одна структура использует разные методы в зависимости от контекста. В контроллерах DI - это действительно простая вещь, посмотрите на $ helpers, $ components переменные CakePHP, которые предписывают вводить соответствующие переменные в класс контроллера. Для самого приложения синглтон по-прежнему хорошо, так как всегда есть только одно приложение. Реже изменяемые / имитируемые свойства вводятся с использованием общедоступных свойств. В случае MVC создание подклассов также является вполне жизнеспособным вариантом: так же, как AppController, AppView, AppModel в CakePHP. Они вставляются в иерархию классов между фреймворками и всеми вашими конкретными классами Controller, View и Model. Таким образом, у вас есть единственная точка для объявления глобальных объектов для вашего основного типа классов.

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

Вы можете ответить на вопрос, что подходит именно вам, только если вы знаете то, что вам нужно в первую очередь.Но на самом деле, почему вы все равно пишете просто еще один новый фреймворк?

3
ответ дан 30 November 2019 в 01:34
поделиться

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

Скорее всего, у вас будет контроль над созданием экземпляров контроллеров, поэтому вы можете обойтись упомянутым $ controller-> setApplication ($ application) , но при необходимости вы можете использовать статические методы и переменные ( которые гораздо менее вредны для ортогональности приложения, чем синглтоны); а именно Controller :: setApplication () , и получить доступ к статическим переменным через методы экземпляра.

например:

// defining the Application within the controller -- more than likely in the bootstrap
$application = new Application();
Controller::setApplication($application);

// somewhere within the Controller class definition
public function setContentType($contentType)
{
    self::$application->setContentType($contentType);
}

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

1
ответ дан 30 November 2019 в 01:34
поделиться

Вопрос в том, когда вы хотите, чтобы сошли с вашего пути , чтобы сделать это?

Если вы развертываете webapp, и он НЕМЕДЛЕННО в прямом эфире, то, пока вы «согреваете» его, вы добавляете дополнительную нагрузку, что контрпродуктивно. Подобное справедливо и при запуске настольного приложения. Нет смысла греть, если пользователь собирается немедленно начать использовать его. Или, что еще хуже, не позволяет пользователю взаимодействовать во время разогрева приложения.

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

-121--3815186-

В этой командной строке имеются неправильные кавычки. Самое простое, вероятно, это:

du -h file_size.txt | cut -f -1

Исправить вашу командную строку:

du -h file_size.txt | sed 's/file_size.txt//'

Так как ваш пост имеет awk тэгов:

du -h file_size.txt | awk '{ print $1 }'
-121--238844-

Как насчет рефакторинга ?

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

1
ответ дан 30 November 2019 в 01:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: