查看原文
其他

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

李运华 博文视点Broadview 2020-11-06



面向对象是目前最流行的一种程序设计和实现思想。无论从事企业级开发、互联网应用开发,还是手机软件开发,都会用到面向对象的技术。在主流的编程语言中,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”的案例来说明面向对象方法在业务系统和算法系统中如何落地,让读者对具体开发项目中如何应用面向对象方法更加有“体感”。


▼ 扫码获取本书详情 ▼


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




如果喜欢本文欢迎 在看留言分享至朋友圈 三连

 热文推荐  





▼ 点击阅读原文,了解本书详情~

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存