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

07 | 理论四:哪些代码设计看似是面向对象,实际是面向过程的?

避免滥用,细化设计
为何需要Utils类
改进设计思路
影响代码的复用性
增加代码的编译时间
影响代码的可维护性
基于贫血模型的开发模式
Utils类的设计问题
Constants类的设计问题
解决方案:避免滥用setter方法,防范集合内部数据被修改
潜在的数据不一致问题
违反封装特性
其他情况下的面向过程风格的代码
如何用面向过程编程语言模拟面向对象的四大特性
基于贫血模型的开发模式
Constants类、Utils类的设计问题
滥用getter、setter方法
面向对象和面向过程并不是完全对立的
面向对象编程的基础
面向对象编程难度较大
符合人的流程化思维方式
定义数据和方法分离的类
滥用全局变量和全局方法
滥用getter、setter方法
将所有代码都塞到类里并不一定是面向对象编程
函数式编程
面向对象编程
面向过程编程
课堂讨论
重点回顾
面向过程编程的用武之地
容易写出面向过程风格的代码的原因
三个典型的代码案例
面向对象编程的误解
三种编程风格
哪些代码设计看似是面向对象,实际是面向过程的?

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

上一节课,我们提到,常见的编程范式或者说编程风格有三种,面向过程编程、面向对象编程、函数式编程,而面向对象编程又是这其中最主流的编程范式。现如今,大部分编程语言都是面向对象编程语言,大部分软件都是基于面向对象编程这种编程范式来开发的。
不过,在实际的开发工作中,很多同学对面向对象编程都有误解,总以为把所有代码都塞到类里,自然就是在进行面向对象编程了。实际上,这样的认识是不正确的。有时候,从表面上看似是面向对象编程风格的代码,从本质上看却是面向过程编程风格的。
所以,今天,我结合具体的代码实例来讲一讲,有哪些看似是面向对象,实际上是面向过程编程风格的代码,并且分析一下,为什么我们很容易写出这样的代码。最后,我们再一起辩证思考一下,面向过程编程是否就真的无用武之地了呢?是否有必要杜绝在面向对象编程中写面向过程风格的代码呢?
好了,现在,让我们正式开始今天的学习吧!

哪些代码设计看似是面向对象,实际是面向过程的?

在用面向对象编程语言进行软件开发的时候,我们有时候会写出面向过程风格的代码。有些是有意为之,并无不妥;而有些是无意为之,会影响到代码的质量。下面我就通过三个典型的代码案例,给你展示一下,什么样的代码看似是面向对象风格,实际上是面向过程风格的。我也希望你通过对这三个典型例子的学习,能够做到举一反三,在平时的开发中,多留心一下自己编写的代码是否满足面向对象风格。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

面向对象编程中常见的面向过程编程风格是一个常见问题,本文通过三个典型案例展示了滥用getter、setter方法、全局变量和全局方法、以及数据和方法分离的类可能导致的问题。作者指出,这些做法违反了面向对象编程的封装特性,导致代码退化成了面向过程编程风格。针对这些问题,作者提出了一些建议,如尽量避免滥用getter、setter方法,拆解Constants类为功能更单一的多个类,以及避免定义过于大而全的Utils类。此外,文章还提到了基于贫血模型的开发模式,即数据和方法分离的类,这种开发模式在Web项目中非常常见。作者承诺在后续的面向对象实战环节中对这个问题进行更加细致、全面的讲解。整体而言,本文深入浅出地解释了面向对象编程中的常见误区,对读者在平时的开发中多留心编写的代码是否满足面向对象风格提出了建议。文章还探讨了面向过程编程及面向过程编程语言的实际应用,强调了面向过程编程风格在某些场景下的适用性。同时,重点回顾了三种违反面向对象编程风格的典型代码设计,为读者提供了清晰的总结和思考方向。

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

全部留言(271)

  • 最新
  • 精选
  • Jxin
    1.用shell实现自动化脚本做的服务编排,一般都是面向过程,一步一步的。而k8s的编排却是面向对象的,因为它为这个顺序流抽象出了很多角色,将原本一步一步的顺序操作转变成了多个角色间的轮转和交互。 2.从接触ddd才走出javaer举面向对象旗,干面向过程勾当的局面。所谓为什么“充血模型”不流行,我认为不外呼两个。一,规范的领域模型对于底层基础架构来说并不友好(缺少setget),所以会导致规范的领域模型与现有基础架构不贴合,切很难开发出完全贴合的基础架构,进而引深出,合理的业务封装却阻碍关于复用通用抽象的矛盾。二,合理的业务封装,需要在战略上对业务先做合理的归类分割和抽象。而这个前置条件很少也不好达成。进而缺少前置设计封装出来的“充血模型”会有种四不像的味道,反而加剧了业务的复杂性,还不如“贫血模型”来得实用。事实上快节奏下,前置战略设计往往都是不足的,所以想构建优秀的“充血模型”架构,除了要对业务领域和领域设计有足够的认知,在重构手法和重构意愿上还要有一定讲究和追求,这样才能让项目以“充血模型”持续且良性的迭代。 3.“充血模型”相对于“贫血模型”有什么好处?从我的经验来看,可读性其实可能“贫血模型”还好一点,这也可能有思维惯性的原因在里面。但从灵活和扩展性来说“充血模型”会优秀很多,因为好的“充血模型”往往意味着边界清晰(耦合低),功能内敛(高内聚)。这一块老师怎么看?

    作者回复: 说的非常好👍

    2019-11-18
    24
    394
  • 嘉一
    个人觉得,MVC这种框架模式本质上与面向对象并不冲突。当我们在讨论面向对象的时候,我们究竟应该怎样去定义一个对象,究竟什么才能被我们看成是对象,是不是只有像某种物体,比如说一只鸟或者一只狗我们才能去把他定义为对象?我认为,MVC里面的三个部分Model 、Controller 、View 我们都能把他们单独的看成一个对象,比如说Model,本来它是数据单元,但是如果我们把他看做一个对象的话,里面存储的数据不就是我们对象里的属性么,而对于数据的二次加工处理等等操作不就是对象里的方法么?同理,对于View而言,里面小的view组件或者是其他的view不就是我们对象里面的属性,而对于不同的view组件或其他view的组合或者其他的处理操作不就是对象里面的方法么?所以说,不必死抠定义,数据就一定要和业务逻辑组成一个类云云。。。我们最后写出来的代码的目的就是,1.要解决问题;2.代码有可扩展性,可读性;3,代码解耦;

    作者回复: 说的没错,MVC跟贫血模型没直接关系。我后面在实战篇会讲到的。你的观点我基本都赞同。

    2019-11-18
    6
    104
  • 青阳魂
    看完这篇,真的太有感触了,提出的这些问题,都是目前大部分程序员所存在的编码问题。 实际上面向对象、充血模型,面向过程,都是各有各的使用场景,这点上面的同学都说的很明白了,老师也说的非常明白。 很想加老师的微信交流沟通,总有那种一见如故的感觉。 我一直觉得我推崇的编码方式好像在他们眼里是异类,又说不清楚自己推崇的是什么。 说一个非面向对象语言实现面向对象的方式 lua 可以使用 setmetatable 方式实现 封装 继承

    作者回复: 欢迎加啊 wangzheng0822

    2019-11-21
    2
    16
  • 梦倚栏杆
    1.现在因为使用封装好的框架,没有提供set方法,类的序列化会成为一个问题 2.从理论上来说,数据和逻辑应该放在一起,但是数据的赋值往往可能依赖其他的service提供的数据,如果这样的话数据属性和纯粹依赖的service就会导致一个类的成员属性特别的多。 3.对于一个具体现实对象而言,不同场景下可能关心的字段稍微有些不一样,对于此又该怎么处理呢?多个小对象,他们之间有无相关关系,有的话如何阐述,还是全部赋值完毕,都完整返回。当然可能具体场景具体分析,那是否有一个稍微通用的指导纲领 期待老师关于面向对象的实战流程

    作者回复: 😄你说的后面都基本上有讲到

    2019-11-18
    12
  • hong
    习惯了从前端的参数直接使用 BeanUtils.copyProperties 映射到具体实体类,如果不直接提供set方法,有啥好的方法去组装数据呢

    作者回复: 给类本身提供一个copy方法呢

    2019-11-21
    5
    11
  • 编程界的小学生
    1.get set 这个很好理解,但是我有很多疑问,比如有的属性理论上来讲不该添加set方法,那我怎么对他进行属性拷贝?比如两个vo进行拷贝属性值,还有作为接口参数,spring又怎么给他赋值? 2.看完贫血模式那个知识点后,我懵了,我甚至不知道怎么才能写出面向对象的代码了,如果数据和业务不分离的话,那比如我多个业务接口需要同一份数据,难道要定义多份吗?我有点懵了😥😥😥

    作者回复: 1. 并没有说一定不能定义set方法,文章中说不要滥定义用不上的set方法 2. 多个业务接口需要同一份数据?这个怎么理解呢?

    2019-11-18
    3
    5
  • 码农Kevin亮
    老师这一讲,解我多年困惑。 仍有一事困惑:前端传数据到后端,我要是不定义一个开放了所有属性的POJO,那么数据如何反序列化成类呢?

    作者回复: 前端跟后端交互的那个叫dto 可以定义为之包含数据的类 后面会讲到

    2019-12-02
    4
  • grey927
    Constants用接口是不是比用类更好?

    作者回复: 接口不能包含属性的 用接口不合适

    2019-11-20
    3
    4
  • 肖大妞
    是不是对不同的业务场景,应该采用不同的编程范式 业务驱动比较强的场景,是不是用采用面向过程编程更容易让人理解,

    作者回复: 后面实战篇会详细的讲解的。

    2019-11-18
    4
  • 月坛小雨
    老师讲课举例的时候,能不能稍微带点python的例子?(另外,老师在加餐里有Java的基础知识,非常贴心了)

    作者回复: 我python不怎么懂啊 抱歉啊

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