​面向对象的两大迷思,再给你们解答一次

2024-02-01 09:59

本文主要是介绍​面向对象的两大迷思,再给你们解答一次,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


面向对象是目前最流行的一种程序设计和实现思想。无论从事企业级开发、互联网应用开发,还是手机软件开发,都会用到面向对象的技术。

在主流的编程语言中,C++、Java、C#、PHP、Python等都是支持面向对象的语言;在编程排行榜前十的语言中,面向对象的编程语言能够稳定占据7~8席……

所有的这些现象,都展示了面向对象的流行程度和受欢迎程度。但即使这样,仍然存在一些歪理邪说在坊间流传!

下面我们就对其中流传较广的两条逐个击破!

  • 面向对象会导致性能降低?

  • 面向对象语言=面向对象编程?

本文选自李运华老师新作《编程的逻辑:如何用面向对象方法实现复杂业务需求》,本书会通俗易懂地带你揭示面向对象的本质,助你实现复杂的业务需求!

▼ 扫码获取本书详情 ▼

迷思1:面向对象会导致性能降低?

这是一个在IT江湖流传已久的传说,很多对面向对象不甚了解,或者一知半解的人,每当需要抵触面向对象的时候,就会把这条“金科玉律”拿出来救驾!

更要命的是,每个相信这个传说的人都会举一个看起来很显而易见的例子:C语言和Java的对比!

你可以在网上搜索出一大堆C语言和Java的性能对比,你也可以做一个简单的对比测试,我毫不怀疑测试结果肯定是C语言快,但这能证明面向对象导致性能降低吗?

从语言层面来说,面向对象的语言肯定要比面向过程的语言性能低一些,毕竟这是由处理机制决定的,就像不同的人的差别由基因决定一样,这个很难改变。所以,对性能要求很高的系统软件,例如操作系统、驱动程序、网络设备程序基本上都是用C语言编写的。

但在实际应用中,除了前面提到的专有系统(操作系统、驱动、嵌入式等),对一般的业务系统来说,无论是企业级应用,还是互联网应用,抑或是电信银行应用,都是复杂的系统,这些系统要和存储系统(磁盘、磁带等)打交道,要通过网络进行交互,要访问数据库……

我们看一下常见的一些性能数据(量级数据,不一定精确)。

  • CPU:每秒10亿次,性能是纳秒级。

  • 内存:每秒1000万次,每次请求时间是微秒级。

  • 磁盘:每次请求5ms,请求时间是毫秒级。

  • 网络(TCP):每次网络交互2ms,请求时间是毫秒级。

  • 数据库:基本等于网络与磁盘之和,甚至更慢。

从上面的数据可以看出,如果业务流程中涉及了磁盘、网络、数据库等操作,那么性能就一下子降到了毫秒级。

而对于大部分开发语言来说,语言本身的运行速度至少是内存级别的。

试想一下,在整个流程中,语言本身的处理占了微秒级的时间,而一次磁盘或者网络的时间是毫秒级的,那么从全流程来看,就算你把语言本身的处理速度提高了10倍,但对整个流程来说,性能几乎没有受到影响。

例如,假设C语言全流程处理时间为:10μs(语言部分)+ 5ms(磁盘操作)= 5.01ms。

如果换成Java,那么处理时间变成:100μs(语言部分)+ 5ms(磁盘操作)= 5.1ms。

从这个简单的样例可以看出,语言本身性能的提升,对整个流程中性能的提升几乎没有影响!

因此,对于复杂的业务系统来说,性能的好坏是由设计来决定的,而不是由语言来决定的,更不会因为采用了面向对象而导致性能降低!

迷思2:面向对象语言=面向对象编程?

C语言是纯粹的面向过程的编程语言,而Java是纯粹的面向对象的编程语言,因此很多人就自然而然地认为:用C语言编程就是面向过程编程,用Java编程就是面向对象编程!很多人在面试的时候都会说“我掌握了面向对象编程”,其实他只是掌握了Java编程而已。

之所以产生这种误解,我认为主要原因还是大部分人并没有深入理解“面向过程”和“面向对象”的本质,而只是将它们简单地和编程语言等价对应起来。

其实,不管是“面向过程”还是“面向对象”,都是一种思维方式、一种思考问题的方式,而和具体的语言没有关系。用C语言一样可以写出面向对象的程序,用Java也可以写出面向过程的程序。

我们以Redis为例。Redis是标准的C语言程序,但是你知道吗,其中就用到了面向对象的思想。

Redis的事件处理支持epoll(Linux操作系统)、kqueue(BSD系统)、select(UNIX系统)几种方式,但Redis没有在事件处理流程中用if( OS == Linux)...else if(OS == BSD)...else if(OS == UNIX)这种方式,而是将事件处理抽象成几个通用的接口:aeApiCreate、aeApiAddEvent、aeApiDelEvent等。不同的实现方式都实现这几个接口,在事件处理流程中统一调用这些接口。

同样,用Java一样可以写出面向过程的代码。一种最简单的方式就是写一个大类,这个类有很多方法,在main函数里面按照面向过程的方式调用即可。

例如,如下代码用Java实现了一个面向过程的HttpServer(省略具体的代码实现)。

package com.po;/*** 用Java语言实现一个面向过程的HttpServer,省略具体的代码实现**/
public class HttpServer {public static void main(String[] args) {//虽然我们用的是Java编程语言,但如下代码实际上是面向过程的代码openSocket();while(true){acceptConnection();acceptHttpRequest();handHttpRequest();sendHttpResponse();}}/*** 打开监听端口*/private static void openSocket(){//此处省略具体实现}/*** 接收HTTP连接*/private static void acceptConnection(){//此处省略具体实现        }/*** 接收HTTP请求*/private static void acceptHttpRequest(){//此处省略具体实现}/*** 处理HTTP请求*/private static void handHttpRequest(){//此处省略具体实现}/*** 发送HTTP响应*/private static void sendHttpResponse(){//此处省略具体实现}
}

面向对象经过几十年的发展,理论已经趋于成熟。虽然面向对象更加类似于“人的思想”,但其理论相比面向过程来说要复杂很多,相关的知识和技术也更加纷繁复杂。

因此导致很多人在学习面向对象的时候感觉比较难,或是在实际开发中不能很好地运用这些技术。

这本《编程的逻辑:如何用面向对象方法实现复杂业务需求》是李运华老师在多年的摸索与不断的实践下,逐渐形成的一套完整的面向对象方法论。本书可以帮助更多的程序员更好地掌握面向对象思想和技巧,享受程序人生,实现自己的梦想!

李运华 著

▊ 作者简介 

李运华

阿里前资深技术专家(P9),15年软件设计开发经验,曾就职于华为、UCWEB、阿里巴巴、蚂蚁金服,承担架构设计、架构重构、技术团队管理、技术培训等职责;专注于开源技术、系统分析、架构设计,对互联网技术的特点和发展趋势有较深入的研究和理解,先后负责过阿里游戏异地多活、飞鸽消息队列、交易平台解耦、蚂蚁国际澳门钱包等项目,对于高性能、高可用、业务架构、系统解耦等有丰富的经验,著有《面向对象葵花宝典:思想、技巧与实践》、《从零开始学架构》2本书籍,极客时间专栏《从0开始学架构》作者。

本书内容架构

第1部分 面向对象基础

通过对面向对象相关的历史、发展,以及与面向过程的对比等相关背景知识的介绍,让读者对面向对象有一个更完整的认识;并深入地阐述面向对象的各种概念,让读者“知其然,并知其所以然”。

第2部分 面向对象方法

通过一个实例,完整地介绍面向对象相关技术如何在软件开发流程中落地,整个面向对象的开发流程一环扣一环,步步为营,让读者避免使用“拍脑袋”“头脑风暴”式的开发方式。

第3部分 面向对象技巧

对“内聚耦合”“设计模式”“设计原则”“UML”等最常见的面向对象技术进行深入和别具一格的阐述,让读者不但知道“What”(是什么),还能知道“Why”(为什么)和“How”(如何用)。

第4部分 面向对象实战

通过增加“朋友圈踩”和“ZooKeeper”的案例来说明面向对象方法在业务系统和算法系统中如何落地,让读者对具体开发项目中如何应用面向对象方法更加有“体感”。

▼ 扫码获取本书详情 ▼

 ▼ 加入本书交流群,共同学习 ▼ 


如果喜欢本文

欢迎 在看留言分享至朋友圈 三连

这篇关于​面向对象的两大迷思,再给你们解答一次的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/666906

相关文章

ffmpeg面向对象-待定

1.常用对象 rtsp拉流第一步都是avformat_open_input,其入参可以看下怎么用: AVFormatContext *fmt_ctx = NULL;result = avformat_open_input(&fmt_ctx, input_filename, NULL, NULL); 其中fmt_ctx 如何分配内存的?如下 int avformat_open_input(

(function() {})();只执行一次

测试例子: var xx = (function() {     (function() { alert(9) })(); alert(10)     return "yyyy";  })(); 调用: alert(xx); 在调用的时候,你会发现只弹出"yyyy"信息,并不见弹出"10"的信息!这也就是说,这个匿名函数只在立即调用的时候执行一次,这时它已经赋予了给xx变量,也就是只是

flume系列之:记录一次flume agent进程被异常oom kill -9的原因定位

flume系列之:记录一次flume agent进程被异常oom kill -9的原因定位 一、背景二、定位问题三、解决方法 一、背景 flume系列之:定位flume没有关闭某个时间点生成的tmp文件的原因,并制定解决方案在博主上面这篇文章的基础上,在机器内存、cpu资源、flume agent资源都足够的情况下,flume agent又出现了tmp文件无法关闭的情况 二、

chapter06 面向对象基础 知识点Note

文章目录 前言类的设计 属性和行为对象的内存解析 (堆 栈 方法区)类的成员之一 变量(属性) field类的成员之二 方法 method对象数组方法重载 overload可变个数的形参 语法糖方法的值传递机制递归关键字package importMVC设计模式import导入面向对象特征之一 封装类的成员之三 构造器JavaBeanUML类图 前言 ` 面向对象封装 面向

jmeter之仅一次控制器

仅一次控制器作用: 不管线程组设置多少次循环,它下面的组件都只会执行一次 Tips:很多情况下需要登录才能访问其他接口,比如:商品列表、添加商品到购物车、购物车列表等,在多场景下,登录只需要1次,我们期望的是重复执行登陆后面的接口来做压测,这就和事务相关,例如 事务1: 登录—>添加购物车 事务2: 登录—>购物车列表 事务3: 登录—>商品列表—>添加购物车 … 一、仅一次控制器案例 在

一次生产环境大量CLOSE_WAIT导致服务无法访问的定位过程

1.症状 生产环境的一个服务突然无法访问,服务的交互过程如下所示: 所有的请求都是通过网关进入,之后分发到后端服务。 现在的情况是用户服务无法访问商旅服务,网关有大量java.net.SocketTimeoutException: Read timed out报错日志,商旅服务也不断有日志打印,大多是回调和定时任务日志,所以故障点在网关和商旅服务,大概率是商旅服务无法访问导致网关超时。 后

关于一次速度优化的往事

来自:hfghfghfg, 时间:2003-11-13 16:32, ID:2292221你最初的代码 Button1 34540毫秒 5638毫秒  Button2 我的代码 这个不是重点,重点是这个  来自:hfghfghfg, 时间:2003-11-13 16:54, ID:22923085528毫秒 不会吧,我是赛杨1.1G  128M内存  w2000, delphi6  128M

【JVM】JVM栈帧中的动态链接 与 Java的面向对象特性--多态

栈帧 每一次方法调用都会有一个对应的栈帧被压入栈(虚拟机栈)中,每一个方法调用结束后,都会有一个栈帧被弹出。 每个栈帧中包括:局部变量表、操作数栈、动态链接、方法返回地址。 JavaGuide:Java内存区域详解(重点) 动态链接 动态链接:指向运行时常量池中该栈帧所属方法的引用。 多态 多态允许不同类的对象对同一消息做出响应,但表现出不同的行为(即方法的多样性)。 多态

java基础总结15-面向对象11(抽象类)

下面通过一下的小程序深入理解抽象类 因此在类Animal里面只需要定义这个enjoy()方法就可以了,使用abstract关键字把enjoy()方法定义成一个抽象方法,定义如下:public abstract void enjoy();   从某种意义上来说,抽象方法就是被用来重写的,所以在父类声明的抽象方法一定要在子类里面重写。如果真的不想在子类里面重写这个方法,那么可以再在子类里

java基础总结14-面向对象10(多态)

面向对象最核心的机制——动态绑定,也叫多态 1 通过下面的例子理解动态绑定,即多态 package javastudy.summary;class Animal {/*** 声明一个私有的成员变量name。*/private String name;/*** 在Animal类自定义的构造方法* @param name*/Animal(String name) {this.name = n