首页 博文

我为什么不喜欢面向对象

2015-6-10 10:24:27 网络 A+

最近跟某位朋友讨论了一些工作上的事情,他目前就职于某世界500强IT公司,在他们现在做的一个项目中,整个系统构架(基于Web)是完全面向对象的(非基于jQuery的传统WEB,完全OOP,到处都是class,extend, override),而且他对这种框架极其推崇,不过他们经常加班到深夜,打开他们开源框架的GitHub主页,一个知名IT公司做的纯OOP前端框架仅仅有100多个Star(关注),笔者当时从直觉上觉得这里有问题,回去之后仔细反思,搜索了一些资料,算是找到了他们为什么这么累的原因吧。

面向对象(Object Oriented,OO)是当前计算机界关心的重点,它是90年代软件开发方法的主流,不过随着时代的发展,很多人对OO编程方法的看法也出现了一些变化;

最近在网上面看到有个名人喷面向对象的文章,我们可以先看一看:

“面向对象编程是一个极其糟糕的主意,只有硅谷里的人能干出这种事情。” — Edsger Dijkstra(图灵奖获得者)

“面向对象设计是用罗马数字做计算。” — Rob Pike(Go语言之父)

““面向对象”这个词包含很多意思。有一半是显而易见的,而另一半是错误的。“ — Paul Graham(美国互联网界如日中天的教父级人物)

“实现上的继承就跟过度使用goto语句一样,使程序拧巴和脆弱。结果就是,面向对象系统通常遭受复杂和缺乏复用的痛苦。” — John Ousterhout( Tcl and Tk 的创始人) Scripting, IEEE Computer, March 1998

“90%的这些胡说八道都称现在它很流行,非要往我的代码里搓揉进面向对象的石粒。” — kfx

“有时,优雅的实现只需要一个函数。不是一个方法。不是一个类,不是一个框架。只是一个方法。” — John Carmack(id Software的创始人、第一人称射击游戏之父)

“面向对象编程语言的问题在于,它总是附带着所有它需要的隐含环境。你想要一个香蕉,但得到的却是一个大猩猩拿着香蕉,而其还有整个丛林。” — Joe Armstrong(Erlang语言发明人)

“我一度曾经迷恋上了面向对象编程。现在我发现自己更倾向于认为面向对象是一个阴谋,企图毁掉我们的编程乐趣。” — Eric Allman(sendmail的创造者)

——摘自: 面向对象编程从骨子里就有问题

下面我们来分析一下他们为什么讨厌面向对象,过度追求OO到底有什么问题:

面向对象的生产效率

这是OO编程比较推崇的一点,不过我们可以先看看这篇文章: 如此理解面向对象编程 

在文章中,某“黑客”,将下面一段代码,“面向对象”成了7个文件,代码量由原来的几行变成了几十行。

public class PrintOS
{
 public static void main(final String[] args)
 {
 String osName = System.getProperty("os.name") ;
 if (osName.equals("SunOS") || osName.equals("Linux"))
 {
 System.out.println("This is a UNIX box and therefore good.") ;
 }
 else if (osName.equals("Windows NT") || osName.equals("Windows 95"))
 {
 System.out.println("This is a Windows box and therefore bad.") ;
 }
 else
 {
 System.out.println("This is not a box.") ;
 }
 }
}

文中的这位“黑客”将学院派的做法发挥到了极致。虽然这只是一个OO的教学文档,但确实很像OO的一篇高级黑,但我们仍能看出一味地追求OO会增加多么大的代码量。你现在明白你为什么需要IDE来辅助了吧? 在茫茫多的文件中寻找一个变量是多么的不容易呀。

面向对象的性能

这篇文章详细地讨论了OO的性能: Pitfalls Of Object Oriented Programming.

文中指出,从1980年至今,CPU的性能提高了近10W倍,但内存的访问性能只提高了不足10倍,原因就是内存的访问相对速度大为降低,OO的滥用使程序要经过很多间接过程才能访问到目标内存地址,

因而过度使用面向对象,会严重影响性能, 作者推荐优化数据和代码结构为先,并尽量使用KISS(keep it simple, stupid)原则来设计软件。

面向对象的可维护性

面向对象从一开始就要求我们完全了解各个子类的不同,并将他们的“共性”提取到父类里,从而实现代码复用, 在这个过程中自然形成了一种最强的耦合关系。这种设计方法在需求非常确定的情况下是有效的,但在实际生活中我们发现需求总是在开发过程中不断提出的,而且也总在变化,甚至跟之前完全相反,当你看到你精心设计的框架成为你需求变更的障碍时,你做何感想?

在一个完全OO的系统中,我们会不自觉地使用设计模式驱动型编程,正如这种编程的名字所说的,这种编程风格使用大量的设计模式,在你的程序中,四处都是设计模式,你的代码到处都是Facade,Observer ,Strategy,Adapter,等等等等。于是,你的程序要处理的业务逻辑被这些设计模式打乱得无法阅读,最后,也不知道是业务需求重来,还是设计模式重要,总之,实际业务需求的程序逻辑被各种设计模式混乱得不堪入目。摘自:各种流行的编程风格 

该如何面向对象

本文并不是完全否定面向对象的编程方法,经过上面的分析,我们已经可以发现,OO比较适合需求确定,耦合度高的子模块中使用; 但在一个需求在不断变化,业务逻辑在不断增加的复杂系统中(尤其是WEB前端系统),面向模块、库或者接口(module/package)也许是更好的选择。


自己一直对面向对象都挺抵触的,因为我觉的它把简单的事情弄的复杂了,我就吃个饭而已,非要把我从人-手-嘴-吃都定义一下,有必要那么麻烦吗。我的设计原则就是:灵活、高效、简单。

上一篇: PHP利用mysqli操作数据库方法总结
下一篇: 面向对象的缺点,你了解了吗
相关文章