java、jvm与.net

 现在sun已经被oracle收购了!也从侧面验证了作者的一些论断!

当然从技术上看,这篇文章也是分析很精辟。反正我自己感觉c很好用,java以及所谓的OO更多是一些概念。

Java在自取灭亡
 
 
    一个比较Java语言发展的讨论贴,非常精辟深刻,从语言的设计到系统架构的策略。Java是开源了,但是它的发展策略似乎是一种封闭的老路(sun的风格?)。原讨论贴详见 http://www.chinaunix.net/jh/23/1406918.html
    这里我整理了一下shan_ghost老兄的一些论述。
(1) Java语言不是平台无关,而是排外的,作为一个寄生者创建一个它自己独有的平台。
    安全剃刀是一种工具,它限制了裸露的刀片的锋芒,于是你可以很随意的用它来对付胡须——当然,它仍然可能伤到皮肤;但不可否认,它毕竟是比裸露的刀片安全便利许多。 
    所以,安全剃刀称得上是一项伟大的发明。剃刀则是另一种工具。它仍然可以对付胡须,但不熟练时容易伤到自己;相比安全剃刀,它还能用来裁纸、削果皮,在旧时代做手术刀用,它还能做其他很多很多事——可怕的是,拿它来杀人也极其方便。 用安全剃刀的,自然不会去把剃刀灭绝,更不会劝说那些买了剃刀的家庭把那种“锋利的凶器”销毁。 同样,用剃刀的,也不会去批评用安全剃刀的胆小、娘娘腔。 在财力许可的情况下,同时选择两个,显然更为合算。当然,我说的是C++和Java。 
—————————————————— 
事实上,上面的比喻并不恰当。因为计算机的世界很大很大。
只是: 
    当一个人“沉迷”于简单web编程时,自然想不到Java的世界有多大——算法和数据结构还有所谓的编程模式?谁用得着它。 同样,用惯了Java,很多人就以为世界和Java一样大,进而以为其它一切‘牛鬼蛇神编程语言’都应该淘汰,都应该拜倒在Java的脚下。 由于jvm的隔离,Java取得了跨平台便利的同时,也导致其本身的封闭,以至于那些本该、且必须被利用的硬件被Java群体选择性无视——无视了GPU,无视了PPU,无视了far cry。 
一个图像处理算法,利用了90年代老掉牙的MMX便可以直接提高8倍速率。 但是否开启MMX,是任何编译器所无能为力的。 因为,MMX本身就意味着精度损失(编译器敢自作主张替你选择近似算法吗),意味着使用不当将反而大幅度降低性能。 同时,一个必须在有MMX指令集的CPU和/或DX10显卡上才能跑的Java应用——有点不可想象吧?
    所以说,为了抹平平台差距,Java必须付出很多很多;多到很多时候都根本无法承受。 更坏的是,Java绝不会宣传这一点。别人不提,众Javar自然也乐得无视。 
——无视了GPU,无视了PPU,无视了far cry,无视了无数人投入大量资金添置的昂贵硬件。一旦要支持这些——甚至仅仅是要和其他语言“协同作战”——不能说Java绝对做不到,但要说“基本上不值得做”恐怕也不能算太夸大。 
——引用下某大牛的一句话: Java并非平台无关。JVM就是平台。 —而我要补充的是,JVM不仅是平台,它还是个很排外的平台。
    这种排外不仅仅表现在对待那些不寻常硬件的支持上,也表现在和其他语言的协作上。 甚至于,这种排外,也表现在很多Java使用者的身上,他们令人反感甚至厌恶。 相比之下,C#虽然是微软的私有玩物;但至少它不会排斥其他语言(微软一贯都很重视托管和非托管代码间的交互)。 跳出JVM的小圈子,外面的天地很大。 此外,Java还是一个“纯种”的OO语言——但在技术界,纯种只意味着限制。 比如另一个著名的“纯种”的结构化程序设计语言Pascal:大量程序员在课堂上学习它,很少有程序员愿意在工程中使用它。 事实上,虽然拼命热炒,但OO并不成功。除了游戏以及一些特殊领域,使用它并没有明显好处,甚至可能是事倍功半。 当然,虽然有种种缺憾,但Java不愧为一种优秀的语言。这只要看它在种种限制下仍然能够达到现在这个高度便可以看出。 一句话: Java是一种好工具,但它不是整个计算机世界——远远不是。 当然,我的意思并不是说c/c++就是整个计算机世界。 只是,C/C++从不会像Java那样自我封闭——它下不排斥汇编甚至机器码;中不排斥诸如PRO*C、CUDA之类扩展;上不排斥Java、LUA、perl等等脚本语言。 
——事实上,其他传统语言彼此间也都不存在排斥现象;相反,几乎每一门传统语言都会提供与C交互的手段,起码也能生成标准格式的二进制静/动态库。 除了Java。 事实上,由于JVM平台的缘故,Java天生就是排他的、拒绝和其他语言协作的。 我不知道这是不是Javar喜欢攻击C/C++的原因(呵呵,开个玩笑^_^)
    事实上,C/C++的强大,就在于它的开放性、包容性。 我亲眼见过有高人用Delphi写的一个底层图形库,可以自动根据CPU切换最优算法——Borland编译器编译出的二进制代码,绝不会比同时期的C++编译器差太多。 Delphi的失败,很大程度上就在于它是Borland的私有标准。这决定了它不可能像C/C++那样拥有“语言大师”——据说C/C++是世界上唯一有语言大师的编程语言。 没有真正开放的标准,是不会有人穷究语言的每个细节的;没有这样的大师,一门语言的潜力也就不可能被真正挖掘出来。 C语言很简单——32个关键字,48个运算符,如此而已。C++要复杂一些,但真正独有的东西并不多,很多特性还是从其他语言那里借鉴来的。 但只有C/C++可以充分发挥优秀程序员的全部实力。 无它,标准开放,可以无限制的深入研究下去,如此而已。  
前面说了,Java是计算机世界的很小一部分;C/C++也远不是整个计算机世界。
那么,也许有人会问了,那什么是整个计算机世界? 
C? 
C++? 
汇编? 
机器码? 
再加上Java? 
再加上其他各种语言? 
再加上操作系统? 
再加上各种算法、理论? 
都不是。 
计算机世界比以上种种全部加起来,还要大上很多。
不信的话,请用google搜索下这个数字: 0x5f3759df 
如果你以为这就是计算机世界的边界,那么不妨再去看看遗传算法——然后重新读一遍进化论。
 
(2) JVM创造出来的新地狱----新的封闭(对比.net--对所有语言开放)
    有JGPU,有没有JMMX?有没有JSSE?有没有JPPU?有没有JOPENGL、JDX 3D? JGPU又是哪个版本的JVM才有的?是否我必须要求用户下载最新的JVM1.6甚至(在GPU标准化之后)下载JVM2.0呢? JGPU本身有没有标准?能否向前/向后兼容?会不会像某些特性一样,依赖于某个特定版本的JVM实现呢?JNI和可以无缝集成进C的、成熟的CUDA相比,哪个更容易使用? 是不是说,任何“新”的、尚未被JVM支持的硬件,程序员都要自己在JVM操作系统上利用JNI自己写个驱动程序? 带着这么大一堆包袱,JVM又要置掌上设备于何地?准备发行多少个版本? 搞这么复杂,它相对于其他语言的优势又在哪里? 最后,一旦带上了这么一大坨子累赘,JVM和Linux、Windows、Windows CE有何区别?和VMWare、wine有何区别? 装一套操作系统,还不够吗? 
—————————————————————————— 
    以上,正是JVM的尴尬之处。 想搞定一切硬件,它基本上就相当于要重写一个操作系统——寄生操作系统的性能能比得上宿主操作系统吗?吹这种牛的人自己信吗? 事实上,JVM的作用也无非就是统一部分操作系统API罢了——要能彻底统一早统一了,轮不到JVM来做,微软/苹果等商业公司也不会允许它去做。 既然说到这里,可以看看所谓的JIT了。 前面已说到,所谓的JVM其实相当于一个寄生操作系统;而JIT则是即时把JVM上的应用程序编译成目标系统可执行文件的过程。 JIT从本质上说是一个编译器。这是Java代码实际执行效率(在某些情况下)可以与C/C++相提并论的根本原因。 
换句话说,Java表面上是解释执行的,但有了JIT,它实际上是编译执行的。 玩Linux的都知道,网上下的C/C++程序,多数都是先下载源程序、再在本地编译安装,然后就可以执行了。 从这点上说,Java和C/C++在本质上没有太大区别;而且,之前看过CSDN一则报道,说由于C标准的开放性、稳定性,C语言程序的跨平台能力是强于JAVA的;两者最终的差别,无非是一个要手动配置编译环境完成编译,一个可以自动完成而已。 所以,不必怀疑Java的速度——在它可以完美支持的范围内,Java和c/c++的速度是一样的。 但是,请记住JVM只是一个残疾操作系统,并不能支持所有硬件,操作系统厂商也不允许它这么做;即便允许,等它真成了操作系统,它也已经落后于C#了。 
    因为,可运行C#的虚拟机是微软操作系统原生支持的,天生支持一切微软操作系统可以支持的硬件。不仅如此,就连C/C++都可以编译成托管代码,在这个虚拟机上运行——这个虚拟机的起点,可比JVM要高太多了。 同时,前面已经说过,微软一直相当关注托管/非托管代码的交互问题;C#生成的托管代码也可以直接编译成dll供C/C++调用。 
换言之,在微软平台上,C#、C、C++、VB等等编程语言的地位是等同的,可在各个层次上交互的。 这,又比Java的孤家寡人高明太多。同时,只要Linux等操作系统也实现了兼容的虚拟机,那么托管的C/C++代码就可以直接运行其上——这才是真正的跨平台。 而JVM,微软已经断然取消了对它的支持。 没有强势的传统操作系统做后盾,JVM就是无源之水。 
———————————————— 
    也许可以说,小看微软智商的人,很难有好下场。 那么,为何微软不肯继续支持JAVA?为何微软不惜激怒SUN,也要把JAVA微软化、哪怕是因此失去Java授权? 因为微软要保护自己的利益。统一操作系统API这个任务,即便微软不能完全掌握,也一定要拥有足够的发言权。 
既然已经和微软撕破脸皮,那么,要么JVM彻底发展起来,逼微软就范,完成统一操作系统API的大业;要么就蜕变成一种流行语言的解释器——除了语法像C++因而讨人喜欢外,其他方面并不比RUBY、python、LUA等语言高明。 至于JIT——python、lua以及新兴的很多函数式语言也是跨平台的,也是可以编译成二进制代码执行的(虽然执行方法不同,但原则上,起码其中的相当部分,是同样可以达到编译语言的效率的)。 更何况,微软还推出了另一个可以支持C/C++等多种语言的新虚拟机,和与这个虚拟机配合的、另一套字节码、JIT规范。 
—————————————————————————— 
    事实上,这是一场争夺新兴的即地编译市场的战争。现代处理器的速度已经足以支持即时编译各种语言源码并执行;而所有的高级语言都是跨平台的,只是在一些特殊地方(操作系统API上)有一些细节差异罢了。 那么,只要在操作系统中给出一个合适的中层抽象,原则上所有语言都可以解释执行;而这个中层抽象还可以进一步(以极低的消耗)编译成本地原生代码。 现在,谁掌握了这个全世界都认同的中层抽象的定义权,谁就在未来立于不败之地。 这一点,微软看的很清楚;sun也很清楚,但他的野心太大了点,大到不知道自己吃不吃得下整个市场的程度。 不出所料,Java统一新兴的即地编译市场的野心被挫败了,并还必将在未来为自己的封闭付出更多代价。 
———————————————————— 
总结一下:
1、JVM是虚拟机,但并不仅仅是虚拟机 
2、要支持所有硬件,JVM必须发展成“伪操作系统”,或者至少是得到操作系统毫无保留的支持 
3、微软不会允许另一个操作系统的出现,尤其是它还带着统一操作系统接口的野心时 
4、sun过于强势。与微软谈崩是第一大败笔,JVM排斥其他语言使用者是第二大败笔 
5、JIT并不仅仅可用于JAVA。只要有合适的中间层,任何语言都可以玩即地编译——微软已经这样做了 
6、JIT是未来的趋势,但JAVA不一定是。两者根本不是一回事——这点微软看得很清楚。 
7、JVM同样和JAVA不是一回事;同样,JVM也不等于中间语言。这点微软同样看得很清楚。 
8、中间语言的定义是争夺焦点。今后JVM可能会得到开源组织的支持,微软则肯定会继续推自己的托管代码 
9、两者合流是大势所趋,并且将来的中间语言会同时支持所有流行编程语言(也就是支持所有编程语言编译成中间代码,然后再在特定平台上使用JIT编译成目标代码——事实上,微软已经做出来了) 
10、如果不能合流,那么JVM也将提供各种流行编程语言的支持 
11、某种程度上,Linux/unix系统里,C就相当于中间语言。其他如C++、Pascal等等,都曾经是先编译成C代码,然后才进一步编译成二进制可执行文件。 
12、关于Java的讨论常常很扯淡。原因之一就是没有把Java本身、JVM、中间语言以及JIT分开来说——也正是这一整套体系让他们成了孤家寡人。这或许也是别的如python等语言的拥护者就不那么有攻击性的原因之一。
 
(3)开源不等于开放
1、前面说过很多次了,JVM和.net只是两个通用平台,或者你可以把它们看作两者新兴的轻量级虚拟操作系统。如此而已。 
2、无论是C#还是Java还是C++,原则上都可以编译成这种新的轻量级虚拟操作系统上的代码——微软已经直接暴露了本质: 托管代码和仅包含托管代码的DLL。 
3、既然都可以编译成这种新虚拟操作系统上的动态库,那么还有所谓的库、架构的区别吗? 之前,Java是借助JVM的封闭与垄断,禁止其他语言在二进制层面直接与它的支撑库交互。一旦它开放了,看看GTK+,Linux上有几种语言不能与之交互? 微软已经用实际行动证明,即便是C++,在避开一些底层特性的情况下,也是可以编译成中间字节码的(即所谓的托管C++)。 这就好象Borland的C++ builder直接用了Delphi写的VCL库一样,既然有了二进制兼容的动态库,你以为cpper真的会“饿死不用Java库”吗? 
C++的特点就是大而全,所以用户必须学会自己裁剪,自动避开那些并非非用不可的特性。
    比如说,如果只是用stl容器的话,你完全可以把C++当Java来用——没有指针,没有弱类型,有不完全的垃圾收集(C++09后就有完全版的了)。 凭借这种可裁剪性,C/C++几乎可以和其他任何东西无缝结合——这也正是C/C++体系的威力所在。 说白了,Java的市场策略无非是: 利用封闭的JVM排斥其他语言,花大力气开发方便使用的库以吸引用户,然后在排斥了其他语言代码的情况下借助跨平台优势和丰富强大的库狂推Java。 
.net则准确的击中了这种策略的软肋,逼JVM去接纳其他各种语言;而一旦JVM接纳了别的语言,Java已有的那些库也就自然而然像GTK那样开放了;这时候,哪怕是asp都可以是强悍的,可直接利用Java已有基础构架的。 没有什么通用语言是天生支持/不支持什么架构的。就好象python也可以轻松使用C写的GTK一样(哪怕GTK是一种“C写的面向对象图形库”)。
4、一直没有理解“开放”二字的含义。 
    开源不等于开放。允许其他体系在不损失性能的情况下、很方便很自然的交互才是开放。所以,请摒弃Java灌输给你的错误观念——JVM和.net都不是语言。它们是平台。 
所不同者,JVM是封闭的、仅支持Java的平台,而.net是通用平台。 换言之,Java是靠JVM的封闭优势和其他语言展开不公平竞争的;而精明的微软正是意识到了这一点,才用.net狠狠将了它一军,强迫JVM给其他语言平等竞争的权利。 JVM的开放,必将给Java带来前所未有的冲击——有人就喜欢asp,借助已有的Java库,asp很容易就能变得更强大,这就是对Java市场的侵蚀。 
同样,使用托管C++就可以得到和Java几乎一样的便利,还可以随时“超点范围”,学学C++的底层东东,何乐而不为。这就是另一种冲击。 当然,微软的算盘打得很不错,实际能做到几分,只能靠事实来验证了。 
5、关于.net的推广,只能说不能小看微软的手段。 况且,就连微软不喜欢的wine都有人自发搞出来了,Linux下搞个微软期望推广的.net支持,有那么难吗? 
6、开源界不是不喜欢C++,而是不喜欢不问青红皂白的OO。 或者说,他们讨厌教材上那种死板的OO,讨厌死板的OO框架。 
这里或许需要多解释两句。
    首先是何谓OO? OO是一种协议。这种协议规定了一套机制,这套机制可用来实现多态;具体机制可能有无数种,但不管具体如何做,只要能支持多态,这机制就是OO。 既然是协议,就一定会有实现。 所不同者,就是这个实现是什么样子、使用什么机制。 所有的OO语言,其实都是预设了自己的OO协议和OO机制;所不同者,只是这套协议允许不允许你抛弃或替换。 比如说,Java就不允许抛弃它的OO机制,不管需不需要;而C++则可自主选择。 开源界的那些牛人们又有一套看法。 对他们来说,用OO语言开发,无异于接手别人做了一半的、不开放源码的、仅实现了OO协议的一套烂摊子,然后再修修补补搞出自己的一套系统。 最糟糕的是,一旦换一个编译器,或者仅仅是用了同一个编译器的不同版本,烂摊子就可能轰然倒塌,或者是出现这样那样的问题。 同时,由于具体OO实现的问题,还要注意诸如自动类型转换、默认拷贝函数等等很多衍生细节。这都加大了项目复杂度,加大了项目失败的可能。 
    与其如此,不如他们自己动手,制定精确合乎自己需要的、每行代码都可见、每个行为都可以精确控制的OO协议,然后在这个协议之上开发精确可控的、可移植的系统。 这方面的典型例子,不妨看看GTK。看看它是如何在不使用任何诘屈聱牙的语法和/或hack手段的情况下,用C实现OO以及类型安全的。 事实上,开源界是提倡用C++编译器重新编译C代码的——强类型的C++太容易揭示某些隐藏错误了,STL也太好用了。这些都很好,笑纳。至于它的OO……谁喜欢谁用好了(俺就是不成器的、不挑剔C++的OO部分的菜鸟之一)。 允许每个人根据需要裁剪功能,这也是C++的魅力所在。
 
(4) Java真的是在做OO吗?
    所谓OO,本质上其实就是“实现了兼容的interface,因而这一系列组件可以相互替换而无需改变上层算法”,如此而已。 优秀的软件往往都有很好的“抽象”。所谓抽象,就是抓住事物的本质,找出它们的共同点——比如: 一切都是文件;文件可分为字符文件和块文件…… 换言之,当你还在为这是U盘、那是硬盘、这是网络硬盘、那是subst虚拟出的磁盘等等等等伤透脑筋、甚至写出数万数十万行代码的时候,人家一句“一切都是文件,文件只有如下几个关键属性:输入,输出,缓冲”,然后一个循环就轻松搞定了一切! ——这就是OO,这就是OO的威力,这就是OO的本质。 
    而要实现“一切都是文件”,需要什么? 只需要“一切都支持fopen fwrite fread fclose(注意这里有两层含义:1、必须有这几个接口函数,2、即使还有其他接口函数,上层逻辑也不能调用。其中1对应接口继承,2对应封装)”,没了。 至于具体细节,另外用特定的xxctl微调一下即可;而这个xxctl,也归为几个大系,不同设备要实现不同的xxctl(就好象继承xx子类一样,但没有任何性能代价)。 说一千道一万,没有如同上面那样真正抓住事物本质的话,写再多class,你的设计也和OO没多大关系。 
    既然OO只和设计有关,那么虚函数表是什么?公有/私有继承又是什么?RTTI又算什么? 它们不过是应OO设计的需求而给出的“语法糖”而已;尤其是私有基础和RTTI,根本就和OO的本质没有任何关系。甚至于,RTTI很大程度上,是在不适合OO的领域生搬硬套OO(或在适合OO的领域做出了不合格的设计)、进而不得不“回归杂乱”,重新搞出的四不像。侯捷老师说过,凡在面向对象领域写出根据对象类型不同做不同操作的if或switch语句的家伙,都应该自己抽自己一个耳光——而RTTI,除了写根据对象类型不同做不同操作的代码,还能做什么? 当然,侯老师说的有点绝对。RTTI在某些场合还是必不可少的,但一旦把它当作OO必不可少的一部分来考虑、使用,可想而知,这位恐怕永远也学不会面向对象设计了。这就是一个怪圈,一种束缚。 OO本来是一种直指本质的设计风格;然而,一旦把这个概念表现为类,表现为继承,立刻就模糊了目标——为类而类,为继承而继承;糟糕的设计导致无法OO,于是又搞个RTTI在号称禁止非对象的东西出现的编程语言里把根据对象类型的if/switch找回来!
    这不丢人么?! 更有甚者,和高明设计所作出的自然而然的约束不同(就好象大自然约束我们永远不能超过光速一样),OO语言是靠着硬性规定来约束程序员不违反接口约定的。 
为了保护这些约束不被违反,OO语言引入了“权限”语义(这方面矫揉造作的例子一时还没想到特别典型的) 
为了用户能定义自己的约束,比如对于“必须自己给出具体实现”这个约束,C++语言加入了纯虚函数,Java搞了个接口类(interface) 
为了在用户瞎搞的情况下不产生内在冲突(如菱形继承),如Java等语言禁止了多重继承。 
为了防止过分的保护约束住用户的手脚,它们又搞了很多类似RTTI的东西,以便让用户在封装上掏窟窿……
    乱花迷眼。只使用OO语言的人,往往反而陷入OO协议实现以及这些协议实现的漏洞以及协议漏洞的补救等等细节中出不来,反而永远学不会真正OO的设计。 换言之,他们学的是某种特定的OO协议,而不是OO本身。 被某种特定的或流行的OO协议实现本身所限制——这,就是OO语言使用者的心智负担。
 
(5) 到底什么是RTTI?
    COM的QueryInterface是为了和其他语言在二进制层面上兼容而设。 换言之,在有源码(或仅仅是头文件)的情况下,编译器一定知道整个继承树的一切细节,无论如何转型(除了强制转型)都不会出现问题。 
本质上说,QueryInterface是一个通过元数据在其他语言中通过一个接口找到同时实现的其他接口的接口。或者说,它偏偏正是“以自定义的UUID作为元数据,以便在二进制层面查询接口有无实现的、对C++做的扩充。这个扩充是为了让其他语言在无源码的情况下都能知道某对象实现了多接口这个事实”。 相比之下,RTTI只能对同一种语言(对C++来说,甚至要限定同一种基础库)起作用、并且只要一个声明接口的头文件(对C++来说,由于没有规定实现细节,没有头文件就想在二进制层面重用是不可能的),它就是完全可以避免使用的——和COM的QueryInterface无论是适用范围还是目的都是不同的。 ——请不要把更本质、更重要的元数据概念与RTTI混淆。
最后,重复一下我的观点:  
1、我不挑剔各种OO语言的协议实现,因为我知道该如何取舍它们。 
2、我不认为某语言特定(或被公认有效而通用)的协议实现就是天经地义、不可更改的——比如禁止不紧张多继承;提供/不提供元数据和RTTI等等。 
3、C++是一个很好的工具箱,但修理手表的时候我不认为有把锤子拿出来的必要。 
4、你有了一匹好马,所以最好配个好鞍;你有了好鞍,所以要有把好剑;你有了把好剑,所以需要一副盔甲;你有了沉重的行头,所以需要另一匹马帮忙运送装备,于是你又需要一个仆人来帮忙牵马,还得找个马夫来照料它们;人多了,衣食住行都得靠你,于是你又不得不再买辆马车;买了马车,为了配上你华丽的长剑,你又需要漂亮装饰品…………………………………… 
事实上,我以为一切讲解C的OO实现或汇编实现OO的书,在项目设计角度看,都是垃圾。 好的设计只有一条路:抓本质。这就好像物理定律一样。这世界多复杂,多抽象又多具体! 
牛顿3条定律,足够你走遍天下。 同样,图形,动画,时钟,精灵,音乐,音效,碰撞检测,3D贴图,各种池,各种回收算法……这乱糟糟的一切,是怎么变成war3地图编辑器里的角色和触发器的?又是如何和LUA配合起来的? 
———————————————————————— 
    所谓的OOC之类东西,根本就不研究上面的本质性问题,而是哗众取宠般的去用C模拟C++的某些特性——我说过不挑剔所有OO语言的OO协议,但这不代表我就对某个特定的协议感兴趣。 模仿OO协议,和OO设计之间连一星半点关系都没有。 所谓OO设计是这样一种东西: 通过深刻的思考抓住事物的本质,然后针对本质(而不是表象)写程序;既然本质是不变的、精悍的,针对本质写出的程序自然也就是不变的、精悍的。 这方面的典型实例,不妨看看GTK+。 而所谓OO协议则常常是这样一种东西: 它规定了一整套的繁文缛节,以便于你使用它来表达自己的种种设计思想(尤其是什么是本质,也就是基类或接口),以及这些思想中的种种细节——并且往往还走偏到“要求你使用它表达一切思想”的地步。 事实上,OO协议经常起的作用是限制人的思想——不敢动用协议不支持的功能;不敢以另一种思路达到使用协议的同样效果;盲目使用协议提供的、违反了OO目标的扩展;甚至在实践中被协议的繁文缛节所困扰,搞出很多本来根本不需要宗教仪式——比如C++的拷贝构造函数、单参构造函数被用作自动类型转换等等。 OO协议和OO本身毫无干系。OOC和面向对象同样毫无干系。
 
(6) Java能帮我们做出好的OOP软件?
    某种程度上说,是的。但我认为这里正是本质所在。OO的目的是为了什么?抽象。抽象到一个循环不加判断的处理所有性质类似的事物的程度。 只要能达到这个目的,管它什么实现手段。 
    OO三要素不就是 封装,继承和多态吗?那么,泛文件这个“抽象”,封装目标没有达到吗? “继承”根本上说是代码重用,泛文件设计有没有达到? 多态根本上是以同样手段处理相似事物,只是后台逻辑不同,这个泛文件设计有没有达到? 事实上,所谓OO三要素,不过是对已有的、成功的、在没有面向对象概念的日子里开发的那些系统的成功之处的提炼与总结。 只有封装,才能保证适应变化而外部表现不变。 继承是在封装的基础上,保留旧封装的一些行为、扩展一些新行为并保持兼容。这个特性保证了可替换性(也就是多态的基础) 多态要求的是封装外在表现的一致性——只有以相同方式封装相似事物,才能达到这个效果。 OO协议是一根拐杖,一个篱笆。人们以为靠着这根拐杖、这个篱笆的限制,就能让新设计的系统自然而然的体现出如上的“幸福三要素”。 这个目标实现了吗?可能这样简单实现吗? 这个篱笆,这根拐杖,是否反而使得人们淡忘了本来的目标?是否反而导致人们去研究拐杖的瑕疵、篱笆的漏洞而不是在设计上精益求精? 甚至于,这个协议本身,是否真的做出了正面的引导?
    刘德华反串女角扮演芙蓉姐姐,他还是刘德华;芙蓉姐姐扮成刘德华的模样假唱《忘情水》,她仍然是芙蓉姐姐。 
    同样总结一下: 
1、面向对象程序设计本质上是一种抽象准则,达到这个准则的系统就是可重用、易维护、易扩充的 
2、要达到面向对象的高度,并不一定需要任何流行的面向对象协议里用到的技术。 
3、所谓面向对象语言,其实是一种提供了一套可以表达面向对象设计思想关键要素的协议的编程语言 
4、使用面向对象协议,你可以让任何垃圾表现出面向对象的三要素;但它们仍然是垃圾 
有个笑话说,古代一大哲学家,好像是柏拉图吧,说人是什么?人就是无毛的直立行走的两足动物。结果他的学生就把一只拔光毛的鸡扔他面前,说这就是人。人是面向对象的话,柏拉图关于人的定义就是面向对象协议,而扒光毛的鸡符合所有柏拉图关于人所定的指标。 同样,泛文件是面向对象的,C++/Java定义了一组面向对象的协议,然后fans们仔细研究着这个协议的点点滴滴,搞出了一只又一只无毛鸡;并且越是研究到细枝末节,越是容易搞出无毛鸡。,泛文件设计不穿OO的外衣,它也100%达到了OO的目标; 很多写了无数class用了无数设计模式拿Java这样纯种的OO语言搞出来的系统,仍然可能是个连结构化目标都没达到的垃圾。 甚至于,林依伦浓重的鼻音被无数他的歌迷喜爱;但大家是因为他的歌而喜欢上了鼻音而不是因为鼻音才喜欢上了他的歌。 越模仿他的鼻音,你的歌声也就越发无法让除了林的少部分fans以外的人接受。这就叫病态的爱好。 OO和抽象,也是同样的关系。 好的抽象应该达到OO三要素的程度;而刻意模拟甚至强制出来的OO三要素,仅仅是个拙劣的模仿。 OO给人一种假象,好像一旦用了OO语言提供的OO协议,这个设计自然而然就具备了OO三要素,接下来只需要搞一些繁文缛节的宗教礼仪就够了;甚至进而完全抛弃了抽象,拿着对象发现方法论随便一对付就以为三要素已经满足了,然后就完全钻到繁文缛节里研究更高深的学问去了。
 
(7) Java到底想干什么
    其实我是很欢迎Java或别的什么语言取代c/c++的,只要它有这实力。 甚至可以说,Java刚推出那时候,整个c/c++社区几乎是万众一心,等待它取代C++的。 可惜,它没做到。不光没做到,还变得热衷于耍嘴皮子了,喜欢到处吹嘘自己比c++快什么的,好像它就是当之无愧的王者一样。 
    事实上,关于JVM的封闭性问题(这个问题也是近年才有所好转),以及.net等问题,我其实一向也是懒的关心——倒是对JIT很感兴趣,认为那是将来的必然趋势。 所谓WPF,其实是微软的下一代GUI接口(当然,写游戏还是不能用这个,效率问题仍然没解决);最近热炒的、要取代flash的silver light就是它的一个子集——GUI接口的子集都有叫板flash的实力,由此也可见这个GUI接口的设计是如何的强大和成功。 互联网的出现,导致对软件跨平台能力的需求变得急迫起来;而web页面很容易就能流行开,进而成为事实上的工业标准。Java就是抓到这个空子发展起来的——不是因为这门语言设计得有多成功,而是这门语言依托的那个中间语言+JIT的设计太成功了。 事实上,操作系统也有个posix标准。记得WIN NT就有个posix子系统,号称可以兼容符合posix标准的unix代码,但似乎并没有被人接受——这或许就是微软的跨平台尝试。 但他走错了路。unix并不仅仅是一些API标准,它还包括大量的脚本以及其他配套程序——包括那个很无厘头的yes。这和Windows平台的设计风格格格不入。 
    微软确实狠。sliver light如何?很轻量级,而且仅仅是个基于xml的标准。很容易就能扩充出支持,但——没有3D。借助IE的垄断地位,其他系统无论如何也得支持sliver light。这就是第一步。 至于C#能否取代C/C++,至少在微软目前的架构里是不可能,也没有这种迹象——即便有操作系统的支持,有的和硬件关系密切的东西也不是虚拟机所能搞定的。 事实上,和Java不同,微软根本没有消灭C/C++的必要(sun也没打算消灭C/C++)。因为Java是一套独立的平台——而且在初期它显然是想吃独食的,所以即便c/c++以及其他语言都可以编译成JVM中间语言,sun也不允许这样做。甚至就连Java标准他都要紧紧捏在手中。如果不是这样,而是从一开始就允许C/C++以及其他语言编译成JVM中间字节码的话,恐怕JVM早成事实上的工业标准了。 当然,如果这样做了,那么sun也就失去了靠卖Java以及相关库、解决方案等等大把捞钱的机会。 所以,尽量多吃掉包括C/C++在内的其他所有编程语言的市场,对sun来说是最优策略。——显然,sun也根本就没打算消灭C/C++,他只想尽量扩大市场份额,如此而已。 对微软来说,他担心的是自己在操作系统方面的垄断地位受到挑战——所以他不担心Java,只担心虚拟机;他不担心程序员不喜欢C#,只担心程序员喜欢Linux或其他什么。 所以,只要有人愿意用他的CLI,不管是用什么语言,他就很满足了。 毕竟,vc也是他的拳头产品。 
    事实上,C/C++的市场份额虽然降低不少,但它的实际影响力丝毫未减。这从Java初期号称C++--,微软的C#也沿用C/C++风格(甚至就连名字都要刻意和“已经日薄西山的C/C++”扯上关系)就看得出来。事实上,不管吹得有多厉害,不管是微软还是sun,都明明白白知道,C/C++的地位是不可撼动的——这么多年了,Java的定位有所改变吗?微软新设计的C#的定位又如何? 说白了,微软和sun这么做,都不过是为了拉那些学了些C/C++、但没必要(或没能力)用它们的那帮人过去——看吧,很像C++吧?而且没有吓人的指针! ——微软和sun都不傻,他们从来没有向那些必需C/C++的领域里伸过哪怕一根手指头;但有些人被他们忽悠傻了。就这么简单。    所以,争吵语言的优劣确实毫无意义,尤其是很肤浅的纠结于几个公说公有理、婆说婆有理的特性上面的时候(甚至是拿JIT出来吓唬cpper的时候)。 但另一方面,正确认识一门语言确实有必要——不光要知道其利,还要知道其弊,最终还要找到适用范围。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值