Почему все помещают контроллеры в одну папку, а представления в другую?

36

Я собираюсь взять изгиб asp и в инфраструктуру MVC, Asp.net MVC или Нэнси. Куда бы я ни пошел, я вижу папки для контроллеров / модулей и папки для представлений. Является ли это просто рефлексом Павлова, приводящим вещи в порядок по типу, или действует какая-то более глубокая мудрость? У меня есть небольшой проект для проверки концепции, в котором я храню вместе файлы, которые я могу открыть вместе, что очень удобно. Поскольку эти файлы также могут вызывать друг друга, они могут делать это с помощью более коротких, менее хрупких, относительных ссылок. Этот шаблон оспаривается mvc, поскольку путь к папке больше не соответствует автоматически URL-пути, а в asp.net mvc шаблоны проектов и маршрутизация применяют views \ controllers \ schism.

На этой странице Microsoft вводится понятие областей. Это можно прочитать как признание того, насколько громоздкими становятся большие приложения из-за этого искусственного разделения.

Люди будут возражать против «разделения интересов», но разделение интересов уже достигается благодаря наличию отдельных исходных файлов. Мне кажется, что нет никакой конкретной выгоды от того, что вы берете эти тесно связанные исходные файлы и отправляете их на противоположные стороны структуры папок?

Кто-нибудь еще борется с этим? Какие-нибудь советы?

bbsimonbb
источник
3
Вы не думаете, что логично отделять файлы внутреннего кода от файлов просмотра? Если мы уже выбираем направление, почему бы не поместить соответствующие файлы CSS и JavaScript в одну и ту же папку?
Alternatex
2
Если вы получите Resharper, то F12 при вызове Viewв контроллере приведет вас к представлению, а первая опция в меню правой кнопки мыши на представлении приведет вас к контроллеру, и вся проблема с отсутствием навигации исчезнет.
Пит Киркхэм,
4
@Alternatex Я извиняюсь, но я не вижу, как контроллер является "back-end". Он тесно связан с его представлениями. Без контроллера вид бесполезен, без вида контроллер бесполезен. Однажды вы захотите удалить их вместе. Что для меня является лучшим тестом того, что принадлежит вместе в папке ?? Разве кто-то может показать мне лучший способ?
bbsimonbb
2
Представления представляют собой слой представления. Контроллеры - это слой, который содержит сервисы, которые могут содержать объекты из вашего домена, которые содержат вашу бизнес-логику и, следовательно, содержат внутреннюю логику вашего приложения. Представления состоят только из простых условных выражений и простых циклов для итерации по коллекциям. Если ваши представления содержат что-то еще, вы делаете это неправильно. Как и в случае с обычной структурой, вы разделили внутренний и внешний интерфейсы, что для меня является лучшей структурой, чем та, которую вы предлагаете.
Энди
10
Так что нет недостатка в людях, чтобы сказать мне, что контроллер - это посуда, так что он помещается в кухонный шкаф. Виды - это очки, поэтому они идут в стеклянный шкаф. Я знаю, что контроллер - это посуда, но я предлагаю, чтобы было здорово иметь обеденный шкаф и обеденный шкаф, поскольку мы говорим о вещах, которые используются только во время обеда или ужина.
bbsimonbb

Ответы:

38

Я хотел бы сказать, что это программирование культа грузов , но для этой структуры есть технические причины. Asp.Net MVC придерживался соглашения о конфигурации подходов почти ко всему. По умолчанию механизм представления Razor выполняет поиск в Viewsкаталоге, чтобы определить, какое представление следует вернуть из контроллера. Однако есть несколько способов получить другую структуру проекта, и Microsoft даже предоставляет функцию MVC под названием Areas, которая позволяет нам создавать более разумную структуру проекта. Вы также можете реализовать свой собственный механизм просмотра , чтобы указать, где искать представления.

Почему я говорю, что это программирование культа грузов и вы правы? Дядя Боб убедил меня, что структура каталогов проекта не должна говорить мне, что это приложение MVC. Это должно сказать мне, что это витрина магазина, или система запроса времени, или что-то еще. Структура и архитектура высокого уровня должны рассказать нам о том, что это за штука, а не о том , как она реализована.

Короче говоря, я верю, что вы правы в этом, но любая другая структура каталогов будет просто бороться с фреймворком, и поверьте мне, когда я говорю, что вы не хотите пытаться заставить фреймворк Asp.Net MVC делать то, чего не было не предназначен для этого. Жаль, что это не более настраиваемый на самом деле.


Чтобы быстро решить архитектурные проблемы, я по-прежнему считаю, что бизнес-модели (бизнес, а не представление) и DAL должны находиться в отдельном проекте / библиотеке, которая вызывается из вашего приложения MVC.

Просто контроллер действительно очень тесно связан с видом и может быть изменен вместе. Мы все должны помнить разницу между связью через зависимость и логической связью. Только то, что у кода были развязаны зависимости, не делает его менее логически связанным.

Резиновая утка
источник
1
Комплексный способ контроля, где бритва ищет взгляды, здесь . Я мог бы просто продолжать
bbsimonbb
3
Я смотрел, как дядя Боб, в x1.25, как и предполагалось. Это заставляет меня задуматься о том, что если бы ИТ-архитекторы строили здания, мы все жили бы на маленьких плотах, связанных вместе, плавая на озере. Жизнь не обязательно будет проще.
bbsimonbb
1
Это немного сложнее. Чтобы действительно совмещать контроллеры и представления, вам нужно разрешить путь представления во время выполнения, чтобы включить пространство имен контроллера. Вот как это сделать .
bbsimonbb
1
Также взгляните на функционально-ориентированную разработку программного обеспечения ( fosd.net ), для академического аналога тому, что описывает дядя Боб.
нгм
1
Закон Конвея на работе. Я уверен, что это работает в вашей компании @Flater. Стандартная схема MVC работает во многих компаниях, но я все же предпочитаю группировать вещи по семантике, а не по синтаксису. Компании, в которых я работаю, были организованы вокруг продуктов вместо ролей / рабочих функций. Я считаю, что это корень моих предпочтений здесь.
RubberDuck
9

Какой бы ни была причина, это плохая практика. Это очень анти-OO, потому что пакеты или папки (как вы хотите их называть) должны иметь слабые взаимозависимости. Классы (или файлы) внутри них должны иметь сильные взаимозависимости.

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

Представление и контроллер - это две половины целого и должны принадлежать друг другу. У вас не будет одного шкафа для носков с левой стороны и другого - для носков с правой стороны.

Оливер Уоткинс
источник
6

Чтобы ответить на ваш вопрос «Почему все ...?» вопрос: вот некоторые потенциальные причины, хотя я не совсем уверен, какая из них является реальной причиной, поскольку это на самом деле субъективный вопрос

  • Для репликации логической архитектуры (модель, представление, контроллер) с соответствующей папкой и структурой пространства имен

  • Из соглашения и удобства следуйте шаблону проекта ASP.net MVC

  • Группировать по пространству имен, так как Controllers/папка приведет к .Controllersпространству имен

  • Возможно включение некоторых сценариев в DI / IoC, где классы контроллера запрашиваются / сканируются только из пространства имен, которое содержит / заканчивается «Контроллерами» (это может быть неправильно)

  • Чтобы позволить шаблонам T4 сканировать и создавать модели и контроллеры для создания представлений

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

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

Bishoy
источник
2

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

Другая причина состоит в том, чтобы упростить создание «тем» и отключить все шаблоны, внеся незначительные изменения в путь просмотра.

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

Единственное «жесткое соединение» должно быть:

  1. Переменные, отправленные в представление контроллером.
  2. Формы полей или действий в представлении отправляются обратно в контроллер.

Я использую универсальный контроллер и пытаюсь сохранить имена переменных в общем представлении, чтобы многие представления могли использовать один и тот же контроллер, а многие контроллеры могли использовать одно и то же представление. По этой причине я предпочитаю держать взгляды совершенно отдельно. Модель - это место, где вы можете различать каждую «вещь» в вашем приложении - это могут быть объекты со списком свойств и методов для доступа / изменения этих свойств.

Для тесно связанного кода подход, который может работать для вас, заключается в хранении всех файлов, которые являются частью пакета или «модуля», вместе в каталоге пространства имен. Затем вы можете использовать скрипт для копирования или «компиляции» ваших необработанных шаблонов в основной каталог «views». Например:


    lib/my-namespace/my-package/
        -> controllers/
        -> models/
        -> views/
            -> theme/
               -> template-name1
    app/compiled_views/theme/
        -> url/path/template-name1

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

Учтите, что представления - это просто способ форматирования данных, будь то json, xml, csv или html. Это особенно помогает, если вы хотите, чтобы ваше приложение также работало как API. Попробуйте отделить представление от данных, используя общие имена переменных, чтобы вы могли использовать один и тот же шаблон для многих контроллеров или моделей (или использовать include, чтобы минимизировать объем кода, который необходимо поддерживать).

Фрэнк Форте
источник
1

Не обязательно все это делают. Например, среда Python Django имеет концепцию приложения, где подмодули вашего приложения живут в своих собственных каталогах со своими собственными моделями, представлениями и шаблонами (представления - это то, что Django называет контроллерами по сути). Я предпочитаю такой способ работы, потому что это означает, что я могу легко упаковать «приложение» и повторно использовать его в разных проектах, просто включив его в список приложений в настройках моих проектов. Также легче узнать, где находятся разные детали. Если я посмотрю на файл urls.py и увижу что-то вроде этого url(r'^users/', include('my_site.users.urls')), я знаю, что модуль my_site.usersсодержит весь код, который обрабатывает пользователей. Я знаю, чтобы посмотреть на модули my_site.users.viewsи my_site.users.modelsкогда я хочу увидеть, как пользователи создаются и проходят проверку подлинности. Я знаю, что все мои маршруты определены в my_site.users.url.

Также, если он достаточно универсален, я, вероятно, смогу использовать этот модуль на других сайтах, просто изменив конфигурацию или упакуя его в виде библиотеки и опубликовав его как OSS.

Павел Пенев
источник
1

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

  1. Одной из причин может быть то, что контроллеры всегда не имеют отношения один к одному с представлениями, особенно частичные представления могут совместно использоваться контроллерами.
  2. Другая причина может заключаться в том, что когда ваш проект расширяется, вы можете захотеть перенести контроллеры и модульные тесты в другой проект (ы), но довольно сложно сделать то же самое для представлений плюс представления / js / css, соединенные вместе, так как они ссылаются друг на друга.

Сказав, что есть много сообщений о том, как делать это по-своему, например, это .

Низко летящий пеликан
источник
«Это рекомендованный Microsoft способ» ... Можете ли вы уточнить, что вы подразумеваете под этим? Есть ли настоящая, авторитетная статья MS об этом? Или это просто настройка проекта по умолчанию для приложения MVC? И, если вы основываете это на последнем, разве не возможно, что настройка проекта MVC по умолчанию является такой, какой она есть, потому что именно так все это делают?
svidgen
1
Основываясь на статье msdn.microsoft.com/en-us/library/… там написано: «Контроллеры, что рекомендуется» и т. Д. Для представлений и т. Д.
Low Flying Pelican
0

Для записи

Почему я говорю, что это программирование культа грузов и вы правы? Дядя Боб убедил меня, что структура каталогов проекта не должна говорить мне, что это приложение MVC. Это должно сказать мне, что это витрина магазина, или система запроса времени, или что-то еще. Структура и архитектура высокого уровня должны рассказать нам о том, что это за штука, а не о том, как она реализована.

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

Попытка подражать поведению проекта (витрина магазина) - культ груза.

Магеллана
источник
3
Когда я пишу код, меня больше всего интересуют функции, а не типы. Когда я вижу, что функция не работает должным образом, я знаю, что что-то не так в коде, связанном с этой функцией, хотя я не обязательно знаю, какой это тип кода.
Прекратить причинять вред Монике
1
«Скажем, командный проект, один отвечает за контроллер, другой - за модель, другой - за дао». Такая команда будет испытывать трудности с доставкой чего-либо, и когда они это сделают, это будет стоить гораздо больше в связи с накладными расходами и ошибками.
RubberDuck
Как установлено в цепочке комментариев под принятым ответом, вы получаете точку, но только в определенных случаях. Когда компания сосредотачивается на проектах MVC, которые она продает многим различным клиентам, сохранение структуры MVC имеет смысл для повторного использования. Когда компания фокусируется на нише (например, интернет-магазины) и, возможно, использует много разных технологий, имеет больше смысла иметь структуру, ориентированную на интернет-магазин. Это практическое применение закона Конвея . Код (а следовательно, и структура проекта) должен соответствовать структуре компании.
Флэтер
@RubberDuck: Вы можете аргументировать добавленную стоимость в любом случае. Вы правы в том, что когда разные люди выполняют разные технические компоненты, вы усиливаете коммуникацию бизнес-логики. Однако, если у вас есть разные люди, которые полностью реализуют разные функции, то вы можете увеличить расходы на то, чтобы все были в курсе (опытный + согласный) с использованием одного и того же технического подхода. В любом случае, вам нужно общение, чтобы люди работали вместе.
Флэтер
Да, и передача обслуживания всегда стоит дороже, чем одна пара разработчиков, реализующих функцию сквозного IME.
RubberDuck