我们其实在用面向对象编程语言写着面向过程风格的代码

常见的编程范式或者说编程风格有三种,面向过程编程、面向对象编程、函数式编程,而面向对象编程又是这其中最主流的编程范式。

现如今,大部分编程语言都是面向对象编程语言,例如我所学的Java,大部分软件都是基于面向对象编程这种编程范式来开发的。

 

一、什么是面向对象?什么是面向过程?

什么是面向对象?

面向对象编程是一种编程范式或编程风格。它以类或对象作为组织代码的基本单元,并将封装、抽象、继承、多态四个特性,作为代码设计和实现的基石 。

面向对象编程语言是支持类或对象的语法机制,并有现成的语法机制,能方便地实现面向对象编程四大特性(封装、抽象、继承、多态)的编程语言。

什么是面向过程?

面向过程编程也是一种编程范式或编程风格。它以过程(可以理解为方法、函数、操作)作为组织代码的基本单元,以数据(可以理解为成员变量、属性)与方法相分离为最主要的特点。

面向过程风格是一种流程化的编程风格,通过拼接一组顺序执行的方法来操作数据完成一项功能。面向过程编程语言首先是一种编程语言。

它最大的特点是不支持类和对象两个语法概念,不支持丰富的面向对象编程特性(比如继承、多态、封装),仅支持面向过程编程。

 

其实从实际来讲,面向对象就是用对象来操作事物的变化,你可以是上帝视角,通过操作物来完成任务,而面向过程就是操作的过程,你以自身为视角,操作的过程。

 

二、面向对象编程相比面向过程编程有哪些优势?

 

  • 面向对象编程相比起面向过程编程的优势主要有三个。对于大规模复杂程序的开发,程序的处理流程并非单一的一条主线,而是错综复杂的网状结构。

 

  • 面向对象编程比起面向过程编程,更能应对这种复杂类型的程序开发。面向对象编程相比面向过程编程,具有更加丰富的特性(封装、抽象、继承、多态)。

 

  • 利用这些特性编写出来的代码,更加易扩展、易复用、易维护。从编程语言跟机器打交道的方式的演进规律中,我们可以总结出:面向对象编程语言比起面向过程编程语言,更加人性化、更加高级、更加智能。

 

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

在用面向对象编程语言进行软件开发的时候,我们有时候会写出面向过程风格的代码。有些是有意为之,并无不妥;而有些是无意为之,会影响到代码的质量。

 

  • 滥用getter、setter方法

       我们知道面向对象特性之一封装是不可缺少的,如果我们使用lombok的@Data这样的注解, 相当于所有的成员变量都新增了

       setget方法他们的理由一般是,为了以后可能会用到,现在事先定义好,类用起来就更加方便,而且即便用不到这些 getter、

       setter 方法,定义上它们也无伤大雅。其实这样完全暴露了所有的成员变量,可以任意修改,违背了面向对象封装的特性,

       试想,全部开放set方法,成员变量跟加public又有什么区别,而面向对象封装的定义是:通过访问权限控制,隐藏内部数据,

       外部仅能通过类提供的有限的接口访问、修改内部数据。所以,暴露不应该暴露的 setter 方法,明显违反了面向对象的封装

      特性。数据没有访问权限控制,任何代码都可以随意修改它,代码就退 化成了面向过程编程风格的了

  • 滥用全局变量和全局方法

       在面向对象编程中,常见的全局变量有单例类对象、静态成员变量、常量等,常见的全局方法有静态方法。单例类对象

       在全局代码中只有一份,所以,它相当于一个全局变量。静态成员变量归属于类上的数据,被所有的实例化对象所共享,

       也相当于一定程度上的全局变量。而常量是一种非常常见的全局变量,比如一些代码中的配置参数,一般都设置为常量,

       放到一个 Constants 类中。静态方法一般用来操作静态变量或者外部数据。你可以联想一下我们常用的各种 Utils 类,

       里面的方法一般都会定义成静态方法,可以在不用创建对象的情况下,直接拿来使用。所以说,工具类让我们单独使用

       静态方法,一些配置类又让我们单独使用变量,将方法与 数据分离,破坏了封装特性,是典型的面向过程风格,但在面向

       对象中是真的是一点都不能用?主要是不能滥用,对于配置类我们应该化为更细节化,并且最好能直接放在一些配置类中

       直接使用。例如,RedisConfig 类用到了 Redis 配置相关的常量,那我们就直接将这些常量定义在 RedisConfig 中,这样也

       提高了类设计的内聚性和代码的复用性。而对于Uitls这种工具类它在软件开发中还是挺有用的,能解决代码复用问题。

       所以,这里并不是说完全不能用 Utils 类,而是说,要尽量避免滥用,不要不加思考地随意去 定义 Utils 类。你还是觉得

      确实有必要去定义这样一个 Utils 类,那就大胆地去定义它吧。因为即便在面向对象编程中,我们也并不是完全排斥面向

       过程风格的代码。只要它能为我们写出好的代码贡献力量,我们就可以适度地去使用。

  • 定义数据和方法分离的类

       你可能会觉得,这么明显的面向过程风格的代码,谁会这么写呢?实际上,如果你是基于 MVC 三层结构做 Web 方面的

       后端开发,这样的代码你可能天天都在写。在做前后端分离之后,三层结构在后端开发中,会稍微有些调整,被分为

       Controller 层、Service 层、 Repository 层。Controller 层负责暴露接口给前端调用,Service 层负责核心业务逻辑,

       Repository 层负责数据读写。而在每一层中,我们又会定义相应的 VO(View Object)、BO(Business Object)、Entity。

       一般情况下,VO、BO、Entity 中只会定义数据,不会定义方法,所有操作这些数据的业务逻辑都定义在对应的 Controller 类、

       Service 类、Repository 类中。这就是典型的面向过程的编程风格。实际上,这种开发模式叫作基于贫血模型的开发模式,

       也是我们现在非常常用的一种 Web 项目的开发模式。

 

四、在面向对象编程中,为什么容易写出面向过程风格的代码?

 

你可以联想一下,在生活中,你去完成一个任务,你一般都会思考,应该先做什么、后做什么,如何一步一步地顺序执行一系列

操作,最后完成整个任务。面向过程编程风格恰恰符合人的这种流程化思维方式。而面向对象编程风格正好相反。它是一种自底

向上的思考方式。它不是先去按照执行流程来分解任务,而是将任务翻译成一个一个的小的模块(也就是类),设计类之间的

交互,最后按照流程将类组装起来,完成整个任务。我们在上一节课讲到了,这样的思考路径比较适合复杂程序的开发,但并

不是特别符合人类的思考习惯。除此之外,面向对象编程要比面向过程编程难一些。在面向对象编程中,类的设计还是挺需要

技巧,挺需要一定设计经验的。你要去思考如何封装合适的数据和方法到一个类里,如何设计类之间的关系,如何设计类之间

的交互等等诸多设计问题。所以,基于这两点原因,很多工程师在开发的过程,更倾向于用不太需要动脑子的方式去实现需求,

也就不由自主地就将代码写成面向过程风格了。总结就是,我们总会用我们习惯的方式去思考,上面我说过,面向过程是以

自身角度出发去执行一件事的过程,而面向过程就类似我们的思考方式。

 

五、面向过程编程不能用吗?

 

其实,我们可以把面向过程看做是面向对象的基础,因为其实每个方法的执行,不就是一个过程,不就是面向过程么,如果

我们开发的是一个以算法为主,数据为辅的,那脚本式的面向过程的编程风格就更适合一些。面向对象和面向过程两种编程

风格,也并不是非黑即白、完全对立的。在用面向对象编程语言开发的软件中,面向过程风格的代码并不少见,甚至在一些

标准的开发库(比如 JDK、Apache Commons、Google Guava)中,也有很多面向过程风格的代码,不管使用面向过程

还是面向对象哪种风格来写代码,我们最终的目的还是写出易维护、易读、易复用、易扩展的高质量代码。只要我们能避免

面向过程编程风格的一些弊端,控制好它的副作用,在掌控范围内为我们所用,我们就大可不用避讳在面向对象编程中写

面向过程风格的代码。

   

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值