排序逻辑应该放在模型,视图还是控制器中?

Rya*_*ohn 156 model-view-controller asp.net-mvc

我有一个下拉列表,显示从表到最终用户的值.我想按字母顺序排序这些值.

根据适当的MVC设计,我应该在哪个层放置我的排序逻辑:模型,视图还是控制器?

编辑:在回答LarsH的问题时,"你的意思是代码决定了什么样的顺序吗?或代码执行排序?",我最初指的是确定所需排序顺序的代码.

Izk*_*ata 62

谁控制排序顺序?

简单的MVC图(来自维基百科)

1)数据本身内的自然顺序:

订单是模型的一部分,所以它应该去那里."所有数据"的原始提取将按排序顺序返回数据,并且没有用于选择排序顺序的界面.

2)用户应该控制他们看到数据的方式:

View将提供与Controller交互的接口(例如上升/下降箭头),并且Model能够很好地理解数据,以便对数据执行请求的排序.但是,与(1)中不同,数据的原始拉动不一定必须进行排序.

在任一情况下,

View不理解正在进行中,还有一种能够显示选择了哪个排序方向的能力.不要把逻辑放在那里.

小警告

排序功能可以完全在视图中,在一种情况下(我可以随意思考;可能还有更多):

一种"哑"排序,其中所有数据已经​​在视图中,并且它不必使用任何领域知识来进行排序.例如,非常简单的字符串或数字比较.例如,当结果可能跨多个页面分割时,这在网页上的搜索结果中是不可能的.

  • 视图可以看到用户!? (58认同)
  • 该模型更新视图!? (41认同)
  • 维基百科文章很糟糕:"组件交互"部分与右侧显示的图表(您刚刚在此处发布)冲突.其次,该模型不"更新"视图.当状态发生变化时,它会通知视图.视图决定如何更新.啊.你想知道为什么当有太多不清楚的信息浮出水面时,这个问题有1000个不同的答案. (13认同)
  • @StephenSarcsamKamenar和其他所有人:不,图像非常有意义:它显示的是数据_流,而不是代码连接. (6认同)
  • @cHao当然.我们可以同意维基百科图表虽然很奇怪,对吧?:) (4认同)
  • Izkata,澄清一下,我并没有像维基百科文章那样抱怨你的答案...视图知道如何更新,因为模型有一个观察者(视图)列表,当模型发生变化时,模型会通知他们模型. (2认同)

Kyl*_*leM 47

(注意:这个引用和引用来自@ dasblinkenlight的答案,但我们不同意我们对它的解释.阅读他的帖子并自己决定).

根据MVC描述,

控制器可以向其关联视图发送命令以更改视图的模型表示(例如,通过滚动文档).它可以向模型发送命令以更新模型的状态(例如,编辑文档).

排序逻辑(例如,排序比较器/排序算法)属于模型,因为它包含业务规则和状态数据.由于改变模型数据的排序方式完全属于"更改视图的模型表示"类别,因此控制器负责通过调用model.changeSortedState()方法进行"排序".

  • 如果要在两个不同的视图中显示相同的数据,排序方式不同,该怎么办? (8认同)

das*_*ght 18

根据MVC描述,

控制器可以向其关联视图发送命令以更改视图的模型表示(例如,通过滚动文档).它可以向模型发送命令以更新模型的状态(例如,编辑文档).

据此,排序逻辑属于控制器,因为改变模型数据的排序方式完全属于"更改视图的模型表示"类别.

编辑:为了澄清评论中提到的多个误解,"排序逻辑" 不是执行排序的代码; 它是定义排序的代码.排序逻辑将各个项目彼此进行比较以建立顺序(例如,通过其实例IComparator<T>)或包含构造用于由外部系统排序的对象的逻辑(例如,通过其实例IOrderedQueryable<T>).此逻辑属于您的控制器,因为它需要与应用程序的"业务"方面相关的知识.执行排序完全足够,但它与实际执行排序的代码是分开的.排序的代码可能在您的视图中,在您的模型中,甚至在支持模型的持久层中(例如您的SQL数据库).

  • -1你是如何从这个引用中得出结论的?有没有人说控制器应该从模型中检索信息?控制器发送命令以更改状态.没有任何关于提取或操纵信息的说法. (12认同)
  • @tereško你是如何从我的回答中得出结论,控制器需要从模型中检索信息?通过"排序逻辑",我只是指建立排序所必需的逻辑 - 在C#术语中,它提供了`IComparer <T>`的实现.排序的剩余"样板机制",包括从模型中检索数据,取决于视图. (3认同)
  • *"..排序逻辑属于控制器......"*,这还意味着什么? (3认同)
  • "控制器可以向其关联的视图发送命令以更改视图的显示"实际上听起来像视图将执行排序,以响应来自控制器的命令. (3认同)

non*_*ont 10

以上都不是.排序是业务逻辑,业务逻辑不属于三者中的任何一个.并非您的应用程序中的每一段代码都是模型,视图或控制器.

我通常在我的MVC应用程序中做的是我有一个执行所有业务逻辑的服务层.服务层中的方法应该具有干净,简单的API以及具有良好命名的参数.然后,您可以从控制器调用这些方法来操作模型中的数据.

从这个意义上说,排序是"在控制器中",但是进行排序的代码本身不应该在控制器中实现,只能从那里调用.

  • 我最近被告知有些人认为"服务层"(业务逻辑)是模型的一部分. (5认同)
  • 仅仅因为应用程序使用MVC模式,并不意味着应用程序中的每一段代码都是模型,视图或控制器.这也是字面上的设计模式.例如,您的应用程序可能具有某种配置文件.该配置文件既不建模用户数据,也不呈现视图,也不控制通过模型到视图的数据流.它是一个配置文件,这是它自己的一种东西. (2认同)

Jen*_*der 8

绝对不是控制器:它将消息发送到视图和模型,但应尽可能少地工作.如果用户可以通过通知模型或视图来更改控制器处理请求的排序.

也许是View,如果它是一个纯粹的View事物.如果应用程序在没有排序的情况下也能正常工作,那么排序只是表示的一部分,应该放在视图中.

如果排序是域的固有部分,它应该放在模型中.


ter*_*ško 6

  • 视图是MVC的一部分,它应该包含表示逻辑.
  • 模型层是包含业务逻辑的地方.
  • 控制器仅根据用户输入更改两者的状态.

所以选择是 - 您认为这是域业务逻辑或表示逻辑的一部分.

如果您正在实现适当的MVC Model2或经典MVC模式,那么我会说模型层提供的数据排序应该由视图对模型层的请求触发.查看请求有序数据,模型层提供它.

但是,由于您使用的是ASP.NET MVC对MVC模式的解释,这与您的标准MVC略有不同 - ViewModel实例应该从模型层请求有序信息(出于某种原因,ASP.NET框架认为应该调用模板"views"和视图应该被称为"viewmodels"..这很奇怪).

  • 你依靠"排序逻辑"应用你自己的假设*来继续使用多个答案.你的假设是完全错误的 - 排序逻辑不包括检索,也从未包含检索. (12认同)

bUK*_*eer 5

我通常会在控制器中按照其他答案保持与模式一致.请参阅下面的推理.

我一直在考虑这个并阅读答案和相关材料,并且实际上我会说这将取决于您的应用程序:

它是一个中型/大型应用程序和/或具有多个与之关联的UI(即Windows应用程序,Web界面和电话界面).

  • 在这种情况下,我可能会构建一个服务层并将其放在业务对象中,然后从控制器调用适当的方法.

如果它是一个定义良好的单一UI网站,并且您使用的是EF Code First之类的东西,并且您没有或无意创建服务层,并计划使用简单的开箱即用扩展方法来实现它:

  • 在这种情况下,我可能会把它放在控制器中,实际上它在时间/预算方面最合适.

如果与上述BUT相同,则无法使用开箱即用的扩展方法实现.

  • 我可能会选择在Model类中弹出它(如果它真的定制到那个单一类型),因为它在这里比在控制器中更合适.如果排序可以应用于多个类,那么我将在扩展方法中实现它,然后在控制器中调用它.

总结一下:

教条答案:服务层

务实回答:通常是控制器