Приводит ли традиционное использование контроллера в MVC к нарушению принципа единой ответственности?

Википедия описывает принцип единой ответственности следующим образом:

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

Традиционное использование контроллера в MVC, похоже, приводит программиста к нарушению этого принципа. Возьмите простой контроллер гостевой книги и просмотрите. Контроллер может иметь два метода / действия: 1) Index () и 2) Submit (). Индекс () отображает форму. Submit () обрабатывает его. Представляют ли эти два метода две разные обязанности? Если да, то как здесь задействована единственная ответственность?


person Byron Sommardahl    schedule 22.04.2010    source источник


Ответы (2)


Да.

И если вы хотите следовать SRP, вы разделяете свой Контроллер на Диспетчер и Действия; Диспетчер отправляет управление своим действиям, и во время компиляции (шаблоны C ++) или во время выполнения (Java XML, что угодно) вы должны составить Диспетчеры и Действия.

Почему мы не видим это чаще? Поскольку контроллеры часто представляют собой «специальные» реализации, конкретные классы конечного уровня, которые не являются обобщенными и не предназначены для создания подклассов. Здесь класс используется в большей степени для удобной группировки кода, действия почти наверняка не являются общедоступными (вероятно, частными, возможно, защищенными), "просто" внутренними деталями реализации.

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

person tpdi    schedule 22.04.2010

Нет, это не так.

В шаблоне MVC или его вариациях нет ничего, что привело бы к нарушению принципа единой ответственности. Нарушает ли реализация контроллера SRP или нет, зависит от того, имеет ли инкапсулированное поведение более одной причины для изменения (как и любой другой класс), а не из-за какого-либо предполагаемого предписывающего использования шаблона.

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

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

Чтобы получить немного истории о шаблоне MVC, а также обсудить его применение в веб-разработке, ознакомьтесь с Шаблоны архитектуры интерактивных приложений.

person Derek Greer    schedule 23.05.2010
comment
Я согласен, это само по себе не нарушает шаблон MVC, но побуждает вас - где вы собираетесь разместить это новое действие, связанное с пользователем? Ну конечно в UserController. Довольно скоро он выходит из-под контроля и наполняется методами-действиями, которые не зависят друг от друга, но сгруппированы просто потому, что это удобно. Я начал обсуждение здесь, чтобы обсудить идею отказа от контроллеров и группировки действий вместо этого в пространства имен. - person mindplay.dk; 03.05.2013