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