0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

面向对象编程会被抛弃吗?这5大问题不容忽视

电子设计 来源:电子设计 作者:电子设计 2020-10-30 12:03 次阅读

20 世纪 60 年代,编程遇到了一个大问题:计算机还没有那么强大,需要以某种方式平衡数据结构和程序之间的能力。

这意味着,如果你有大量数据,那么不将计算机推向极限就无法充分利用这些数据。另外,如果你需要做很多事情,那么你就不能使用过多的数据,否则计算机将会一直运行下去。

接下来到了 1966、1967 年,Alan Kay 从理论上证明可以使用封装的微型计算机。这些微型计算机不共享数据,而是通过消息传递进行通信。这样就可以更加经济地使用计算资源。

尽管这个想法很巧妙,但直到 1981 年,面向对象编程才成为主流。在那之后,它就没有停止过吸引新的和经验丰富的软件开发者。面向对象的程序员市场一如既往地忙碌。

但是在最近几年中,这种已有几十年历史的编程范式受到越来越多的批评。难道是在面向对象编程大行其道 40 年之后,技术已经超越了这种范式?

函数和数据耦合

面向对象编程的主要思想非常简单:尝试将一个功能强大的程序整体分解为功能同样强大的多个部分。这样就可以将一些数据和那些只在相关数据上使用的函数耦合起来。

注意,这仅涵盖封装的概念。也就是说,位于对象内部的数据和函数对于外部是不可见的。我们只能通过消息(通常通过 getter 和 setter 函数)与对象的内容进行交互。

继承性和多态性并没有包含在最初的设计想法中,但是对于现在的面向对象编程而言是必需的。继承基本上意味着开发者可以定义具有其父类所有属性的子类。直到 1976 年,即面向对象的程序设计的概念问世十年之后,继承性才被引入。

又过了十年,多态性才进入面向对象的编程。简单来讲,这意味着某种方法或对象可以用做其他方法或对象的模板。从某种意义上说,多态性是继承性的泛化,因为并不是原始方法或对象的所有属性都需要传输到新实体。相反,你还可以选择重写一些属性。

多态性的特殊之处在于,即使两个实体在源代码中互相依赖,被调用实体的工作方式也更像插件。这使得开发人员的工作变得轻松,因为他们不必担心运行时的依赖关系。

值得一提的是,继承性和多态性并不是面向对象编程所特有的。真正的区别在于封装数据及其包含的方法。在计算资源比今天稀缺得多的时代,这是一个天才的想法。


面向对象编程中的 5 大问题

面向对象的编程一经问世,便改变了开发人员看待代码的方式。20 世纪 80 年代以前,过程式编程非常面向机器。开发人员需要非常了解计算机的工作原理才能编写好的代码。

通过封装数据和其他方法,面向对象的编程使软件开发更加以人为中心,符合人类的直觉。比如,方法 drive() 属于 car 数据组,而不是 teddybear 组。之后出现的继承性也很直观。比如,现代汽车(Hyundai)是汽车的一个子类,并且具有相同的属性,但 PooTheBear 不是,这样很好理解。

香蕉猴子丛林问题

想象一下,你正在设置一个新程序,并且正在考虑设计一个新类。然后,你回想起为另一个项目创建的简洁的小类,发现其对正在进行的工作很合适。

没问题,你可以将以前项目中的类在新项目中复用。

这里有一个问题:这个类可能是另一个类的子类,因此你需要将它的父类也包含在内。然后你会发现,这个父类可能也是另一个类的子类,以此类推,最后要面对一堆代码。

Erlang 的创建者 Joe Armstrong 曾有一句名言:「面向对象语言的问题在于,它们自带其自身周围的所有隐式环境。你想要香蕉,但是得到的却是拿着香蕉的大猩猩和整个丛林。」

这几乎可以说明一切。复用类是可以的,实际上这可能是面向对象编程的主要优点,但不要将其发挥到极致。有时你应该建立一个新的类,而不是添加大量依赖项。


脆弱的基类问题

想象一下,如果你已经成功地将另一个项目中的类复用于新的代码,那么如果基类发生变化会怎样?

这可能会破坏你整个新项目的代码,即使你可能什么也没做。一旦有人更改了基类中的一个细节,而这一点又对你的项目至关重要,那么这种影响将是非常大并且突然的。

使用继承的次数越多,潜在的维护工作就越多。因此,即使在短期内复用代码非常有效,但从长远来看,它可能让你付出一定的代价。

菱形继承问题

利用继承可以将一类中的属性传递给其他类。但是,如果你想混合两个不同类的属性怎么办?

没错,这无法完成,至少常规的方法都不行。以 Copier 类为例(在此引用以下链接文章中的例子:https://medium.com/@cscalfani/goodbye-object-oriented-programming-a59cda4c0e53),Copier 将扫描文件的内容并将其打印在白纸上。那么它应该是 Scanner 还是 Printer 的子类?

这个问题根本没有完美的答案。即使这个问题不会破坏你的代码,但它经常出现,会让人很沮丧。

层级问题

在菱形继承问题中,Copier 是哪个类的子类是问题的关键所在。但或许有个投机取巧的方案:假设 Copier 是父类,Scanner 和 Printer 是仅继承属性子集的子类,那么问题就解决了。

但如果你的 Copier 是黑白的,而 Printer 也能够处理彩色,那怎么办?从这个意义上说,Printer 不是 Copier 的一种泛化吗?如果 Printer 连接了 WiFi,而 Copier 没有呢?

类上堆积的属性越多,建立适当的层次结构就越困难。在你所处理的属性集群中,Copier 共享了 Printer 的一些属性,但不是全部属性,反之亦然。在大型复杂项目中,层次结构的问题会导致很大的混乱。


引用问题

你可能会想到进行没有层次结构的面向对象编程。我们可以使用属性集群,并根据需要继承、扩展或重写属性。也许这有点混乱,但这将是对当前问题的准确表示。

这里只存在一个问题:封装的全部目的是使数据片段彼此之间保持安全,从而使计算效率更高,但没有严格的层次结构,这是行不通的。

假设一个对象 A 通过与另一个对象 B 交互来覆盖层次结构,会发生什么情况?其他关系的情况并不重要,但当 B 不是 A 的直接父类时,A 必须包含 B 的全部私有引用,否则,它们将无法交互。

但是,如果 A 包含 B 的子类也具有的信息,那么就可以在多个位置修改该信息。因此,有关 B 的信息已经不再安全,并且封装已经被破坏。

尽管许多面向对象的程序员都使用这种架构来构建程序,但这并不是面向对象编程,只是一团糟。

单一范式存在的风险

以上 5 个问题的共同点是它们都存在不合适的继承。由于继承没有包含在面向对象编程的原始形式中,所以这些问题可能不能称为面向对象本身的问题。

但是也并不是只有面向对象编程会被夸大。在纯粹的函数式编程中,处理用户的输入或在屏幕上输出消息极其困难。对此,面向对象或面向过程编程会好很多。

但仍然有一些开发人员试图将这些东西用纯函数的方式实现,并且编写几十行没人能看懂的代码。而使用另一种范式就能够轻松地将代码简化为几行可读的代码。

毫无疑问,函数式编程正在得到更多关注,而面向对象编程近几年遭到一些诟病。了解新的编程范式并在适当的时候使用它们是很有意义的。无论哪种编程范式,都不需要只遵循一种,在适当的时候使用不同的编程范式才能更好地解决问题。

审核编辑 黄昊宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
收藏 人收藏

    评论

    相关推荐

    深入解析:海外IP代理在跨境电商与数据分析中的应用

    海外IP代理在跨境电商与数据分析中的应用广泛,其重要性不容忽视
    的头像 发表于 11-20 08:27 284次阅读

    编程语言的误区与常见问题

    误区一:编程语言的选择 常见问题: 初学者在选择编程语言时,往往会被市场上的热门语言所吸引,而忽视了自己的实际需求和兴趣。 一些开发者认为某种编程
    的头像 发表于 11-15 09:35 301次阅读

    工业 4.0 时代:连接器不容忽视的挑战与高效应对方案

    工业4.0时代的到来,制造业已趋向自动化、智能化和高效化。这要求生产设备具备更高的灵活性和可靠性,连接器作为连接电子设备和电路的部件,连接器的性能和功能需求也相应提升,需要满足更复杂的工业应用场景。连接器市场面临的挑战1.产品迭代带来的灵活性挑战在下游产业中,产品和技术更新换代的速度快。以汽车领域为例,新车型不断涌现,这就要求连接器具备高度的灵活性,能满足多
    的头像 发表于 10-30 08:08 413次阅读
    工业 4.0 时代:连接器<b class='flag-5'>不容忽视</b>的挑战与高效应对方案

    不容忽视的PCB测试点,关键时刻可以避免批量事故哦!

    it Test Point in English. NOKIA手机的测试点有什么用? 为什么要留两排测试点? 我虽然不知道NOKIA手机这些测试点的具体作用,但我大概可以猜测出来: 供电:包括至少一个Vbat
    的头像 发表于 10-08 06:58 223次阅读
    <b class='flag-5'>不容忽视</b>的PCB测试点,关键时刻可以避免批量事故哦!

    如何利用电源滤波器降低电源噪声

    在电子设备的设计与运行中,电源噪声是一个不容忽视的问题。它不仅会影响设备的性能稳定性,还可能对信号质量造成干扰,甚至导致设备故障。
    的头像 发表于 09-26 10:21 279次阅读

    PCB想要做好铺铜,这几点不容忽视!

    一站式PCBA智造厂家今天为大家讲讲高速PCB设计当中铺铜处理方法有哪些?高速PCB设计铺铜的正确处理方法。在高速PCB设计中,铺铜的处理对于确保信号完整性和电磁兼容性至关重要。 高速PCB设计中正确处理铺铜的方法: 1. 差分对铺铜: 对于差分信号,确保它们在相邻层上有相等且相反的铺铜。这有助于提高信号的免疫性,减小串扰,并提高差分信号的质量。 2. 规遍铺铜: 在高速PCB中,规遍(Ground Plane)是非常重要的。在每一层中都铺上规遍铜,可以提供
    的头像 发表于 07-30 09:21 453次阅读

    3针M5母头接口尺寸和外观是否符合要求

    对于确保设备间的准确连接、提高数据传输效率以及维护系统的稳定性具有重要意义。因此,对3针M5母头接口尺寸和外观的规范性要求不容忽视
    的头像 发表于 05-13 17:49 429次阅读
    3针M<b class='flag-5'>5</b>母头接口尺寸和外观是否符合要求

    不容忽视的PCB设计细节

    比起低价压力、紧迫交期、严苛品质、货款拖延等常规烦恼,订单里那些不起眼的设计失误和小BUG,带来的影响更叫人脑壳疼!
    发表于 04-10 11:46 392次阅读
    <b class='flag-5'>不容忽视</b>的PCB设计细节

    工业安全不容忽视 防止意外伤害的发生

    机械工控机
    jf_18500570
    发布于 :2024年04月07日 10:18:37

    PCB设计细节不容忽视,SMT行业大佬这样说

    的是0402的小电阻 ,但 PCB对应的焊盘却是1206的 ,怎么搭得上呢? 虽然物料才15块一盘,但为了这个小小的电阻,我们得从华强北加急采购,还得花上150的跑腿费。 而SMT线还在等着,误工
    发表于 04-02 20:38

    工业安全 不容忽视

    自动化机械臂
    jf_18500570
    发布于 :2024年03月30日 10:12:49

    为什么很少用C++开发单片机

    C语言是面向过程的语言,C++是面向对象编程语言。结合本文来说,面向过程相比面向
    发表于 03-25 14:26 979次阅读
    为什么很少用C++开发单片机

    不容忽视的小电阻:CAN(FD)终端电阻在汽车通信中的关键角色

    CAN总线终端电阻,顾名思义就是加在总线末端的电阻。此电阻虽小,但在CAN总线通信中却有十分重要的作用。终端电阻的作用CAN总线终端电阻的作用有两个:提高抗干扰能力,确保总线快速进入隐性状态;提高信号质量。提高抗干扰能力CAN总线有“显性”和“隐性”两种状态,“显性”代表“0”,“隐性”代表“1”,由CAN收发器决定。图1是一个CAN收发器的典型内部结构图,
    的头像 发表于 01-19 08:24 2976次阅读
    <b class='flag-5'>不容忽视</b>的小电阻:CAN(FD)终端电阻在汽车通信中的关键角色

    比亚迪跃居全球最大纯电动车制造商,特斯拉市值缩水2319.84亿

    尽管比亚迪在AI及自动驾驶领域相对低调,但其庞大的资金实力和技术实力不容忽视。值得注意的是,在FSD和Optimus实现商业化前,特斯拉仍高度依赖汽车销售。
    的头像 发表于 01-04 10:50 606次阅读