胖模型/瘦控制器与服务层 [英] Fat model / thin controller vs. Service layer

查看:25
本文介绍了胖模型/瘦控制器与服务层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

选项 1 - 模型与服务对话

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

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

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

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

感谢所有对优质资源的建议和参考.

解决方案

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

也就是说,这是我对中等规模"(不是当地餐厅,也不是 Twitter/Facebook)网络应用程序的建议.

  1. 精益领域建模

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

    MVC 中的模型"最准确地表示控制器知道的模型,因此用于视图的模型.

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

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

  2. 强大的服务层

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

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

  3. 精益控制者

    我确保我的控制器只是教练,因为它既不是play(服务)也不是玩家(实体模型)或查看模型),但只是决定谁玩什么位置和玩什么.我的控制器做了两件事:

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

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

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

<小时>

编辑 1:

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

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

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

<小时>

编辑 2:

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

<小时>

编辑 3:

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

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.

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

Option 1 - Model talks to services

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().

Option 2 - Controller talks to services

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)

Thanks for all advices and references to good resources.

解决方案

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.

  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 of and 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 obese logic, 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.


EDIT 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 Model in MVC represents the model meant for the controller, to hand off to your View.

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

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:

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 soon require) 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.


EDIT 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.

这篇关于胖模型/瘦控制器与服务层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆