面向对象(OOP)是编程语言发展中的弯路吗?为什么?

一切皆对象的口号显然有点过了,但也不至于说走了多少弯路。这个问题跟「子类型(subtyping)是不是错误(ill-defined)的东西?」有点类似,就是程序员突然发现工具箱里面有些工具没了的话好像也没关系,就开始怀疑它们是不是多余的或错误的设计。OOP是个模糊的概念,它不仅仅指程序语言的那些特性,OOP之前必须先OOD (Object Oriented Design),不可能脱离OOD谈OOP,如果只谈概念,我们来看看:封装:到底什么是封装?私有方法?那 Haskell 只导出 Smart Constructors 算不算?继承:OCaml module include 算不算?Typeclass hierarchy 算不算?多态:参数化多态也叫多态啊!如何才能划出一条清晰的边线界定OOP?对象内部状态?这可就麻烦大了,所有非纯函数式编程都不可能完全避开内部状态。如果你就是要原教旨 Pure FP 大法好?那……你开心就好:type MonadStackHell a b c = AppT (MaybeT (ReaderT a (StateT b IO))) c不要跟我提Extensible effects,既然Haskell都只能做到这种地步,为什么它就不算走弯路?有些人不爽的地方可能在于,数据和行为是两个不同的维度,而现有的OOP语言都把数据和行为绑定到了一起,不得不用 Extensible Visitor Pattern 绕弯。可这本身就是难解之题,Haskell 里面虽然可以很方便地用 Typeclass 扩展方法,但添加新的数据却成了问题。Data types à la carte 那种方式虽然可以无限扩展数据,但却增加了转型的运行时开销,鱼和熊掌不可兼得,OOP 语言选择了另一条路,但子类型虚函数又会增加方法调用的运行时开销。(我也不提 Object Algebras 只从编程语言角度思考就进入了死胡同,我们要从OOD的角度看。在设计时自然说 A student is a Person,继承了Person的属性和方法,Haskell不支持Record继承,难道在设计时也说Student包含一个Person?然后白板上 Functor、MonadTrans、Constraints 满天飞?这样看将 Subtying 和 Inheritance 捆绑在一起还真是非常贴心,要是只说Student是Person的子类还不够,还要加一句Person有的ABCD接口Student都继承实现,那就太啰嗦了 。对象思维方式显然更易于描述现实中的大部分业务模型。它有它的局限性,但离泛滥还远着呢,我看到更多的是很多程序员根本不懂面向对象设计,甚至根本就没有 Design 这一步,从这方面来讲,不但不算是弯路,甚至还应该继续大力推进。问题的关键并不在于OOP,而在于错误的OOD。如果OOD本身就是错的,那么正确的又是什么?我觉得现在我们还不能完美回答这个问题,有一个词呼之欲出: Language Oriented Design,但是我们还有很多路要走,而且我很怀疑有些业务逻辑天生更适合用OOD描述,换成LOD只不过是重新发明一个OO DSL而已。






在面向对象编程范式成为主流的今天,为何有此一问?我想暂且归于辩证思维。但基于此思维模式下回答这个问题并不容易——完整地回答这个问题,需要从编程范式的理论基础、发展历程及应用场景来阐述。这里就抛开那些长篇大论,就这个问题本身而言,存在即合理,我们不能简单地去归类“它”是错的还是对的。为了避免话题引起类似OOP VS Functional P或OOP VS Procedural P的纯粹的对立性争论,例如:喜欢面向对象编程的开发人员认为,在创建程序方面,它比函数编程方法更好,相反,支持函数编程的开发人员认为,他们的方法更好。OOP的支持者认为,继承和封装的概念更易于管理和操作数据,而函数式编程的支持者认为,数据和方法的分离以及使用该方法实现的高级抽象,为错误留下的空间非常小......这类争论也将是无休止的;所以我试着从OOP的优缺点来看待它。

优点

作为一种能被多数开发语言所采用的编程范式,必定有其巨大的优势所在。

  • 提高的软件开发效率

OOP是模块化的,因为它在基于对象的程序开发中提供了职责分离。

OOP也是可扩展的,因为对象可以被扩展以包含新的属性和行为。

对象还可以在跨应用程序中重用;面向对象编程语言提供了丰富的对象库,在项目期间开发的代码也可以在未来的项目中重用。

由于这三个因素(模块化、可扩展性和可重用性),OOP提供了比传统面向过程的编程范式有更高的软件开发效率。

  • 提高软件可维护性

基于上述原因,面向对象软件也更容易维护。

由于设计是模块化的,系统的一部分可以在出现问题时进行更新,而不需要进行大规模的更改。

  • 更低的开发成本

软件的重用也降低了开发成本。通常,更多的工作被投入到面向对象的分析和设计中,这降低了开发的总体成本。

  • 更高质量的软件

更快的软件开发和更低的开发成本允许在软件验证中使用更多的时间和资源。

尽管质量取决于团队的经验,但面向对象编程往往能够产生更高质量的软件。

缺点

  • 陡峭的学习曲线

对一些人来说,面向对象编程所涉及的思维过程可能不是很自然,需要一些项目经验来理解。

一些关键的编程技术,例如对象设计原则和设计模式,需要有足够的OOD经验才能真正领会其意图。

  • 更大的体积

面向对象的程序通常比面向过程程序包含更多的代码行。

  • 性能较低

面向对象程序通常比面向过程的程序慢,因为它们通常需要更多的指令来执行。

  • 并不是所有类型的问题都适合

有些问题适合函数式编程范式、逻辑编程范式或面向过程的编程范式,在这些情况下应用面向对象编程不能开发出高效的程序。

总结

没有哪种方法是放之四海而皆准的,脱开实际应用场景单论哪种方法也不可取。毕竟所有的努力是为解决问题,吸取各种方法所长,灵活运用方是正道。




不是弯路,是一种抽象封装,便于维护扩展!!!

展开阅读全文

页面更新:2024-04-14

标签:弯路   范式   函数   思维   对象   概念   成本   错误   过程   类型   程序   方法   更多   数据   科技   软件

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top