MVC: куда девать бизнес-логику?
во-первых, я видел много вопросов об этом, но недостаточно рассуждений об этом. Если мой вопрос недостаточно хорош и должен быть удален, я пойму.
Я взглянул, например, на это, и 45+ проголосовал за ответ говорит, что он советует вам поместить бизнес-логику в модель, которая звучит довольно логично.
тем не менее, мой первый большой проект я сделал со всеми моими BL полностью в контроллерах, потому что я не ставил под сомнение эти вещи и посмотрел, как это делается в AccountController который автоматически добавляется, если вы выбираете MVC с проверкой подлинности формы. Все методы выглядят довольно набитыми BL. Или, может быть, это наименьшее количество кода, которое можно было добавить, и я пропускаю вещи?
человек на youtube спросил меня, прав ли он, поставив всю логику в свои модели, и сначала я был нет! Тогда я начал думать, что, возможно, он был прав!?
Итак, в конце концов, где я ставлю свою бизнес-логику? если он находится в классах моделей, то сколько кода следует считать здоровым количеством в методе, который находится в контроллере? Одна строка для вызова некоторого метода из модели в контроллере не более, а затем возврат к представлению?
10 ответов:
Я предпочитаю помещать логику домена в модель по нескольким причинам.
модель не должна иметь кода пользовательского интерфейса в нем и, следовательно, быть проще в тестировании. Когда это возможно, мне нравится иметь полностью работающую (то есть полную тестовую модель) перед написанием любого кода пользовательского интерфейса. Контроллер может доверять тому, что модель делает правильные вещи и просто справляется с проблемами пользовательского интерфейса.
Если вы поместите логику домена в контроллер, это не так просто разделить между различные приложения, или даже между различными контроллерами.
Мне нравится держать мои модели в чистоте, т. е. просто со свойствами и без бизнес-логики. Я всегда думаю, что хорошо вводить зависимости в контроллер, и эти зависимости содержат логику, которую я выполняю на своих моделях. Мне нравится придерживаться принципа единой ответственности, где это возможно, и я нахожу, что модели с тоннами методов очень быстро раздуваются. Есть плюсы и минусы для обоих, инъекция большого количества зависимостей имеет накладные расходы, но позволяет тестировать изолированно и сохраняет классы просто, и вы будете в конечном итоге иметь более компактных контроллеров. Несмотря на то, что моя логика фактически не существует в моей модели как членов класса, ее все еще бизнес-логика. У меня, как правило, нет бизнес-логики, определенной в контроллере, поскольку насмешливые вещи, такие как Httpcontext, немного кошмарны и ненужны.
The бизнес логика принадлежит к проблемной области и все, что принадлежит к проблемной области идет в модель в MVC.
The контроллер должен отвечать за передачу данных из модели в представление и из представления обратно в модель. Таким образом, контроллер является мостом между тем, с чем взаимодействует пользователь, и тем, как программа моделирует и сохраняет состояние проблемы. Элемент сантехники, так говорить.
ключевым здесь является различие между бизнес-логикой и логикой сантехники. На мой взгляд, то, что делает Автогенерированный контроллер учетных записей, - это в основном сантехника, а не бизнес-логика. Имейте в виду, что логика сантехники не обязательно короткая, поэтому вам не нужно вводить искусственные ограничения (например, "X количество вызовов не более чем в контроллере").
моя команда при переходе на mvc из webforms (asp.net) сделал много исследований и придумал следующую структуру. По мне его не о том, насколько большой или маленький приложение. Его держать код чистым и ясным.
DALProject
AccountsDAL.cs --- > Calls SP or any ORM if ur using anyBLLProject
AccountsBLL.cs ---> Calls DALWebProject
Model AccountsModel --- > Contains properties And call BLL Controllers IndexController ---> Calls Models and returns View Views Indexконтроллеры должен нести ответственность за передачу данных между модель и вид. Кроме этого в нем не должно быть никакого ненужного кода. Например, если вы входите, это должно быть сделано на уровне модели, а не контроллера.
там, кажется, некоторая путаница вокруг этой темы. В основном кажется, что люди склонны путать шаблон MVC с N-уровневой архитектурой как ситуацию или/или. Реальность такова, что эти два подхода могут использоваться вместе, но один не зависит от другого и ни один не требуется.
N-уровневая архитектура связана с разделением приложения на несколько уровней. Простой пример - это когда приложение разбивается на презентационный слой, бизнес логический уровень и уровень доступа к данным.
MVC-это шаблон проектирования, связанный с уровнем представления приложения. Полностью возможно разработать приложение, следуя подходу MVC, не отделяя бизнес-логику и логику доступа к данным от уровня представления и, таким образом, в конечном итоге с одноуровневым дизайном.
результат, если вы следуете подходу MVC, не разделяя приложение на уровни, заключается в том, что вы получаете модели, представления и Контроллеры, которые имеют биты бизнес-правил и логики доступа к данным, смешанные с остальной логикой.
по определению, в N-уровневой архитектуре уровень представления должен быть способен взаимодействовать только со слоем бизнес-логики, поэтому он должен содержать, что любой из компонентов MVC может взаимодействовать только со слоем бизнес-логики.
Если вы создаете приложение, которое не включает презентацию и, следовательно, не является слоем презентации, вы не должны придется беспокоиться о шаблоне MVC. Тем не менее, вы очень хорошо можете разделить свое приложение на несколько уровней и, таким образом, следовать N-уровневому дизайну, даже если нет никакого уровня представления.
Мне нравится держать мои модели в чистоте, а также (ref: @Mark Walsh). Проблема невозможности повторного использования логики, встроенной в контроллеры, может быть легко преодолена путем внедрения зависимостей, или, если вы думаете, что этого будет слишком много, предоставьте свою логику бизнеса/домена через интерфейсы и используйте шаблон фасада в контроллерах. Таким образом, вы получаете необходимую функциональность, но держите как контроллеры, так и модель в чистоте и порядке.
вообще говоря, бизнес-логика не должна находиться ни в одном из игроков MVC; она должна быть только потреблено по Вашим действиям контроллера.
Как многие уже упоминали, лучше всего создать библиотеку для размещения бизнес-логики в виде набора клиентских агностических, многоразовых компонентов.
когда это делается таким образом, мы значительно увеличиваем повторное использование, совместимость, масштабируемость и тестируемость с нашим программным обеспечением. Мы также уменьшаем нашу зависимость от некоторых особенностей фреймворка, что облегчает переход на более новые / различные технологии.
абстрагирование нашей бизнес-логики в отдельную сборку (или сборки) хорошо служило нам на протяжении многих лет. Наша бизнес-логика может быть использован практически любой .Чистая технология (ASP.NET в MVC, API или ядро, в WPF, выиграть форм, ФОС, магазина, ВФ, консоли и т. д.).
кроме того, нам нравится наш средний уровень для обработки бизнес-правил и логики проверки, чтобы уменьшить наши зависимости от .NET MVC Framework. For например, мы избегаем использования помощников проверки .NET MVCs и вместо этого полагаемся на свои собственные. Это еще один фактор, который позволяет нам легко использовать нашу бизнес-логику из любой технологии .NET.
логическое проектирование нашего среднего уровня таким образом позволило нам легко достичь этой физической архитектуры:
Это было написано с Peasy.NET, и служил нам хорошо на протяжении многих лет. Так хорошо на самом деле, что мы решили с открытым исходным кодом.
Если кому-то интересно, как выглядит наш средний уровень, вот пример клиент-агностик, бизнес-уровень. Он также демонстрирует потребление его несколькими клиентами .NET (ASP.NET MVC, Web Api и WPF).
надеюсь, это кому-то поможет!
Я также предпочел бы держать модели в чистоте. Контроллеры MVC должны использоваться только для совершения вызовов, а также должны содержаться в чистоте. Таким образом, в зависимости от его многократного использования, чувствительности и релевантности бизнес-логика может быть записана в
1.Контроллер Веб-API: преимущество использования контроллера webapi заключается в том, что вы можете предоставить их в качестве служб позже другим устройствам, что делает ваш код повторно используемым.
2. Бал / общий commonent: есть некоторые логики, которые имеют конкретное использование и не могут быть представлены как api, могут быть выдвинуты в этом классе.
3. Репозиторий: все запросы, связанные с базой данных, добавляются в репозиторий. Может быть общий репозиторий, который будет реализовывать все функции (операции CRUD)или конкретные репозитории для каждой таблицы. В зависимости от выполняемых операций.
Как писал ахануса, вы должны поместить свою бизнес-логику в отдельную DLL или отдельный каталог.
Я часто использую каталог с именем Logics на том же уровне моделей и контроллеров, где я помещаю классы, которые делают бизнес-логику.
Таким образом, я позволяю чистить как модели, так и контроллеры.
Я знаю, что это вопрос о MVC, но я думаю, что пример, который я даю (Web API), будет полезен.
Я разрабатываю свой первый веб-API, и я повторно использую бизнес-логику из других приложений. Чтобы быть конкретным, он исходит из внешней DLL, поэтому мой API используется только для "разговора" с решением SAP, получения запросов от PO и отправки ответов обратно.
Как я могу поместить свою логику (уже реализованную) в мой контроллер? Мне это не нужно. Мой контроллер будет только получать, проверять запросы и составлять ответы для отправки данных обратно.
Я работаю с классами ViewModel, и все, что они должны иметь, это функция отображения, просто для чтения информации из TransferObjects (которая поступает из внешней DLL) и перевода в ViewModel.
Мне не нравится мое приложение (в данном случае Web API), содержащее бизнес-логику, я думаю, что повторное использование будет потеряно таким образом.
Я рассматриваю свою бизнес-логику как зависимость, которую я вводил в контроллер.
Я сделал много рефакторинга в наследии, чтобы обеспечить модульное тестируемое решение, мне пришлось создать много интерфейсов и реализовать некоторые шаблоны проектирования в наследии, чтобы обеспечить это решение.
на мой взгляд, должен быть кроме заявления, предпочтительно в другой библиотеке классов. Таким образом, у вас будет реальная концепция разделения, реализованная в вашем приложении.
конечно, если ваше ядро (бизнес) это ваше приложение (API / сайт), бизнес-правила будут реализованы в ваших классах MVC. Но в будущем, если вы хотите разработать новое приложение и некоторые бизнес-правила одинаковы, я уверен, что у вас будет много проблем, чтобы поддерживать ту же логику, реализованную в обоих приложениях.

Comments