设计模式之美
王争
前 Google 工程师,《数据结构与算法之美》专栏作者
123425 人已学习
新⼈⾸单¥98
登录后,你可以任选6讲全文学习
课程目录
已完结/共 113 讲
设计模式与范式:行为型 (18讲)
设计模式之美
15
15
1.0x
00:00/00:00
登录|注册

11 | 实战一(上):业务开发常用的基于贫血模型的MVC架构违背OOP吗?

定义业务领域模型及其交互
划分业务模块
用于解耦业务系统
数据与业务逻辑封装在同一个类中
面向过程编程风格
数据与操作分离
Controller
View
Model
2. 合并类的可能性
1. 项目经历
适用场景
传统开发模式 vs. DDD开发模式
前期设计投入更多时间和精力
业务复杂的系统开发
思维固化,转型成本高
设计难度低
业务简单
领域驱动设计(DDD)
充血模型
贫血模型
MVC三层架构
课堂讨论
重点回顾
什么项目应该考虑使用基于充血模型的DDD开发模式?
为什么基于贫血模型的传统开发模式如此受欢迎?
什么是基于充血模型的DDD开发模式?
什么是基于贫血模型的传统开发模式?
业务开发常用的基于贫血模型的MVC架构违背OOP吗?

该思维导图由 AI 生成,仅供参考

在前面几节课中,我们学习了面向对象的一些理论知识,比如,面向对象四大特性、接口和抽象类、面向对象和面向过程编程风格、基于接口而非实现编程和多用组合少用继承设计思想等等。接下来,我们再用四节课的时间,通过两个更加贴近实战的项目来进一步学习,如何将这些理论应用到实际的软件开发中。
据我了解,大部分工程师都是做业务开发的,所以,今天我们讲的这个实战项目也是一个典型的业务系统开发案例。我们都知道,很多业务系统都是基于 MVC 三层架构来开发的。实际上,更确切点讲,这是一种基于贫血模型的 MVC 三层架构开发模式。
虽然这种开发模式已经成为标准的 Web 项目的开发模式,但它却违反了面向对象编程风格,是一种彻彻底底的面向过程的编程风格,因此而被有些人称为反模式(anti-pattern)特别是领域驱动设计(Domain Driven Design,简称 DDD)盛行之后,这种基于贫血模型的传统的开发模式就更加被人诟病。而基于充血模型的 DDD 开发模式越来越被人提倡。所以,我打算用两节课的时间,结合一个虚拟钱包系统的开发案例,带你彻底弄清楚这两种开发模式。
考虑到你有可能不太了解我刚刚提到的这几个概念,所以,在正式进入实战项目的讲解之前,我先带你搞清楚下面几个问题:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文探讨了贫血模型和充血模型在MVC架构中的应用及其对面向对象编程的影响。贫血模型将数据与操作分离,破坏了面向对象的封装特性,而充血模型则将数据和对应的业务逻辑封装到同一个类中,满足面向对象的封装特性。文章介绍了基于充血模型的领域驱动设计(DDD)开发模式,并探讨了其在微服务架构中的应用。同时,文章分析了基于贫血模型的传统开发模式受欢迎的原因,包括业务简单、充血模型设计难度大以及转型成本等因素。总的来说,本文通过对MVC架构、贫血模型和充血模型的解释,帮助读者更好地理解业务系统开发中常用的开发模式,以及贫血模型对面向对象编程风格的影响。文章重点强调了基于充血模型的DDD开发模式适用于复杂业务系统开发,需要在前期设计上投入更多时间和精力,以提高代码的复用性和可维护性。同时,课堂讨论部分提出了对比基于贫血模型和充血模型的优劣以及领域模型设计的问题。整体而言,本文对于读者快速了解贫血模型和充血模型在MVC架构中的应用及其对面向对象编程的影响提供了清晰的概览。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《设计模式之美》
新⼈⾸单¥98
立即购买
登录 后留言

全部留言(285)

  • 最新
  • 精选
  • 倡印
    小时候妈妈说我贫血 ,长大了才知道我真的贫血

    作者回复: 你这是贫嘴,不是贫血

    2020-07-21
    3
    68
  • lmdcx
    看到「领域驱动设计有点儿类似敏捷开发、SOA、PAAS 等概念,听起来很高大上,但实际上只值“五分钱”。」时,不知道引起了多少人的共鸣,O(∩_∩)O~。 做技术的本身就经常会遇到沟通问题,一些人还总喜欢“造概念”,唯恐别人听懂了,争哥这句话无疑说中了我们的心坎儿。 当然我这里也不是说 DDD 不好(看后面的争哥也没这个意思),但是每个理论都有自己的局限性和适用性,看很多文章在讲一些理论时,总是恨不得把自己的理论(其实也算不得自己的)吹成银弹,态度上就让人很难接受。 我还是喜欢争哥的风格,逻辑很清晰,也很严谨,很务实。 关于老师的问题。 说句实话,我们就没有写过充血模型的代码。 我们会把 UserEntity、UserBo 混着用, UserBo 和 UserVo 之间转换时有时还会用 BeanUtils 之类的工具 copy 。 对于复杂的逻辑,我们就用复杂 SQL 或者 Service 中的代码解决。 不过我在翻一些框架时,比如 Java 的并发包时不可避免的需要梳理 Lock、Condition、Synchronizer 之间的关系。比如看 Spring IOC 时,也会需要梳理围绕着 Context 、 Factory 展开的很多类之间的关系。 就好像你要“混某个圈子”时,就不可避免的“拜码头”,认识一堆“七大姑八大姨”,然后你才能理解整个“圈子”里的关系和运转逻辑。 我也经常会有疑问, DDD 和面向对象究竟是什么关系,也会猜想:是不是面向对象主要关注“圈子”内的问题,而 DDD 主要关注“圈子”之间的问题?有没有高手可以回答一下。 (其实我最近一直都想订隔壁DDD的课,但是考虑到精力的问题,以及担心学不会,主要不是争哥讲O(∩_∩)O~,所以没下手)

    作者回复: 哈哈,多谢认可,我写这篇文字的时候,还害怕搞DDD的人会来骂我,看来是我多虑了。隔壁的DDD课程可以去学下,管它是不是我写的,看看他咋“吹”的也好。

    2019-11-27
    9
    49
  • grey927
    能否用代码表达一下充血模型,其实还是不太理解

    作者回复: 下一节课有的

    2019-11-27
    9
  • DullBird
    1.目前基本都在接触贫血开发模型,充血的可能局部模块设计的时候,会把数据和方法组织到一个类里面去。但是DB的操作完全隔离。 这里有一个问题:充血模型的话,OOP的想法,应该是每个人(假设人是类,具体的人就是人这个类的实例化)管理自己的属性,比如我的主管。 这个时候有一个需求。批量修改人员的主管。那么充血模型是要遍历委托给每个具体的人自己去修改呢?还是提供一个service,直接批量操作DB。 2. entity,bo,vo我的做法是不合并,但是真的有贯穿三层的模型。那么就直接用一个。但是要单独分包。并且组内规范好这个包里面的东西都是有修改风险的。我个人倾向用麻烦换容错。毕竟软件的变化性比较大

    作者回复: 1. 充血模型并不是哪都适用 2. 赞成你的看法

    2019-11-27
    9
  • 追风少年
    1. 以前做的项目都是基于贫血模型的,这次的话涉及风控业务,也是基于贫血模型,但是各种问题不断,正在考虑优化,这里刚好看到老师的文章,希望能有所借鉴。 2. Entity是ORM中数据库映射的实体类,BO是业务操作相关实体类,VO是视图层对应实体类。在简单情况下,这三个类可能是一样的,比方说你填写一个登陆注册的表单,此时前端传给后端接口的数据,一般就是VO,而通过业务层Service操作,加入创建时间,IP地址等,就转换成了BO,最后对应到数据层就转换为了Entity,也许一次注册可能需要写多个库,就会生成多个Entity。 有些复杂业务,还有DO,DTO,PO之类的概念,但是个人感觉很模糊,也不是很了解。这里希望老师能指点一下。

    作者回复: DTO:data transfer object,是一种更抽象的概念,这种数据类型可以是贫血模型的,主要是用在接口之间传递数据。 其他的两个没听说过:《

    2019-11-27
    2
    8
  • 饭太司替可
    项目中用到了google的ProtocolBuffer,根据数据结构体生成的类模型只能包含数据,不能包含方法。这种情况也是贫血模型吧。

    作者回复: 是的

    2019-12-19
    7
  • 安静
    要是有代码例子就好了。实操性会强很多。

    作者回复: 一看就是没认真看文章,文章说了例子在下一节课中有的

    2019-11-27
    4
  • 阿卡牛
    最近在看消息队列的专栏,里面有提到Pulsar这个产品采用了存储与计算分离的设计。本质上和文中提到的数据与操作分离应该是一个意思吧?难道也是一种面向过程的设计

    作者回复: 存储本身有自己的逻辑在那里面,不能单独的看做是数据。

    2019-11-27
    2
    3
  • 迁橘
    看完了, 感觉热血沸腾, 特别期待下一节课. 课堂讨论: 1, 自己所参与做的项目中都是典型的基于贫血模型开发模式. 2, 我是基本都用一个类的, 因为所做的系统业务想比较简单, 也就没必要, 还有些共用的属性字段会拿出来,用继承的方式. 基本项目都是这么过来的. 也没遇到啥问题, (大家勿笑哈) 从第一节课听到现在, 受益匪浅, 每节课都会听个3-5遍. 到现在, 基本能意识到自己在工作种存在的一些问题,以及需要提升进步的地方, 期待后面的课程....

    作者回复: (づ ̄3 ̄)づ╭❤~

    2019-11-27
    3
  • 十二差一点
    MVC是面向过程编程,是因为它违反了封装的特性,数据和逻辑操作分离开了,在controller进行相关数据逻辑操作,而model仅仅只是个数据层,没有任何操作。而MVVM是面向对象编程,因为它把数据和其相关逻辑操作封装在了viewModel,只暴露给外部相关方法,controller想要获取数据直接通过这些方法就行了,不用像MVC在controller层进行一堆逻辑操作,同时减轻了controller的代码,在viewModel也方便维护数据逻辑操作。不知道这样的理解对不对?

    作者回复: 恩恩 可以这么理解

    2019-11-27
    3
    3
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部