asp.net-mvc 胖模型/瘦控制器与服务层

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8735466/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 01:40:34  来源:igfitidea点击:

Fat model / thin controller vs. Service layer

asp.net-mvcasp.net-mvc-3model-view-controllerarchitectureservice-layer

提问by PeterFromCologne

I have been developing enterprise applications for many years using .Net My apps usually have a domain model containing entities mapping to SQL DB tables. I use a Repository pattern, Dependency injection and a service layer.

我多年来一直使用 .Net 开发企业应用程序我的应用程序通常有一个域模型,其中包含映射到 SQL DB 表的实体。我使用存储库模式、依赖注入和服务层。

Recently we started working on MVC 3 projects and we had a debate where to put which logic. I came accross thin Controller / FAT Model architecture and was wondering how the service layer would fit in

最近我们开始研究 MVC 3 项目,我们争论了该把哪个逻辑放在哪里。我遇到了瘦控制器 / FAT 模型架构,想知道服务层将如何适应

Option 1 - Model talks to services

选项 1 - 模型与服务对话

Controller is thin, calls methods on the models. The models "know" how to load themselfs from the DB and talk to repositories or services. E.g. customerModel has a Load(id) method and loads the customer and some child objects like GetContracts().

控制器很瘦,调用模型上的方法。模型“知道”如何从数据库加载自己并与存储库或服务对话。例如,customerModel 有一个 Load(id) 方法并加载客户和一些像 GetContracts() 这样的子对象。

Option 2 - Controller talks to services

选项 2 - 控制器与服务对话

Controller asks Services to retrieve model objects. The logic of loading / storing etc. Is in the service layer. The model is a pure entity model with data only.

控制器要求服务检索模型对象。加载/存储等逻辑在服务层。该模型是一个只有数据的纯实体模型。

Why would option 1 be a better choice especially when we talk about enterprise applictions my experience tells me to separate concerns, keep models AND Controllers as thin as possible and have specialized services doing the Business logic (imcl. The DB interaction)

为什么选项 1 是更好的选择,尤其是当我们谈论企业应用程序时,我的经验告诉我将关注点分开,使模型和控制器尽可能精简,并拥有专门的服务来处理业务逻辑(包括数据库交互)

Thanks for all advices and references to good resources.

感谢您对良好资源的所有建议和参考。

回答by one.beat.consumer

All of this depends on the intention and requirements of your application.

所有这些都取决于您的应用程序的意图和要求。

That said, here's my suggestion for "mid scale" (not a local restaurant, and not Twitter/Facebook) web applications.

也就是说,这是我对“中等规模”(不是当地餐厅,也不是 Twitter/Facebook)Web 应用程序的建议。

  1. Lean Domain Modeling

    Dry POCO style objects, preferably ignorant to the MVC architecture of your web application to remain as loosely coupled from your particular implementation as possible.perhaps even class library repack-able for use in an external application, say a REST API via a WCF Web Service).

    "Model" in MVC most accurately means the model the Controller is aware ofand thus the the model intended for the View.

    In smaller (often Tutorial) applications the entity models of your "Application/Domain Model Layer" are often the same instantiated objects the controller ships off to a View.

    In larger applications developers often employ the tenets of MVVM architecture and begin using separate View Model objects. The controllers often call middle-tier services that work with the unseen entities below. In this scenario, the M in MVC most accurately means the View Model.

  2. Robust Service Layer

    This does not mean obeselogic, but well-written single purpose services. While coding your business logic in services outside of the model is a bit more "procedural" than it is pure "OOP", it helps a lot with loose coupling, testing, and flexible deployment (ex. n-tier deployment).

    In my personal practice, I code services both down at the data layer, which I consider my behavioral modeling of the POCO objects (persistence mechanics, low level validation, etc.), and higher level services (business/workflow function) up closer to the MVC mechanics.

  3. Lean Controllers

    I make sure my controller is merely the coach, in that it is neither the play(services) or the player(entity model or view model), but simply decides who plays what position and what play to make. My controllers do two things:

    1. Call services that interact with the entity/domain Models

    2. Prepare a View Model for the appropriate View.

    Even authenticated/authorized controller actions are done via injected services/attributes.

  1. 精益领域建模

    干 POCO 风格的对象,最好不了解您的 Web 应用程序的 MVC 架构,以尽可能与您的特定实现保持松散耦合。甚至可以重新打包类库以在外部应用程序中使用,例如通过 WCF Web 服务的 REST API )。

    MVC 中的“模型”最准确地表示Controller 知道的模型,因此是用于 View 的模型

    在较小的(通常是教程)应用程序中,“应用程序/域模型层”的实体模型通常与控制器发送到视图的实例化对象相同。

    在较大的应用程序中,开发人员通常采用 MVVM 架构的原则,并开始使用单独的视图模型对象。控制器通常调用与下面看不见的实体一起工作的中间层服务。在这种情况下,MVC 中的 M 最准确地表示视图模型。

  2. 健壮的服务层

    这并不意味着肥胖的逻辑,而是精心编写的单一用途服务。虽然在模型之外的服务中编码业务逻辑比纯粹的“OOP”更“程序化”,但它在松耦合、测试和灵活部署(例如 n 层部署)方面有很大帮助。

    在我个人的实践中,我在数据层对服务进行编码,我认为我对 POCO 对象的行为建模(持久性机制、低级验证等)和更接近于更接近于的更高级别的服务(业务/工作流功能) MVC 机制。

  3. 精益控制器

    我确保我的控制器只是教练,因为它既不是游戏(服务)也不是玩家(实体模型或视图模型),而只是决定谁扮演什么位置以及进行什么游戏。我的控制器做两件事:

    1. 调用与实体/域模型交互的服务

    2. 为适当的视图准备一个视图模型。

    甚至经过身份验证/授权的控制器操作也是通过注入的服务/属性来完成的。



EDIT 1:

编辑 1:

Keep in mind, that this does not mean your Entity/Domain Model is or must be anemic. ORMs, repositories and factories, validation or state mechanics are welcome. It only means for applications of moderate scale, the Modelin MVC represents the model meant for the controller, to hand off to your View.

请记住,这并不意味着您的实体/域模型是或必须是贫血的。欢迎使用 ORM、存储库和工厂、验证或状态机制。它仅意味着对于中等规模的应用程序,MVC 中的Model代表用于控制器模型,移交给您的 View

Hopefully this point will calm Fowler apostles who believe the anemic data modelto be an anti-pattern. At the same time, it doesreflect a slightly more procedural angle than OOP where it is more pure to include behavior in the modeled classes.

希望这一点能让 Fowler 使徒们平静下来,他们认为贫血数据模型是一种反模式。同时,它确实反映了比 OOP 稍微多一点的过程角度,其中在建模类中包含行为更纯粹。

There is no "ultimate truth", but using this pattern you'll find it easy to build, test, and deploy your applications - while maintaining a lot of re-usability and scalability.

没有“终极真理”,但使用这种模式,您会发现构建、测试和部署应用程序很容易——同时保持大量的可重用性和可扩展性。



EDIT 2:

编辑2:

That said, even for modestly sized applications, over architecting (that a word nerds made up?) a system is much too common. For instance, wrapping an ORM with a repository pattern, and then writing services to use the repository... all this is good for separation of concern and such, but if your project doesn't require (and is not very likely to soonrequire) such things, don't build it. There is nothing wrong with skipping the repository all together, writing thin business services (ex. query classes) against an ORM, or even having your controller talk directly to it. It all depends on scale.

也就是说,即使对于中等规模的应用程序,过度架构(书呆子这个词?)一个系统也太普遍了。例如,用存储库模式包装 ORM,然后编写服务以使用存储库……所有这些都有助于分离关注点等,但如果您的项目不需要(并且不太可能很快需要) ) 这样的东西,不要构建它。一起跳过存储库,针对 ORM 编写瘦业务服务(例如查询类),甚至让您的控制器直接与之对话,这都没有错。这一切都取决于规模。



EDIT 3:

编辑 3:

I wanted to note that this explanation and advice is for the context of server-side MVC architecture like ASP.Net, not for clent-side frameworks like Knockout or Backbone.

我想指出,这个解释和建议是针对像 ASP.Net 这样的服务器端 MVC 架构的上下文,而不是像 Knockout 或 Backbone 这样的客户端框架。

回答by jgauffin

You need to know some more about MVC before we go ahead and discuss where to put everything. Well, if you want to follow the pattern. Otherwise you can stop reading now.

在我们继续讨论将所有内容放在哪里之前,您需要更多地了解 MVC。好吧,如果你想遵循这个模式。否则你现在可以停止阅读。

The pattern is very loosely defined. There is nothing that says how the controller, view or model should look like or how they should be structured. The pattern simply states that you should separate the parts and how they should interact with each other. So let's look at bit more about what they are (my interpretation).

该模式的定义非常松散。没有任何内容可以说明控制器、视图或模型应该是什么样子,或者它们应该如何构建。该模式只是说明您应该将各个部分分开以及它们应该如何相互交互。所以让我们多看看它们是什么(我的解释)。

MVC

MVC

ModelThe model can be anything. It can be a webservice, your repositories, your service classes or simply your domain models. The Model are everything that are used to get the information that you need. Consider the "Model" as a layer instead of just an single object.

模型模型可以是任何东西。它可以是 Web 服务、您的存储库、您的服务类或仅仅是您的域模型。模型是用于获取所需信息的一切。将“模型”视为一个层,而不仅仅是一个对象。

ControllerThe controller is a glue. It takes the information from the Model and adapts it to the view and vice versa.

控制器控制器是一种胶水。它从模型中获取信息并使其适应视图,反之亦然。

ViewThe view should only render what the user sees.

视图视图应该只呈现用户看到的内容。

Do note that you should not confuse the Model with View Models. Microsoft should really have named the "Model" folder "ViewModels" since that's what they are. I would not use information from the "Model" directly in the views. Failure to do so would mean that you have to change the Model if the View is changed and the other way around.

请注意,您不应将模型与视图模型混淆。Microsoft 真的应该将“Model”文件夹命名为“ViewModels”,因为它们就是这样。我不会直接在视图中使用“模型”中的信息。如果不这样做,则意味着您必须在视图更改时更改模型,反之亦然。

The answer

答案

The model is not a view model but a layer. Everything in the model is used to fetch the information needed for the view. The controller takes that information and puts it into a single view model.

模型不是视图模型而是层。模型中的所有内容都用于获取视图所需的信息。控制器获取该信息并将其放入单个视图模型中。

A single controller action might use one or several calls to the "Model" to be able to assemble the information needed by the view.

单个控制器操作可能会使用一次或多次调用“模型”,以便能够组合视图所需的信息。

That means that your second option is the most correct when if you want to get an application which is easy to maintain and extend.

这意味着当您想要获得易于维护和扩展的应用程序时,您的第二个选项是最正确的。

Do note that a service layer might not be needed. You can call the OR/M directly from the controllers. But if you find yourself duplicating code or getting fat controllers, simply move the logic to a service layer. Nothing but the controller will be affected by that change since you are using proper view models.

请注意,可能不需要服务层。您可以直接从控制器调用 OR/M。但是,如果您发现自己在重复代码或获得胖控制器,只需将逻辑移至服务层即可。由于您使用的是正确的视图模型,因此该更改只会影响控制器。

回答by Sergey Kudriavtsev

Option 2 is what's described as Fat Stupid Ugly Controllers architecture (Reference to author of this expression). This solution is generally against MVC spirit as it breaks separation of concerns.

选项 2 被描述为 Fat Stupid Ugly Controllers 架构(参考此表达式的作者)。这种解决方案通常违反 MVC 精神,因为它打破了关注点分离。

回答by Imre L

Option 1: You could think that model == service. Model also IS the business layer.

选项 1:您可以认为模型 == 服务。模型也是业务层。

Option 2 is an Anemic Domain Model anti-pattern. http://en.wikipedia.org/wiki/Anemic_domain_model

选项 2 是贫血领域模型反模式。 http://en.wikipedia.org/wiki/Anemic_domain_model