首页 文章

胖模型/瘦控制器与服务层[关闭]

提问于
浏览
76

我使用.Net开发了多年的企业应用程序我的应用程序通常有一个包含映射到SQL DB表的实体的域模型 . 我使用Repository模式,依赖注入和服务层 .

最近我们开始研究MVC 3项目,我们讨论了在哪里放置哪些逻辑 . 我来自瘦控制器/ FAT模型架构,并想知道服务层如何适应

选项1 - 模型与服务的对话

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

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

Controller要求服务检索模型对象 . 加载/存储等逻辑在服务层中 . 该模型是仅具有数据的纯实体模型 .

为什么选项1会成为更好的选择,特别是当我们谈论企业应用时,我的经验告诉我要分离问题,让模型和控制器尽可能地薄,并且有专门的服务来做业务逻辑(imcl . 数据库交互)

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

4 回答

  • 88

    所有这些都取决于您的申请的意图和要求 .

    也就是说,这是我对“中等规模”(不是本地餐馆,而不是Twitter / Facebook)网络应用程序的建议 .

    • Lean Domain Modeling

    干POCO样式对象,最好是对Web应用程序的MVC体系结构无知,尽可能保持与特定实现的松散耦合 . 甚至可以在外部应用程序中重新使用类库,例如通过WCF Web服务的REST API ) .

    MVC中的"Model"最精确地表示Controller知道的模型,因此意味着用于View的模型 .

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

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

    • Robust Service Layer

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

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

    • Lean Controllers

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

    • 与实体/域模型交互的呼叫服务

    • 为相应的视图准备视图模型 .

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


    EDIT 1:

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

    希望这一点能够让那些认为贫血数据模型成为反模式的福勒使徒们平静下来 . 同时,它确实反映了比OOP稍微更具程序性的角度,其中在建模类中包含行为更加纯粹 .

    没有“终极事实”,但使用这种模式,您会发现构建,测试和部署应用程序变得容易 - 同时保持了大量的可重用性和可扩展性 .


    EDIT 2:

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


    EDIT 3:

    我想要注意的是,这个解释和建议是针对像ASP.Net这样的服务器端MVC架构的上下文,而不是针对像Knockout或Backbone这样的清晰边框架 .

  • 0

    在我们开始讨论将所有内容放在哪里之前,您需要了解更多关于MVC的知识 . 好吧,如果你想遵循这种模式 . 否则你现在可以停止阅读了 .

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

    MVC

    Model 模型可以是任何东西 . 它可以是Web服务,您的存储库,服务类或只是您的域模型 . 模型是用于获取所需信息的所有内容 . 将"Model"视为一个层而不仅仅是一个对象 .

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

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

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

    答案

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

    单个控制器操作可能使用对“模型”的一个或多个调用来组合视图所需的信息 .

    这意味着如果您想获得易于维护和扩展的应用程序,那么您的第二个选项是最正确的 .

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

  • 0

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

    选项2是Anemic Domain Model反模式 . http://en.wikipedia.org/wiki/Anemic_domain_model

  • 16

    选项2被描述为Fat Stupid丑陋控制器架构(Reference to author of this expression) . 该解决方案通常违背MVC精神,因为它打破了关注点的分离 .

相关问题