Бизнес логика в MVC [закрыто]


184

У меня есть 2 вопроса:

Q1. Где именно лежит «бизнес-логика» в паттерне MVC? Я запутался между моделью и контроллером.

Q2. Является ли «бизнес-логика» такой же, как «бизнес-правила»? Если нет, то в чем разница?

Было бы здорово, если бы вы могли объяснить небольшой пример.

Ответы:


173

Деловые правила идут в модели.

Скажем, вы отображали электронные письма для списка рассылки. Пользователь нажимает кнопку «удалить» рядом с одним из электронных писем, контроллер уведомляет модель об удалении записи N, а затем уведомляет представление об изменении модели.

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

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


5
Спасибо за пример. Для записи электронной почты администратора (контролирующей, может ли она быть удалена или нет), можем ли мы не контролировать это с помощью нашего контроллера?
Хмтур

2
@mud, что, если мы разделим нашу модель на еще два уровня, то есть уровень обслуживания и хранилище ... уровень обслуживания отвечает за бизнес-логику, а хранилище отвечает за уровень данных ...?
Дракон

3
@PeterMatisko "Модели должны нести только данные." Вы не понимаете, что М означает в «MVC». V чисто презентация. C является связующим звеном между представлением и моделью. (На самом деле, «VC» часто рассматривают вместе как уровень представления, а популярные варианты MVC, такие как MVVM - модель представления представления - делают это еще яснее.) М - это все остальное : все данные и логика вашего приложения. Вы можете разделить данные и бизнес-логику в этом слое, и вы можете назвать часть данных этого слоя своей «моделью», но это не то, что означает «M» в «MVC».
грязь

1
@PeterMatisko "в laravel люди тогда бросают все в контроллеры или модели. Плохая плохая архитектура." Плохо как ? Быть конкретной. «V» означает «вид». Все, что не является видом, обязательно идет в «М» или «С». «MVC просто недостаточно, он не говорит явно о бизнес-логике и о том, где ее разместить». Конечно, это так. «М» - это модель вашего приложения, которая представляет собой ваши данные, бизнес-логику вокруг них и все, что не является презентацией. «V» и «C» - уровень представления, пользовательский ввод и вывод.
Грязь

2
Проблема в том, что Laravel называет «Модель» просто носителем данных. Когда в учебниках говорится, что Laravel использует MVC, а затем вы видите, что «Модель» имеет очень конкретную цель, вы не понимаете, куда поместить бизнес-логику. И единственное разумное место - это контроллер, что нехорошо. Я не придумываю это, я просто прокомментировал типичные проекты Laravel (и учебные пособия), которые я часто вижу.
Петр Матиско

191

Кулак всего:
Я считаю , что вы путаете шаблон MVC и принципы проектирования многоуровневых на базе.

Использование подхода MVC не означает, что вы не должны разбивать свое приложение на слои.
Это может помочь, если вы видите MVC больше похожим на расширение уровня представления.

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

Просто взгляните на это: статья в Википедии о многоуровневой архитектуре

.

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

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

Это связано с тем, что контроллер фактически обрабатывает вызовы к конкретному ресурсу, запрашивает данные, вызывая бизнес-логику, и связывает данные (модель) с соответствующим представлением.

Грязь сказала, что бизнес-правила входят в модель.
Это также верно, но он перепутал (презентационную) модель («M» в MVC) и модель уровня данных для многоуровневого проектирования приложений.
Поэтому допустимо размещать бизнес- правила, связанные с вашей базой данных, в модели (на уровне данных) вашего приложения.
Но вам не следует размещать их в модели уровня представления MVC, структурированного, так как это относится только к определенному пользовательскому интерфейсу.

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

Позвольте мне представить это для вас:


Уровень представления: Модель - Вид - Контроллер


Бизнес-уровень: Доменная логика - Логика приложения


Уровень данных: хранилища данных - уровень доступа к данным


Модель, которую вы видите выше, означает, что у вас есть приложение, которое использует MVC, DDD и независимый от базы данных уровень данных.
Это общий подход к разработке веб-приложения для крупных предприятий.

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

Вот в чем дело ... Надеюсь, это поможет ...

[Примечание:] Вам также следует помнить о том факте, что в настоящее время в приложении присутствует не только одна «модель». Обычно каждый уровень приложения имеет свою собственную модель. Модель уровня представления зависит от вида, но часто не зависит от используемых элементов управления. Бизнес-уровень также может иметь модель, называемую «модель домена». Обычно это тот случай, когда вы решаете использовать доменный подход. Эта «модель предметной области» содержит данные, а также бизнес-логику (основную логику вашей программы) и обычно не зависит от уровня представления. Уровень представления обычно вызывает бизнес-уровень на определенном «событии» (нажатие кнопки и т. Д.) Для чтения данных или записи данных на уровень данных. Уровень данных также может иметь свою собственную модель, которая обычно связана с базой данных.

Вопрос: как это вписывается в концепцию MVC?

Ответ -> Это не так!
Ну, это так, но не полностью.
Это связано с тем, что MVC - это подход, разработанный в конце 1970-х годов для языка программирования Smalltalk-80. В то время графические интерфейсы и персональные компьютеры были довольно необычными, а всемирная паутина даже не была изобретена! Большинство современных языков программирования и IDE были разработаны в 1990-х годах. В то время компьютеры и пользовательские интерфейсы полностью отличались от тех, что были в 1970-х годах.
Вы должны иметь это в виду, когда говорите о MVC.
Мартин Фаулер написал очень хорошую статью о MVC, MVP и сегодняшних графических интерфейсах.


10
+1 за правильное перечисление разницы между mvc и n-уровневым приложением. Большинство разрабатываемых мною корпоративных приложений имеют n-уровень и используют mvc только в качестве уровня представления.
Retired_User

Скажем так: 1) Просмотр моделей в MVC (уровень представления) 2) Некоторые технологии C # (бизнес-уровень) для авторизованных транзакций, логика основных бизнес-правил. 3) Репозиторий и единица работы в (Уровень доступа к данным). Приведите несколько технологий (или шаблонов с наилучшей практикой), которые можно использовать для создания бизнес-уровня, который должен позволять разрешать и предоставлять модель, репозиторий для доступа из контроллера на уровне представления (верхний уровень). Слой). По сути, я считаю, добавлять, удалять, обновлять и комбинировать их как бизнес-логику, и они должны храниться в транзакциях. Просьба распространить дополнительный свет на это.
Марк Макнейл Бикио

Привет Рахул, если я правильно тебя понимаю, то ты прав. Операции CRUD являются в основном атомарными частями бизнес-транзакций. Лично я предпочитаю использовать мощное средство сопоставления OR, такое как Hibernate, в качестве репозитория вместо создания своего собственного. Это связано с тем, что hibernate уже реализует внутреннюю единицу работы. Также я обычно помещаю бизнес-транзакции в отдельные бизнес-сервисы.
Фрэнк

Для модели представления я могу дать вам следующий пример: просто изображение, у вас есть графический интерфейс с двойным представлением списка. Это двойное представление списка использует модель двойного представления списка в качестве своей модели данных. Эта модель данных представляет собой просто набор из двух простых списков. Таким образом, модель двойного списка-представления зависит от реализации уровня представления, поскольку он не является частью модели вашего домена, в отличие от двух простых списков, которые используются для создания модели представления. В зависимости от графического интерфейса пользователя, который вы хотите создать, есть несколько случаев, когда вам может потребоваться привязать конкретную модель представления к представлению, а не к модели вашего домена.
Фрэнк

Бизнес-правила / логика немного сложнее объяснить. Чтобы начать обработку данных, вы вызываете метод из одной из ваших служб. Это означает, что вы в основном начинаете транзакцию. Если этот метод содержит бизнес-логику, он называется «сценарий транзакции». Обычно это плохо, так как вряд ли можно использовать повторно. Было бы лучше, если бы этот метод вызывал бизнес-логику модели вашего домена. Это означает, что ваша модель предметной области должна быть разработана таким образом, чтобы она могла содержать бизнес-логику. Этот доменный подход не будет работать с неполной или неправильной моделью предметной области.
Фрэнк

73

Термин бизнес-логика, на мой взгляд, не является точным определением. Эванс рассказывает в своей книге «Управление через домен» о двух типах бизнес-логики:

  • Доменная логика.
  • Логика приложения.

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

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

Для обоих этих типов приложений импорт / экспорт CSV может иметь значение, но правила импорта / экспорта CSV не имеют никакого отношения к реальному домену. Этот вид логики является прикладной логикой.

Доменная логика, безусловно, входит в уровень модели. Модель также будет соответствовать уровню домена в DDD.

Однако логика приложения не обязательно должна быть размещена на уровне модели. Это можно было бы поместить непосредственно в контроллеры или создать отдельный прикладной уровень, содержащий эти правила. Что наиболее логично в этом случае, будет зависеть от реального применения.


1
Это очень верно! Здесь есть две модели: модель просмотра и модель вашего домена. Я думаю, что почти прискорбно, что компоновка проектов MVC заставляет начинающих разработчиков полагать, что они должны просто впихнуть свой код в модель представления.
Джонатан

1
Нашел ваш ответ более приемлемым и понятным. Спасибо.
Revo

27

A1 : бизнес - логика идет в Modelчасть в MVC. Роль Modelсостоит в том, чтобы содержать данные и бизнес-логику. Controllerс другой стороны, несет ответственность за получение пользовательского ввода и решить, что делать.

A2 : A Business Ruleявляется частью Business Logic. У них есть has aотношения. Business Logicесть Business Rules.

Посмотрите на Wikipedia entry for MVC. Перейти к обзору, где он упоминает поток MVCшаблонов.

Также посмотрите на Wikipedia entry for Business Logic. Упоминается, что Business Logicсостоит из Business Rulesи Workflow.


16

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

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

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

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

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


2
Лучший ответ по этому вопросу. Нужно проголосовать выше. Худший ответ помечен как принятый.
Петр Матиско

Лучший ответ .. без сомнения
Салман

Зависит ли это от размера данных и приложения? Для небольшого приложения, я предполагаю, что вся логика могла бы войти в модели без какой-либо путаницы. Если да, то каков порог размера, чтобы начать разделение на отдельный слой?
mLstudent33

15

Это ответ на вопрос, но я дам свой «один цент»:

Бизнес-правила принадлежат модели. «Модель» всегда состоит из (логически или физически разделенных):

  • модель представления - набор классов, который хорошо подходит для использования в представлении (он предназначен для конкретного пользовательского интерфейса / представления),
  • модель предметной области - независимая от интерфейса часть модели, и
  • хранилище - часть «модели», учитывающая хранение.

Бизнес-правила живут в модели предметной области, представляются в форме представления, подходящей для модели «представления», и иногда дублируются (или также применяются) в «слое данных».


5

Нет смысла помещать ваш бизнес-уровень в модель для проекта MVC.

Скажи, что твой босс решит сменить слой презентации на что-то еще, ты бы облажался! Бизнес-уровень должен быть отдельной сборкой. Модель содержит данные, поступающие из бизнес-уровня, который передается в представление для отображения. Затем при публикации, например, модель связывается с классом Person, который находится на бизнес-уровне, и вызывает PersonBusiness.SavePerson (p); где p - класс Person. Вот что я делаю (класс BusinessError отсутствует, но будет добавлен и в BusinessLayer):введите описание изображения здесь


Не могли бы вы уточнить это утверждение? « Модель содержит данные, поступающие из бизнес-уровня, который передается в представление для отображения».
Энтони Ратледж,

2

Q1:

Деловую логику можно рассматривать в двух категориях:

  1. Логики домена, такие как управление адресом электронной почты (уникальность, ограничения и т. Д.), Получение цены товара для счета или расчет общей цены ShoppingCart на основе его объектов товара.

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

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

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

Дело в том, что примечания, упомянутые «Mud» и «Frank» выше, могут быть как истинными, так и «Питом» (бизнес-логику можно поместить в модель или контроллер, в соответствии с типом бизнес-логики).

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


Q2:

Бизнес-логика является более общей, и (как упоминалось выше как «дециклон») мы имеем следующую связь между ними:

бизнес-правила ⊂ бизнес-логика


0

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


-5

Модель = код для операций базы данных CRUD.

Контроллер = отвечает на действия пользователя и передает пользовательские запросы на извлечение или удаление / обновление данных в модель в соответствии с бизнес-правилами, характерными для организации. Эти бизнес-правила могут быть реализованы в вспомогательных классах или, если они не слишком сложны, просто непосредственно в действиях контроллера. Контроллер наконец просит представление обновить себя, чтобы предоставить пользователю обратную связь в виде нового дисплея или сообщения типа «обновлено, спасибо» и т. Д.,

View = UI, который генерируется на основе запроса к модели.

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


Если вы помещаете бизнес-правила в контроллер и у вас есть много-много действий - собираетесь ли вы копировать бизнес-правило много-много раз? Нет. Вы разделите его на вспомогательный метод или какой-нибудь класс. Поместите эту «вещь» в модель, где она принадлежит.
Г. Стойнев

3
MVC не является шаблоном приложения для операций с базой данных CRUD (хотя его можно использовать таким образом), поэтому модель не может быть «кодом для операций с базами данных CRUD». Модель определяет сущности приложения, включая данные и бизнес-правила. Контроллер координирует взаимодействие между видом и моделью. Представление - это пользовательский интерфейс, представляющий модель и доступные операции в моделях, представленных контроллером.
Джон Дэвис
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.