应该将sorting逻辑放在模型,视图还是控制器中?
我有一个下拉列表,显示表中的值到最终用户。 我希望这些值按字母顺序sorting。
根据适当的MVCdevise,我应该在哪一层放置我的sorting逻辑:模型,视图还是控制器?
编辑 :在回应LarsH的问题,“你的意思是代码决定什么sorting顺序是需要的?或执行sorting的代码?”,我最初是指确定sorting顺序是什么意思的代码。
(注意:引用和引用来自@ dasblinkenlight的答案 ,但我们不同意我们对它的解释,请阅读他的post并自己动手)。
根据MVC的描述 ,
控制器可以将命令发送到其关联的视图以更改视图的模型表示(例如,通过滚动文档)。 它可以向模型发送命令来更新模型的状态(例如编辑文档)。
sorting逻辑(例如sorting比较器/sortingalgorithm)属于模型,因为它包含业务规则和状态数据。 由于改变了模型数据sorting的方式直接落入“改变视图的模型表示”类别,控制器负责通过调用model.changeSortedState()方法来“进行sorting”。
谁控制sorting顺序?
(来自维基百科 )
1)数据本身的自然顺序:
订单是模型的一部分,所以它应该去那里。 “所有数据”的原始数据将以sorting顺序返回数据,并且没有界面来selectsorting顺序。
2)用户应该控制他们如何看待数据:
该视图将提供与控制器交互的接口(例如,上升/下降箭头),并且该模型足够好地理解数据以对数据进行所请求的sorting。 然而,与(1)不同,对数据的原始抽取不一定需要进行sorting。
在任一情况下,
视图不理解有一种情况,除此之外,显示select哪种sorting方向的能力。 不要把逻辑放在那里。
小警告
在一种情况下(我能想到的是,可能会有更多的),sortingfunction可以完全在视图中进行:
一个“哑巴”的sorting,所有的数据已经在视图中,而且不必使用任何领域知识来进行sorting。 例如,非常简单的string或数字比较。 例如,当结果可能被分成多个页面时,这在网页上的search结果中是不可能的。
根据MVC的描述 ,
控制器可以将命令发送到其关联的视图以更改视图的模型表示(例如,通过滚动文档)。 它可以向模型发送命令来更新模型的状态(例如编辑文档)。
据此,sorting逻辑属于控制器,因为改变模型数据sorting的方式直接落入“改变视图的模型表示”类别。
编辑:澄清在评论中expression的多个误解,“sorting逻辑” 不是执行sorting的代码; 它是定义sorting的代码。 sorting逻辑比较各个项目以build立一个顺序(例如通过IComparator<T>
一个实例),或者包含构build一个对象的逻辑,这个对象将被外部系统用于sorting(例如,通过一个IOrderedQueryable<T>
)。 这个逻辑属于你的控制器,因为它需要你的应用程序的“业务”方面的知识。 执行sorting是完全足够的,但它与实际执行sorting的代码是分开的。 sorting的代码可能在您的视图中,在您的模型中,甚至在支持您的模型的持久层(例如您的SQL数据库)中。
以上都不是。 sorting是商业逻辑,商业逻辑不属于三者之一。 不是你的应用程序中的每一段代码都是模型,视图或控制器。
我通常在我的MVC应用程序中做的是我有一个执行所有业务逻辑的服务层。 服务层中的方法应该有一个干净而简单的API,它具有很好的参数。 然后,您可以从您的控制器调用这些方法来处理模型中的数据。
从这个意义上讲,sorting是“在控制器中”,但sorting的代码本身不应该在控制器中实现,只能从那里调用。
Definetly不是控制器:它发送消息来查看和build模,但应尽可能less的工作。 如果用户可以通过通知模型或视图来更改控制器处理请求的sorting。
也许查看,如果它是一个纯粹的视图的事情。 如果应用程序不需要sorting,那么sorting只是表示的一部分,应该放在视图中。
如果sorting是领域固有的一部分,它应该在模型中进行。
- 视图是应该包含表示逻辑的MVC的一部分。
- 模型层是包含业务逻辑的地方。
- 控制器仅根据用户input更改两者的状态。
所以select是 – 你认为这是领域业务逻辑或表示逻辑的一部分。
如果你正在实现一个合适的MVC模型2或经典的MVC模式,那么我会说模型层提供的数据的sorting应该由视图对模型层的请求触发。 查看要求订购的数据,模型图层提供。
但是,由于您正在使用ASP.NET MVC对MVC模式的解释,这有点不同,所以您的标准MVC – ViewModel实例应该从模型层请求有序的信息(出于某种原因,ASP.NET框架认为应该调用模板“意见”和意见应该被称为“视图模型”..这很奇怪)。
我通常会在控制器中按照其他答案保持模式一致。 请参阅下面的推理。
我一直在考虑这个问题,阅读答案和相关材料,实际上我会说这取决于你的应用程序的实例:
它是一个中/大型应用程序和/或有多个与之关联的UI(即Windows应用程序,Web界面和电话界面)。
- 在这种情况下,我可能会构build一个服务层并将其放入业务对象中,然后从控制器中调用适当的方法。
如果一个明确定义的单一用户界面网站,你正在使用像EF Code First这样的东西,而你没有或没有创build一个服务层的意图,并计划使用一个简单的扩展方法实现它:
- 在这种情况下,我可能把它放在控制器中,实际上它是时间/预算的最佳select。
如果其与上述BUT相同,则不能用开箱即用的扩展方法来实现。
- 我可以select在Model类中popup它(如果它真正定制为单一types的话),因为在这里比在控制器中更合适。 如果sorting可以应用于多个类,那么我会在扩展方法中实现它,然后在控制器中调用它。
总结一下:
教条式的回答:服务层
务实的答案:通常是控制器
你的模型应该包含数据。
你的观点应该包含你代表数据的方式。
你的控制器应该包含你的数据的操纵。
所以答案就是控制器,因为sorting是明确的操作。
我build议从一个表中sorting数据,这个数据是足够小的,可以在下拉列表中使用,应该来自已经通过查询sorting的数据库。 对我来说,这使模型成为了应用的地方。
如果你决心亲自去做,我认为你可以使用模型或控制器作为你的首选逻辑。 限制将是你的特定框架。 我更喜欢仅在模型中pipe理数据。 我使用控制器来结婚数据(模型)和演示文稿(视图),我已经(自我)教。
虽然我原则上同意sorting是商业逻辑的想法,因为通过将其分解为原产地,您最终会得到类似于“客户希望产品页面以图像按datesorting”的显示,那么变得清楚数据的sorting顺序通常不是任意的 – 即使没有sorting,因为这仍然是一个遗漏的业务决策(空列表仍然是一个列表)。
但是…这些答案似乎没有考虑到ORM技术的进步,我只能谈论entity framework(让我们避免一个关于这是否是真正的ORM的论点,这不是重点)这就是我使用的,但我确信其他ORM提供类似的function。
如果我使用MS MVC和entity framework为产品类创build强types视图,并且产品和图像表(例如FK_Product_Image_ProductId)之间存在外键关系,那么我可以开箱即可快速sorting在视图中使用类似的东西显示图像:
@foreach(Image i in Model.Image.OrderBy(e => e.DisplayOrder)){ //etc etc... }
提到了一个特定的业务逻辑层,我也用它来执行业务逻辑的80%,但是我不打算在我的业务逻辑层中编写sortingfunction,以模仿出自即时来自entity framework。
我不认为这个问题有一个正确的答案,除了这样说; 您应该在可能的情况下抽象复杂的业务逻辑,但不能以重复开发为代价。
假设你有MVC网站,WebForms网站和一个移动应用程序。
如果你想sorting在这些表示层之间是一致的,那么我会说在表示层之外sorting。 服务将是一个很好的候选人。
否则,我会将该逻辑存储在视图模型中。 为什么? 因为它可以重用,易于testing。
在列出的三个中,我会说它属于控制器。 不过,我真的不喜欢把这种逻辑放在控制器中。 我通常创build一个控制器与之通信的服务层,负责与数据存储进行通信并处理sorting逻辑。 不过,对于小型应用来说,坐在控制器中是很好的。
这是一个在asp.net中提出的问题,但是由于有人提到了Rails,我认为在这种情况下考虑问题会很有趣。 在Rails中,由于框架和ActiveRecord / ActiveQuery API为它提供了条件,所以执行sorting以及检索作为控制器动作是很自然和相当常见的。 另一方面,可以为静态项目定义某种自定义的sorting顺序,并将其放入要由控制器使用的模型中,因此模型可以在sorting逻辑中扮演一个angular色,即使它不执行直接操作。 不pipe它是什么,可以肯定地说,在视图中放置sorting逻辑通常是被忽视的。
我有点好笑,有些答案完全反对在控制器或模型中的sorting,我发现他们对我的口味过于迂腐,但我想这取决于所使用的框架的性质和通常的惯例它。 我也同意比尔·克先生的看法,认为首先分居是比较重要的。