百科问答小站 logo
百科问答小站 font logo



面向对象编程是否是从根本上反模块化且反并行的?为什么? 第1页

  

user avatar   lazyseq 网友的相关建议: 
      

这个问题的根本在于 OOP 是基于状态的。每个对象都维护着自己的状态,暴露给外界的是一些可以改变对象状态的方法。一个对象的状态里可以有对其他对象的引用,一个对象的方法也可以调用其他对象的方法来改变其他对象的状态,所以这些状态还是关联的。很多人提到的线程安全与效率的取舍之类其实都是细枝末节,即使是有办法把所有方法都能高效地实现并且全都是线程安全的,只要状态存在,状态带来的问题就存在。在一个复杂的并发系统中,你调用 foo.bar(42),几个指令之后再调用 foo.bar(42),两次调用的结果很可能是不一样的,因为在这中间 foo 的状态可能已经改变了,或者 foo 引用的某个对象的状态可能改变了,不去看 bar() 的实现根本不知道结果依赖于什么。同样一段程序多次运行因为时序的不确定性可能结果也不一样。不管 OOP 也好,过去说的过程式编程也好,理论基础都是图灵机模型,而图灵机就是依靠对状态的记录和改变来进行运算的。图灵机里的纸带和状态寄存器用来记录状态,而读写头用来访问和改变状态。想象一下一个并行的图灵机(多个有独立状态寄存器和不同速度的读写头加上一条共享的纸带)就不难理解在这个模型下并发带来的复杂度。

而目前很多人因为并发的需求所崇尚的函数式编程是基于 Lambda Calculus 的计算模型。计算由层层嵌套的函数调用完成;每个函数调用的结果只依赖于函数和它的参数。如果 f(4, 5) = 10,那么无论你在什么时候调用 f(4, 5),它的结果都是 10。相对而言,这是一个比较干净,比较容易推理和确保正确性的模型。OOP 的程序通常有很多隐藏的数据依赖,函数式编程把这些数据依赖都明确化了。

但函数式编程最大的一个问题是,函数是一个数学抽象,在现实世界中不存在,它必须被模拟出来。目前为止被广泛使用的计算机还是基于图灵机模型,计算机的寄存器、缓存、内存就是用来记录状态的。要真正懂得程序设计,必须知道没有状态的函数是如何在充满状态的计算机上实现的,所以还是绕不开非函数式的编程。另外绝大部分的函数式程序设计语言都不是纯函数式的,出于实用性考虑都夹杂着其他语言的一些特点,并没有完全排斥状态。Haskell 号称纯函数式语言,用 Monad 来抽象状态,理论上可以自圆其说,但在实际使用中其实还是带来了很多不便(于是又发明了 Monad Transformer...)。

从某种程度上说,状态是绕不过去的,毕竟人感知到的宏观世界就是由各种各样有各自状态的对象构成。函数式编程可以帮我们避免很多用其他方式容易犯的错误,在很多情况下写出更高质量的程序,但并发带来的复杂度并不会从根本上消失。各种编程风格一定是互相影响推动程序设计语言的进化,没有绝对的好坏,从 C++ 和 Java 最新标准里引入的函数式方面的功能就很容易看出这一点。比较有意思的是,OOP 最早是在 LISP 里实现的,而 LISP 也被很多人看做函数式编程的起始。同样,好的程序员也会根据具体情况使用合适的编程风格。

OOP 不失为一种比较容易理解的在计算机程序里对现实世界的抽象,在很多场合的应用是非常成功的,至少我没发现以图形用户界面为中心的程序里有比 OOP 更行之有效的抽象方式。把 OOP 从程序员的教育中去掉过于片面和激进了。如果是从基础课程调整为选修课程则是可以理解的,我上本科时记得也是那样设置的。




  

相关话题

  对于私有属性,如何判断什么时候使用浅拷贝,什么时候使用深拷贝? 
  面向对象(OOP)是编程语言发展中的弯路吗?为什么? 
  「重载」的正确读音是什么? 
  那些申请上CS四大PhD的大神的条件都是怎么样的? 
  cmu 计算机的 bic 项目内部是什么样? 
  面向对象编程是否是从根本上反模块化且反并行的?为什么? 
  如何看待 CMU 新开设的 AI 专业? 
  卡内基梅隆大学(CMU)的Eric Xing(邢波)教授为什么能读完一般学校的分子生物学PhD后到伯克利去CS PhD? 
  CMU SV是野鸡大学吗? 
  如何看待 CMU 新开设的 AI 专业? 

前一个讨论
怎么评价 Windows 用盗版,iOS 上用正版的行为?
下一个讨论
为什么炒花生凉了才脆?





© 2025-03-26 - tinynew.org. All Rights Reserved.
© 2025-03-26 - tinynew.org. 保留所有权利