Задать вопрос

Частое нарушение идеологии, в частности в Laravel или так и должно быть?

Приходится записывать из контроллера в модель ему не принадлежащие данные, а еще чаще выводить их. И происходит так часто , если это не просто АПИ , а именно работа с шаблонизатором и формами. То есть из формы приходит в Контроллер A выбранный B.A_id , например в ипнуте,
<select name="B_id" required class="form-control">
   @foreach($Bb as $b)
      <option  value="{{$b->id}}">{{$b->name}}</option>
   @endforeach
</select>
кстати он был получен тоже из контроллера A и выведен в view A(как иначе , то я же не json для SPA запрашиваю по апи) и успешно записывается в laravel к примеру вот так : $B_in_Actrl =new B()....
Если влом читать выше
//cotroller A
use B model;
use A model;
class AController extends Controller
somelistAandBinActrl  function (){
B::all();
A::all();
}
createAandBinActrl function(){
$a = new a();
$b_in_a=new b()
}

Использовать модель B в контроллере A, это норма?или 1m=1c?тогда как болтать меж собой контроллерам?
Так вот , это жестокое нарушение идеологии MVC? и как с ней бороться? есть ли статьи/практики/код стайлы в таких случаях контексте laravel или даже любого другого фреймворка такого рода.
  • Вопрос задан
  • 2091 просмотр
Подписаться 3 Оценить 19 комментариев
Решения вопроса 2
AmdY
@AmdY
PHP и прочие вебштучки
В MVC нигде не сказано, что должен быть один контроллер, одна модель или одна вьюха. Говорится только о разделение на слои по функциональным признакам. Даже самих видов слоёв может быть больше чем три. Никакого нарушения здесь нет.
Ответ написан
Комментировать
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
CleanArchitecture-81565aba46f035911a5018
Использовать модель B в контроллере A, это норма?или 1m=1c?тогда как болтать меж собой контроллерам?


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

Давайте попробуем упростить эту картинку до MVC в самом простом его виде (я про ту шту. В этом случае слой Use Cases (Application layer или операционный уровень у Эванса) сольется с контроллерами. У нас будет по экшену контроллера на каждый юз кейс который выполняет приложение. Это как бы плохо, так как контроллеры перестают выполнять обязанность быть адаптерами к интерфейсу, но если интерфейс у нас один и только один - проблемы нет.

Далее, разбираемся что есть модель - модель это совокупность всех бизнес правил и бизнес объектов, где бизнес правила это сервисы уровня модели, а бизнес объекты это наши сущности или... модели в контексте AR. Согласитесь, это нормальное явление когда в рамках какого-то юз кейса мы оперируем несколькими моделями. То что у вас половина сущностей названа как контроллеры - это только потому что того требуют ваши кейсы, они так и называются - зарегистрировать пользователя, авторизовать пользователя, добавить друзей.... Юз кейсы определяют флоу работы системы.

Так что да, это более чем нормально в рамках серверной интерпритации MVC работать с бизнес сущностями A и B в контроллере C.

А теперь попробуем наладить дела. Про Application layer мы уже говорили, давайте все юз кейсы вернем туда. То есть наш контроллер будет забирать данные из реквеста, преобразовывать в тот формат который кушают наши сервисы из application layer и дергать их. Ну и затем контроллеру так же придется сформировать результат работы этих сервисов в тот формат, которого требует интерфейс. И вот у нас уже с бизнес сущностями A и B работает сервис C, а контроллер всего лишь просит что-то делать и занимается переводом. Так когда мы захотим к WEB добавить REST то нам просто надо будет дописать контроллеры и не трогать логику.

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

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

Войдите, чтобы написать ответ

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