设计模式学习笔记 - 面向对象 - 3.面向对象比面向过程有哪些优势?面向过程真的过时了吗?
简述
在过往的工作中,我发现很多人搞不清面向对象和面向过程的区别,总认为使用面向对象编程语言来开发,就是在面向面向对象编程了。而实际上,他们只是在用面向对象编程语言,编写面向过程风格的代码而已,并没有发挥面向对象编程的优势。这就相当于手握一把屠龙刀,却只把它当做一把普通的到来使用。
1.什么是面向过程编程与面向过程编程语言?
如果你是一名比较资深的程序员,最开始学习编程的时候接触的是 Basic、C等面向过程的编程语言,那么你对这两个概念肯定不陌生。但是如果你是新生代的程序员,一开始学习编程的时候,接触的就是面向对象编程语言,那你对这两个概念可能不熟悉。所以,在对比面向对象与面向过程优劣之前,我们先把面向过程编程和面向过程编程语言这两个概念搞清楚。
我们可以比对这面向对象编程和面向对象编程语言这两个概念来理解面向过程编程和面向过程编程语言。我们来回顾下面向对象编程和面向对象编程语言:
- 面向对象编程是一种编程范式或编程风格。它以类或对象作为组织代码的基本单元,并将封装、抽象、继承、多态这四个特性,作为代码设计和实现的基石。
- 面向对象编程语言支持类或对象的语法机制,能方便地实现面向对象编程四大特性的编程语言。
类比面向对象编程和面向对象编程语言的定义,对于面向过程编程和面向过程编程语言这个两个概念,我给出下面这样的定义。
- 面向过程编程也是一种编程范式或编程风格。它以过程(可理解为方法、函数、操作)作为组织代码的基本单元,以数据(可理解为变量)与方法相分离为主要的特点。面向过程风格是一种流程化的编程风格,通过拼接一组顺序执行的方法来操作数据完成一项功能。
- 面向过程编程语言首先是一种编程语言。它最大的特点是不支持类和对象这两个语法概念,不支持风格的面向对象编程特性,仅支持面向过程编程。
用一个例子来解释下。假设有一个记录了用户信息的文件 users.txt,每行文本的格式是 name&age&gender(如小王&28&男
)。编写一个程序来逐行读取用户信息,然后格式化成 name,age,gender
这种格式,并且按照 age 从小达到排序后,重新写入另一个文件 formatted_user.txt。
首先,使用面向过程编程风格来编写这个程序,使用 C 语言来编写。
struct User {char name[64];int age;char gender[16];
}struct User parse_to_user(char* text) {// 将text“小王&28&男” 解析成结构体 struct User
}char* format_to_text(struct User user) {// 将结构体User格式化成文本 “小王,28,男”
}void sort_users_by_age(struct User users[]) {// 按照年龄从小到大排序users
}void format_user_file(char* file_path, char* new_file_path) {// 打开文件...struct User users[1024]; // 假设最大1024个用户int count = 0;while(1) {// 读取文件,直到读取结束// 从文件内读取一行内容...struct User user = parse_to_user(line);users[count++] = user;}sort_users_by_age(users);int i;for(i = 0; i < count; i++) {char* formatted_to_text = format_to_text(users[i]);// 写入formatted_to_text到文件...}// 关闭文件...
}int main(char ** args, int argv) {format_user_file("/file/user.txt", "/file/formatted_user.txt");
}
在看看面向对象这种风格编写出来的代码是什么样子的。
public class User {private String name;private int age;private String gender;public User(String name, int age, String gender) {this.name = name;this.age = age;this.gender = gender;}public static User parseFrom(String userInfoText) {// 将 “小王&28&男” 解析成类User}public String formatToText() {// 将类User转化成文本 “小王,28,男”}
}public class UserFileFormatter {public void format(String userFile, String formattedUserFile) {// 打开文件...List<User> users = new ArrayList<>();while (true) { // 读取文件,直到读取结束// 从文件内读取一行数据...User user = User.parseFrom(userInfoText);users.add(user);}// 按照年龄排序...for (int i = 0; i < users.size(); i++) {String formattedUserText = users.get(i).formatToText();// 写入到新文件...}// 关闭文件...}
}public class MainApplication {public static void main(String[] args) {UserFileFormatter userFileFormatter = new UserFileFormatter();userFileFormatter.format("/file/user.txt", "/file/formatted_user.txt");}
}
从上面代码,可以看出,面向过程和面向对象最近的区别是,代码的组织方式不同。面向过程风格的代码组织成立一组方法集合及其数据结构(struct User),方法和数据定义是分开的。而面向对象风格的代码被组织成一组类,方法和数据结构被绑定一起,定义在类中。
可能有人会觉得,上面这两个例子的面向对象编程和面向过程编程,这两个风格的区别貌似不是很大呀。
2.面向对象编程比面向过程编程有哪些优势?
为什么面向对象编程晚于面向过程编程出现,却能取而代之,称为主流的编程范式?面向对象编程和面向过程编程比起来,到底有哪些优势?
2.1 OOP 更加能够应对大规模复杂程序的开发
刚刚的例子,你可能感觉两种风格的代码貌似差不多,顶多就是代码组织方式有点区别,没有感觉到面向对象编程有什么优势。其实,主要原因就是因为这个例子比较简单、不够复杂。
对于简单的开发来说,不管是用面向过程编程风格,还是面向对象编程风格,差别确实不会很大,甚至有时候面向过程的编程风格反而更有优势。因为整个程序的处理流程只有一条主线,很容易被划分成顺序执行的几个步骤,然后逐句翻译成代码,这就非常适合采用面向过程这种面条式的编程风格来实现。
但是,对于大模型复杂程序的开发来说,整个程序的处理流程错综复杂,并非只有一条主线。如果把整个程序的处理流程画出来的话,会是一个网状结构。如果再用面向过程编程来实现,就会比较吃力了。这个时候,面向对象的编程风格的优势就比较明显了。
面向对象编程是以类为思考对象。在进行面向对象编程的时候,并不是一上来就去思考将流程拆为一个个方法,而是先去思考如何给业务建模,将需求翻译为类,如何给类之间建立交互关系,而完成这些工作完全不需要考虑错综复杂的处理流程。当有了类的设计之后,再像搭积木一样,按照处理流程将类组装起来形成整个程序。这种开发模式、思考问题的方式,能让我们在应对复杂程序开发的时候,思路更加清晰。
此外,面向对象编程还提供了一种更加清晰的、更加模块化的代码组织方式。比如,我们开发一个电商系统,业务逻辑发咋、代码量很大,可能要定义数百个函数、数百个数据结构,如何分门别类地组织这些函数和数据结构,才能看起来不至于凌乱呢?类就是一种非常好的组织这些函数和数据结构的方式,是一种将代码模块化的有效手段。
有人可能互说,像 C 语言这种面向过程的编程语言,也可以按照功能的不同,把函数和数据结构放到不同的文件里,以达到给函数和数据结构分类的目的。不过,面向对象编程本身提供了类的概念,强制你做这件事情,而面向过程编程并不强求。这也算是面向对象编程语言的一个小小的创新吧。
实际上,利用面向过程的编程语言照样可以写出面向对象风格的代码,只不过可能会比使用面向对象编程语言来说,付出的代码要高一些。而且,面向过程编程和面向对象编程并非完全对立。
2.2 OOP 风格的代码更易复用、易扩展、易维护
刚刚的例子比较简单,只用到了类、对象这两个基本的概念,并没有用到更加高级的四大特性。因此,面向对象编程的优势其实并没有发挥出来。
面向对象编程提供的封装、抽象、继承、多态这些特性,能极大地满足复杂的编程需求,能方便我们写出更易复用、易扩展、易维护的代码。
- 首先,封装特性将数据和方法绑定在一起,通过访问权限控制,只允许外部调用者通过类暴露的有限方法访问数据,而不会像面向过程那样,数据可以被任意访问和修改。因此,面向对象编程提供的封装特性更有利于提高代码的易维护性。
- 其次,再看下抽象特性。我们知道,函数本身就是一种抽象,它隐藏了具体的实现。在使用函数的时候,只需要了解函数具体有什么功能,而不需要了解它是怎么实现的。从这一点上,不管面向对象编程,还是面向过程编程,都支持抽象特性。不管,面对对象编程还提供了其他抽象特性的实现方式,这些实现方式是面向过程所不具备的,比如基于接口实现的抽象。基于接口的抽象,可以让我们在不改变原有实现的情况下,轻松替换新的实现逻辑,提高带代码的可扩展性。
- 接着,继承特性是面向对象编程相比于面向过程编程所特有的两个特性之一(另一个是多态)。如果两个类有一些相同的属性和方法,我们就可以将这些相同的代码,抽取到父类中,让两个子类继承父类。这样两个子类也可以重用父类中的代码,避免了代付重复多谢,提高了代码的复用性。
- 最后,在看下多态这个特性。基于这个特性,我们在需要修改一个功能实现的时候,可以通过实现一个新的子类的方式,在子类中重写原来的功能逻辑,用子类代替父类。在实际的代码运行过程中,调用子类新的功能逻辑,而不是在原有代码上做修改。这就遵从了“对修改关闭、对扩展开放”的设计原则,提高了代码的可扩展性。除此之外,利用多态特性,不同的类对象可以传递相同的方法,执行不提供的代码逻辑,提高了代码的复用性。
所以所,基于四大特性,利用面向对象编程,我们可以更轻松地写出易复用、易扩展、易维护的代码。
2.3 OOP 语言更加人性化、更加高级、更加智能
人类最早和计算机打交道是通过 0、1 这样的二进制指令,然后是汇编语言,再之后才出现了高级编程语言。在高级编程语言中,面向过程编程语言又早于面向对象编程语言出现。之所以先出现面向过程编程语言,那是因为和及其的交互方式,从二进制指令、汇编语言到面向过程编程语言,是一个非常自然的过渡,是一种流程化的、面条式的编程风格,用一组指令顺序操作数据,来完成一项任务。
从指令到汇编再到面向过程编程语言,跟机器打交道的方式在不停地进化,让人和机器打交道越来越容易。面向对象编程语言的出现,也顺应了这样的发展规律,也就是说,面向对象编程语言比面向过程编程语言更加高级。
面向对象编程语言是一种人类的思维方式,在进行面向对象编程的时候,我们在思考如何给业务建模,如何将真实的世界映射为类或对象,这让我们更加聚焦到业务本身,而不是思考如何跟机器打交道。
越高级的编程语言,离机器越远,离人类越近,也越智能。
相关文章:
设计模式学习笔记 - 面向对象 - 3.面向对象比面向过程有哪些优势?面向过程真的过时了吗?
简述 在过往的工作中,我发现很多人搞不清面向对象和面向过程的区别,总认为使用面向对象编程语言来开发,就是在面向面向对象编程了。而实际上,他们只是在用面向对象编程语言,编写面向过程风格的代码而已,并…...

联想开天昭阳N4620Z笔记本如何恢复出厂麒麟操作系统(图解)
联想开天昭阳N4620Z笔记本简单参数: 中央处理器:KX-6640MA G2 内存:8GB 固态硬盘:512GB SSD 显示器:14.0”FHD 电池:4Cell 操作系统:麒麟KOS中文RTM(试用版) 此款笔…...
Qt经典面试之理论总结(自己整理总结)
目录 1、QT信号和槽的原理和理解 2、connect函数的参数,第五个参数是什么 1、QT信号和槽的原理和理解 信号和槽机制底层是通过函数间的相互调用实现的。 信号函数和槽函数通常位于某个类中,和普通的成员函数相比,它们的特别之处在于&#…...

【YOLO系列算法人员摔倒检测】
YOLO系列算法人员摔倒检测 模型和数据集下载YOLO系列算法的人员摔倒检测数据集可视化数据集图像示例: 模型和数据集下载 yolo行人跌倒检测一: 1、训练好的行人跌倒检测权重以及PR曲线,loss曲线等等,map达90%多,在行人跌…...
获取淘宝商品详情API、商品主图、图片搜索api
获取淘宝详情API的方式有以下几种: 使用淘宝开放平台提供的接口:淘宝开放平台提供了多个API接口,让开发者可以通过接口获取商品详情信息。你可以到淘宝开放平台官网申请开发者账号,并查看相关接口文档,了解如何使用接…...

HarmonyOS创建一个ArkTS卡片
创建一个ArkTS卡片 在已有的应用工程中,创建ArkTS卡片,具体操作方式如下。 创建卡片。 根据实际业务场景,选择一个卡片模板。 在选择卡片的开发语言类型(Language)时,选择ArkTS选项,然后单…...

ChatGPT Plus遇到订阅被拒原因与解决方案
ChatGPT Plus被广泛认为相比普通版本更快、更强,并且能最先体验新功能。 很多小伙伴再订阅时遇到图片中的问题 错误提示包括这些: Your credit card was declined.Try paying with a debit card instead.您的信用卡被拒绝了。请尝试用借记卡支付。你的…...

UE蓝图 函数调用(CallFunction)节点和源码
系列文章目录 UE蓝图 Get节点和源码 UE蓝图 Set节点和源码 UE蓝图 Cast节点和源码 UE蓝图 分支(Branch)节点和源码 UE蓝图 入口(FunctionEntry)节点和源码 UE蓝图 返回结果(FunctionResult)节点和源码 UE蓝图 函数调用(CallFunction)节点和源码 文章目录 系列文章目录一、Call…...

Vue单文件学习项目综合案例Demo,黑马vue教程
文章目录 前言一、小黑记事本二、购物车三、小黑记账清单 前言 bilibili视频地址 一、小黑记事本 效果图 主代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"/><meta http-equiv"X-UA-Compatible&…...

机器视觉【3】非线性求解相机几何参数
线性求解相机几何参数的缺点 上一章节介绍学习了(DLT)线性求解相机几何参数,了解到线性求解法当中比较明显的缺点: 没有考虑到镜头畸变的影响不能引入更多的约束条件融入到DLT算法当中优化最关键的是,代数距离并不是…...

Qt编译报错:The slot requires more arguments than the signal provides.
编译时代码没有提示错误的地方,报错的地方在qt的文件,还以为什么莫名其妙的错误呢,原来就是连接的信号和槽函数参数不匹配,有个信号是没有参数的,但我的槽函数有个参数,然后就报错了。 改下槽函数的参数就…...

【Unity】提示No valid Unity Editor liscense found.Please active your liscense.
有两个软件,如果只有一个,点黑的不会有效果、、、、(楼主是这个原因,可以对号入座一下) 简而言之,就是去下载Unity Hub,再里面激活管理通行证 问题情境: 点击unity出现以下弹窗&a…...

如何在 Tomcat 中为 Web 应用程序启用和配置缓存?
在Tomcat中为Web应用程序启用和配置缓存通常涉及到对Tomcat的连接器(Connector)进行配置,以及可能的话,配置Web应用程序本身以支持缓存。 1. 配置Tomcat连接器以启用缓存 Tomcat的连接器可以通过其配置来启用各种…...

QEMU开发入门
1. 简介 QEMU(Quick EMUlator)是一个开源的虚拟化软件,它能够模拟多种硬件平台,并在这些平台上运行各种操作系统。QEMU可以在不同的主机架构之间进行虚拟化,例如x86、ARM、PowerPC、Risc-V等。QEMU是一个功能强大且灵…...

10-pytorch-完整模型训练
b站小土堆pytorch教程学习笔记 一、从零开始构建自己的神经网络 1.模型构建 #准备数据集 import torch import torchvision from torch.utils.tensorboard import SummaryWriterfrom model import * from torch.utils.data import DataLoadertrain_datatorchvision.datasets.…...

高级RAG:重新排名,从原理到实现的两种主流方法
原文地址:https://pub.towardsai.net/advanced-rag-04-re-ranking-85f6ae8170b1 2024 年 2 月 14 日 重新排序在检索增强生成(RAG)过程中起着至关重要的作用。在简单的 RAG 方法中,可以检索大量上下文,但并非所有上下…...

使用logicflow流程图实例
一.背景 需要使用流程引擎开发项目,没有使用flowable、activiti这类的国外流程引擎,想使用国内的引擎二次开发,缺少单例模式的流程画图程序,都是vue、react、angluer的不适合,从网上找了antx6、logicflow、bpmn.js。感…...

Stable Diffusion 绘画入门教程(webui)-ControlNet(IP2P)
上篇文章介绍了深度Depth,这篇文章介绍下IP2P(InstructP2P), 通俗理解就是图生图,给原有图加一些效果,比如下图,左边为原图,右边为增加了效果的图: 文章目录 一、选大模型二、写提示词三、基础参…...
五力分析(Porter‘s Five Forces)
五力分析是一种用于评估竞争力的框架,由哈佛商学院教授迈克尔波特(Michael Porter)提出。它通过分析一个行业的五个关键力量(竞争对手、供应商、顾客、替代品和新进入者)来评估一个企业或行业的竞争环境。这个框架可以…...

十一、Qt数据库操作
一、Sql介绍 Qt Sql模块包含多个类,实现数据库的连接,Sql语句的执行,数据获取与界面显示,数据与界面直接使用Model/View结构。1、使用Sql模块 (1)工程加入 QT sql(2)添加头文件 …...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...