Следует ли размещать логику сортировки в модели, представлении или контроллере? [закрытый]

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

согласно правильному дизайну MVC, на каком уровне я должен разместить свою логику сортировки: модель, представление или контроллер?

редактировать: в ответ на вопрос Ларша: "вы имеете в виду код, который определяет, какой порядок сортировки желателен? или код, который выполняет сортировку?", Я изначально имел в виду код, который определяет желаемый порядок сортировки.

12 ответов


(Примечание: эта цитата и цитата взята из ответ@dasblinkenlight, но мы не согласны с нашей интерпретацией этого. читайте его пост и решайте сами).

по данным описание MVC,

контроллер может отправлять команды на связанный вид для изменения представления модели (например, путем прокрутки документа). Он может отправлять команды модели для обновления состояния модели (например, редактирование документа).

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


кто контролирует порядок сортировки?

Simple MVC diagram (от Википедия)

1) естественный порядок внутри самих данных:

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

2) пользователь должен контролировать, как они видят данные:

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

в любом случае

представление не понимает, что происходит сортировка, кроме того, что возможность показать, какое направление сортировки было выбрано. Не ставьте здесь логику.

маленький нюанс

функции сортировки мог бы идите чисто в поле зрения, при одном обстоятельстве (которое я могу придумать навскидку; может быть больше):

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


по данным описание MVC,

контроллер может отправлять команды в связанное представление для изменения представления модели (например, путем прокрутки документа). Он может отправлять в модель команды для обновления состояния модели (например, редактирования документа).

согласно этому, логика сортировки принадлежит контроллеру, потому что изменение способа сортировки данных модели попадает прямо в "Изменить представление представления модели" категория.

EDIT: чтобы прояснить несколько недоразумений, озвученных в комментариях, "логика сортировки" является не код, который выполняет сортировку; это код определяет сортировка. Логика сортировки сравнивает отдельные элементы друг с другом для установления порядка (e.g через экземпляр IComparator<T>) или содержит логику, которая создает объект, используемый для заказа внешней системой (например через экземпляр IOrderedQueryable<T>). Эта логика принадлежит вашему контроллеру, потому что ей нужны знания, связанные с "деловой" стороной вашего приложения. Вполне достаточно выполнить сортировку, но она отделена от кода, который на самом деле выполняет его. Код, который сортирует, может быть в вашем представлении, в вашей модели или даже в слое сохраняемости, который поддерживает вашу модель (например, вашу базу данных SQL).


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

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

в этом смысле сортировка находится "в контроллере", но сам код, который выполняет сортировку, не должен быть реализован в контроллере, только вызывается оттуда.


определенно не контроллер: он отправляет сообщения для просмотра и моделирования, но должен делать как можно меньше работы. Если пользователь может изменить сортировку, этот запрос обрабатывается контроллером, сообщая об этом модели или представлению.

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

Если заказ является неотъемлемой частью домена он должен войти в модель.


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

Итак, выбор - считаете ли вы, что это часть бизнес-логики домена или логики презентации.

если бы вы реализовывали правильный MVC Model2 или классический шаблон MVC, то я бы сказал, что порядок данных предоставленный слоем модели должен быть вызван запросом представления к слою модели. View запрашивает упорядоченные данные, model layer предоставляет их.

но, так как вы используете ASP.NET интерпретация MVC шаблона MVC, которая немного отличается от стандартной MVC-экземпляр ViewModel должен запрашивать упорядоченную информацию из слоя модели (по какой-то причине ASP.NET framework считает, что шаблоны следует называть "представлениями", а представления - "viewmodels".. это странный.)


Я обычно делаю это в контроллере, чтобы оставаться в соответствии с рисунком, а на другой ответы. Ниже рассуждения.

я обдумывал это и читал ответы и связанные с ними материалы и прагматически говоря, я бы сказал, что это будет зависеть от вашего приложения, например:

Это среднее / большое приложение и / или имеет несколько связанных с ним UI (т. е. приложение Windows, веб-интерфейс и интерфейс телефона).

  • In в этом случае я бы, вероятно, построил слой сервиса и поместил его в бизнес-объект, а затем вызвать соответствующий метод контроллер.

Если его четко определенный веб-сайт UI, и вы используете что-то вроде кода EF, и у вас нет или нет намерения создавать уровень сервиса и планировать использование простого метода расширения из коробки, чтобы достичь его:

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

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

  • Я вполне могу выбрать, чтобы поп его в классе модели (если его действительно на заказ для этого одного типа), поскольку это было бы более уместно здесь, чем в контроллер. Если сортировка может применяться к нескольким классам, то Я бы реализовал его в методе расширения, а затем вызвал его в контроллер.

To подведем итог:

догматический ответ: уровень обслуживания

прагматический ответ: обычно контроллер


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

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


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

но... Эти ответы, кажется, не принимают во внимание учитывая достижения в технологии ORM, я могу говорить только в отношении Entity Framework (давайте избегать спора о том, является ли это истинным ORM, это не важно) от Microsoft, поскольку это то, что я использую, но я уверен, что другие ORMs предлагают аналогичные функции.

Если я создаю строго типизированное представление для класса продукта с помощью MS MVC и Entity Framework, и существует связь внешнего ключа между продуктом и таблицей изображений (например, FK_Product_Image_ProductId), то я бы из коробки можно быстро сортировать изображения во время их отображения, используя что-то вроде этого в представлении:

@foreach(Image i in Model.Image.OrderBy(e => e.DisplayOrder)){ //etc etc... }

было упомянуто о конкретном уровне бизнес-логики, который я также использую для выполнения 80% моей бизнес-логики, но я не собираюсь писать функциональность сортировки в мой уровень бизнес-логики, который имитирует что-то, что выходит из коробки из Entity Framework.

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


предположим, что у вас есть веб-сайт MVC, веб-сайт WebForms и мобильное приложение.

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

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


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


Это вопрос, заданный с помощью asp.net имея в виду, но поскольку кто-то упомянул Rails, я подумал, что было бы интересно рассмотреть проблему в этом контексте. В Rails естественно и довольно часто выполнять сортировку вместе с извлечением в качестве действия контроллера, так как для него предусмотрены API framework и ActiveRecord/ActiveQuery. С другой стороны, можно определить какой-то пользовательский порядок сортировки для статических элементов и поместить его в модель, которая будет использоваться регулятор, поэтому модель может сыграть часть в сортируя логике даже если она не уносит деятельность сразу. Что бы это ни было, можно с уверенностью сказать, что включение логики сортировки в представление обычно не одобряется.

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