他们为什么说面向对象有问题,探讨面向对象的一些缺陷


发布者 newghost  发布时间 1384852842000
关键字 心得体会  分享 

最近跟某位朋友讨论了一些工作上的事情,他目前就职于某世界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)也许是更好的选择。




相关文章

你已经毁了JavaScript

痛苦的Java程序员

Angular之类的框架将被库取代







回复 (14)
  • #
  • #1 夏绯 1385046127000
    总感觉哪里不对……
  • #2 占有欲 1385076653000
    能看到吗?
  • #3 您的豪礼速点进h8377 1385076534000
    完全同意
  • #4 幸运小马 1385217797000
    Great article, 说的是极好的……
  • #5 有田十三 1386846624000
    好坏没有绝对一说。因地制宜吧。
  • #6 海燕海报 1390371733000
    被雷到了。 “面向对象编程是一个极其糟糕的主意,只有硅谷里的人能干出这种事情。” — Edsger Dijkstra(图灵奖获得者) 特意查了一下,Edsger Dijkstra 曾经提出“GOTO有害论”。2002年8月去世,不知道他是什么时候说的上面这句话。
  • #7 aces_c 1394432956000
    1.晚上经常加班和面向对象是怎么扯上关系的? 2.作者偷换概念,用那几行if...else...来套oo的思路,然后得出oo有问题的结论。这结论怎么出来的?咋不用一个小型系统从建模开始分析这种例子来辩驳面向过程呢? 3.面向对象和面向模块完全就是两个不同层面的东西好吧,可能我孤陋寡闻,只听过面向领域编程,没听过面向模块编程啊。。。
  • #8 有志竟成 1395269687000
    @海燕海报

    他应该没有说过这句话,他说过的最相近的是 “I don't think object-oriented programming is a structuring paradigm that meets my standards of elegance”。 语气上要弱了很多。
  • #9 zjhiphop 1396409544000
    不同应用场景之下, 不同的取舍, 没有银弹, 只有权衡。
  • #10 路大大 1398398718000
    问题都是在与有太多人只会生搬硬套,完全不会去分析是否有需要。 所以,在有些情况下,不考虑实际情况,一种思维走到底,就会闹出笑话。 事实上,对于是否OO,用哪种语言,已经有点宗教化了。我们其实要警惕的是这一点。 你要相信,这世界上,万事万物都有其优缺点,都有其试用的范围。不要一概而论。 只有我们成为其主人,才能有效权衡。
  • #11 樊乡地 1412876330928

    这种设计方法在需求非常确定的情况下是有效的,但在实际生活中我们发现需求总是在开发过程中不断提出的,而且也总在变化,甚至跟之前完全相反,当你看到你精心设计的框架成为你需求变更的障碍时,你做何感想? 对这句很不认同!如果需求一直不断变化(完全相反...),那项目怎么可能做的出来?! 面向对象第一步就是分析需求,你连自己要怎么都还搞不懂,就开始盲目去实现,怎么做都错啦 = = "

  • #12 路上飞 1412896282464

    @樊乡地 #10

    快速迭代,不断试错,逐步走向成功的彼岸。这是互联网时代的王道。 ——雷军

    推导一下,"错则改之”,哥们,你说需求会不会经常变?

  • #13 Cory 1417319046246

    这篇文章的立足点就有问题,OO才是能快速适应变化的解决方案。代码是不断的变化,不断的重构,来进行维持的。 而且,刚开始的例子,是典型的结构化思想的写法,毫无OO体现。

  • #14 丁丈臣 1423504121238

    其实大部分问题是糟糕的程序员写出来的糟糕的OO代码造成的。。。这类人换个XXP的方式来写代码后,一样会有人喷XXP有问题

微信扫码 立即评论