Архітектура MVC - скільки контролерів мені потрібно?


54

Я кодую деякий час, але в основному сценарії та прості програми. Я перейшов до нової ролі, де йдеться про розробку веб-додатків та використання належної архітектури MVC, тому я відчайдушно намагаюся дізнатися про все це дуже швидко.

Я сподіваюся, що це питання не надто схоже на " Кращі практики для архітектури MVC ", але, переглядаючи декілька різних навчальних посібників, я помітив, що у деяких є кілька контролерів для різних речей.

Скільки контролерів потрібно одному веб-додатку?

Я усвідомлюю, що важко відповісти без прикладу, тому я надам:

Застосування:

  1. Користувач входить у систему.
  2. Користувач може зробити одне з трьох:
    а) Завантажити файл (зберігається в базі даних mongodb з метаданими).
    б) Пошук файлу.
    в) Вихід.

Моє запитання є загальним, але я наводив приклад, щоб допомогти кожному, хто намагається відповісти.


8
Дійсно красиво задане питання.
Даніель Холлінрак

Відповіді:


34

Для вашого прикладу я створив би два контролери:

  • Контролер сеансів для входу та виходу (створити та знищити сеанс для макета типу REST)
  • Контролер файлів для всього файлу (індекс = пошук і створення = завантаження)

Взагалі RESTful підхід, коли ви думаєте про все як про ресурс, який можна відображати, створювати, редагувати та знищувати, дає вам гарне уявлення про те, як структурувати речі. Як видно з моїх прикладів, я не дотримуюся занадто близько до кожного дієслова в REST.

Вам, швидше за все, знадобиться більше контролерів для подальшого функціонування. Наприклад, Контролер користувачів, де користувачі можуть створювати нові облікові записи. І крім цього вам знадобиться адміністраторський інтерфейс, де ви можете редагувати ресурси з більш високими привілеями. У такому випадку досить часто дублюється майже кожен контролер.

Дуже приблизною оцінкою для отримання початкової ідеї може бути один контролер для кожної таблиці вашої бази даних, до якої користувачі можуть отримати доступ. Але це насправді лише дуже грубе вимірювання.


3
Беручи приклад свого адміністратора: Чи розширив би контролер адміністратора загального користувача або повністю переробив усі методи? Наприклад, можливо, всі користувачі можуть завантажувати та шукати, але лише адміністратори можуть видаляти. Чи буде клас контролера адміністратора успадковувати всі загальні методи користувача?
Джефф

4
Це насправді дуже залежить від фактичної функціональності. Але загалом я просто записую другий контролер без будь-якого спадкування. Дотримуючись принципу "тонкого контролера", в будь-якому випадку не повинно бути багато коду в контролері. А адміністратор-контролер може бути особливо простим. Вся важлива функціональність йде в модель. (наприклад, якщо видалення користувача означає, що всі його файли також повинні бути видалені, тоді модель обробляє це, у контролері немає жодної рядки)
thorsten müller

6

Це дійсно залежить від веб-програми. У вашому прикладі одного, мабуть, достатньо. Якщо ви мали б застосувати повноцінний додаток для електронної комерції з доставкою, податком, управлінням запасами, багаторівневим ціноутворенням тощо, то ви просто можете мати ще пару.

Якщо ваш контролер страждає від одного або декількох запахів коду (особливо великого класу чи об'єкта бога ), то ви знаєте, що ви, ймовірно, минули точку, коли буде робити лише один.


5

Це дійсно залежить від ваших потреб у застосуванні та архітектури бізнес-модулів.

Загальне правило , кількість необхідних контролерів залежить від кількості модулів та підмодулів у веб-додатку.

Як доповнення, було б корисно організувати контролери в райони . Концепція областей вбудована в систему ASP.NET MVC і спрощує організацію контролерів, які обслуговують один модуль.

Існує ряд пов'язаних дискусій:


1
Чудові довідники! Я обов'язково їх перевіряю!
Джефф

А як же, немає проблем.
Е.Л. Юсубов

4

Мені подобається спосіб Apple зробити це.

Кожен огляд контролюється лише одним контролером перегляду. ~ Переглянути Посібник з програмування контролера для iOS

Ідея полягає в тому, що ви зможете легко замінювати погляди. ІМО, маючи лише 1 Controllerна Viewце, полегшує це. Але я впевнений, що у вас може бути контролер з декількома переглядами і все-таки його розробляти, щоб ви могли перемикати представлення даних, не змінюючи логіку програми.


Це хороший момент, але чи потрібно вам мати контролер для кожного перегляду плюс додаткові, щоб дбати про такі речі, як користувачі? Я також здогадуюсь, якби мій проект був більшим, було б більше сенсу мати більше контролерів.
Джефф

Моделі повинні відслідковувати користувачів. Таким чином, кілька контролерів можуть використовувати при необхідності всі об'єкти однієї моделі.
Корей Хінтон

2
Таким чином, у контролері є об'єкт Model та об'єкт View. Контролер запитує в об'єкта Model інформацію (наприклад, інформацію про користувача), а потім встановлює Перегляд відповідно. Модель повинна мати більшу частину програмної логіки, тоді як у Контролера просто є логіка, щоб мати можливість спілкуватися між Поглядом та Моделлю вперед і назад.
Корей Хінтон

2
Один контролер на огляд є дуже обмеженою конструкцією, оскільки ваш контролер не зможе відображати різні моделі перегляду для різних станів моделі.
Е.Л. Юсубов

1
@ElYusubov Я бачу, де це може бути заплутано. У iOS кожен огляд має лише один контролер перегляду, і кожен контролер перегляду має лише 1 активний вигляд (і цей перегляд може мати підпогляди), але цей контролер може також містити посилання на будь-яку кількість переглядів.
Корей Хінтон

2

Один із приклад, який мені подобається, - це думати про терморегулятор. Термостат є прекрасним зоровим оглядом для перегляду шаблону MVC.


На старшому аналоговому термостаті можна зобразити такі речі:

Перегляд - зчитувач температури, який відображає поточну температуру.

Контролер - циферблат, на якому ви змінюєте температуру

Модель - частини всередині, на які викликається контролер, які спричиняють зміну температури.


Ви завжди повинні дотримуватися конструкцій, які дозволяють вільно з'єднати і обмежувати моделі та пов'язані з ними контролери на одне завдання , і ви повинні використовувати стільки модулів / контролерів, скільки вам потрібно . Залежно від розміру вашої програми, у вас може бути набагато менше переглядів, ніж у моделей та контролерів. Цього можна очікувати при будь-якому застосуванні великих розмірів. Хороше об'єктно-орієнтоване програмування характеризується слабкою зв'язкою, інкапсуляцією, успадкуванням та поліморфізмом. Не всі мови підтримують поліморфізм в однаковій мірі (функція, метод, перевантаження / перезавантаження оператора).

Якщо ви хочете краще зрозуміти правильне використання архітектури MVC, зверніться до GoF "Шаблони дизайну: Елементи багаторазового використання ... Програмне забезпечення", яке використовує, наприклад, код C ++ та SmallTalk. Ця книга - це не альфа та омега, але це, безумовно, початок!

Удачі!


1

Я припускаю, що ваш приклад перетвориться на складну систему.

Застосування:

Користувачі входять у систему:

  • LoginController

Його виключна відповідальність - обробляти вхід, перенаправляти або повідомляти користувача про результат.

Завантажте файл

  • UploadController

Я припускаю, що ви хочете завантажити будь-який тип файлу. Якщо пізніше ви вирішите завантажити MP3 та PDF, тоді у мене будуть базові UploadController, MP3UploadController та PDFUploadController.

Пошук файлу.

  • SearchFileController

Цього було б достатньо для основної вимоги. Пізніше ви можете мати кілька контролерів пошуку, залежно від того, наскільки складна логіка пошуку. Останнє, що ви хочете мати, - це один SearchController з 20 методами дій, які виконують різні пошуки.

Вийти.

-LogoutController .

Можна вважати це зайвим, але я не думаю, що це так. Я думаю, що це чисто і гарно розділено.

Якби я дивився на цю структуру проекту, я б одразу зрозумів, що це робить і як вона структурована. Щоб зробити крок далі, я би поставив LoginControllerі LogoutControllerокрему область.

Я раніше щось подібне розробляв, і це спрацювало дуже добре.


Дякую за вклад! Є якийсь робочий код? зациклюватися на кількох речах.
Джефф

Які проблеми у вас виникають?
CodeART

Я можу завантажити тему та дату (у рядковому форматі), але не можу завантажити сам файл (див. Stackoverflow.com/questions/18344614/… ).
Джефф

Я розробник .NET. Вибачте, я не можу вам допомогти.
CodeART

1

Більшість вашого коду відбуватиметься у бізнес-шарі, чи не так? Якщо це так, то все, що ви дійсно робите у своєму контролері, - це повернення даних до перегляду.

Не дуже впевнений, чи я прихильник поділу контролерів на підтипи. Хоча вам слід дотримуватися роз'єднаності проблем, я думаю, що підтипи заходять занадто далеко. Також потрібно бути обережними у випадках, коли важкі предмети ініціалізуються в конструкторі чи контролері. Наприклад: у вашому прикладі ви хочете, щоб важкий об’єкт, який використовується лише для пошуку / завантаження файлу, буде випущений, коли користувач перебуває на сторінці входу.

Краще мати контролер на логічний блок, наприклад AccountController (вхід, реєстрація, вихід), FileController (пошук, завантаження) тощо.


0

Взагалі ви можете сказати, що кожна МОДЕЛЬ має власні КОНТРОЛЕРИ та виділені ПОЗИЦІ. Кажучи загальним, я маю на увазі, що це найкраща практика.

Аспекти програми (наприклад, управління користувачем) повинні бути переведені в службу додатків, і їх потрібно викликати самим контролером або обернути контролер (використовуючи атрибути, які роблять функціональність контролера "видимим" відповідно до ролі запиту користувача).

Пам’ятайте, що всі контролери в основному повинні керувати операціями CRUD над моделлю та використовувати різні види для різних фільтрів.

На мою думку, однією з головних переваг MVC як візерунка є те, що він забезпечує найкращий спосіб прив’язати моделі та види.

Про доданий вами приклад: я створив би 2 контролера: один для всіх операцій входу користувача (реєстрація, вхід, вихід тощо) та другий для операцій з файлами (Завантаження та пошук). зауважте, що перший також має бути підкріплений певним аспектом, пов'язаним з функцією входу, а другий - звичайним контролером


без пояснення ця відповідь може стати марною у випадку, якщо хтось інший висловить протилежну думку. Наприклад, якщо хтось опублікував претензію на кшталт "Керування ролями користувачів та авторизація не повинно бути над контролером" , як ця відповідь допоможе читачеві вибрати дві протилежні думки? Подумайте про те, щоб відредагувати його у кращій формі
гнат

1
@gnat Я приймаю ваш коментар, дивіться відредаговану відповідь
Saturn Technologies
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.