读后点评《再见,面向对象》
原文 《Goodbye, Object Oriented Programming》。 作者指出了面向对象编程的一些问题,并在文章的最后推荐了函数式编程。我认为不管作者的观点我们接不接受,作者提出的面向对象的问题还是需要我们细细琢磨的。
一、面向对象的问题
先来看看作者指出的面向对象编程的几个问题:
1. 继承
作者使用了一个香蕉、猴子、丛林比喻,意思是你想要一个香蕉,却得到了一个拿着香蕉的猴子和整个丛林。这个比喻意在 描述面向对象编程过程中由于使用了继承,导致在移植某个类的同时而不得不把这个类所依赖的所有类同时移植。
2. 菱形继承问题
菱形继承问题就是多继承时导致的歧义问题。
3. 基类方法覆盖问题
在子类中覆盖基类中的方法A,然后在另外一个方法中调用基类的方法A。但实际情况是调用的是被覆盖了的方法A。
4. 层次的优先级问题
面向对象编程中基类更通用,子类更专用。但事实上有的时候并不能明确的给出某两个层次的优先级。
5. 封装的引用问题
使用封装得以使对象的内部变量被保护在对象内部。在将对象传递出去时,传递的是对象的引用或者指针。当一个对象A的构造 构造函数传入了另一个对象B的引用或者指针,按照封装的原理,被保护在对象A内部的对象B应该是安全的。但是当其他代码也拥有指向这个对象B的指针时情况就 有变了,这个指针可能会被修改指向第三个对象。
6. 多态
实现多态比不需要依赖面向对象编程。接口编程也可以实现多态。
二、解决方法
作者在描述上述问题时列举出了一些解决方法,比如使用组合(Contain)和委托(Delegate)。在文章的最后作者推荐了函 数式编程。
三、总结
作者虽然是不再推荐使用面向对象编程,但在实际应用中面向对象编程却是使用的最多的编程范式。
函数式编程并不是一个新的概念,早在1958年被创造出来的Lisp就是函数式编程语言。这么多年的发展函数式编程并没有被广泛采用一定是有它自己的原因。
Javascript在ES6规范中增加了类,使得原先使用原型链实现继承的方式更简单了。同时数组中加入了from、of、reduce、filter、every等借鉴函数式编程的方法。最近几年函数式编程逐渐升温,在Javascript领域出现了lodash、ramda等优秀的函数式编程工具库。函数式编程的纯函数,monad的概念有很多有优点,如更强的鲁棒性、更清晰简洁的代码、更好的代码复用。
编程范式中面向对象是我学得最早用得最多的编程范式,读完文章面向对象确实是有作者提出的这些问题,但也是可以解决的。我在实践中是尽量避免太深的继承,尽量使代码结构扁平化、模块化。最近正在学习函数式编程,接触到了很多新鲜的概念。在使用函数式编程实现快速排序的事件中,我发现函数式编程的写法执行效率不高,这需要更多的实践来做验证。也许对运行效率有影响是函数式编程的一个缺点吧。总之,我想做到的是集各家所长,使代码更易读,项目结构更加清晰。