探讨Java与Ruby语言迁移时的安全性问题

时间:2017-11-15 11:44

  
  通常来说,“使用Ruby具有风险”是一种普遍的看法,这存在一定的原因。因为使用新的语言天生是有风险的。随着Ruby on Rails逐步进入到主流的开发领域中,这样的风险将会随时间逐渐降低,因为有逐步增长的开发者群、组件(或称作gems和plug-ins)相关的书籍、以及业务合作伙伴与你沟通交流。但同时你也可以听到主流的观点指出“使用Java是安全的”。对于这种的观点,我持有强烈的反对意见。随着语言的膨胀,这样的风险通常也会增长。为了便于理解在目前在这些观点上正发生什么变化,投入点精力去研究Java最初的应用情况是值得的。 

  新技术采用概况

  许多分析家拥有技术应用所需的描述模型。其中最为流行的模型是定义在Ruby的Web开发框架Iowa中,用来描述农产品的应用,稍后在一本由Geoffrey A. Moore写作的名为《跨越鸿沟》(Crossing the Chasm)的书中,被用来描述技术内容。在书中,Moore分析了技术应用周期中存在着的五个截然不同的群体:

  技术专家。这个群体倾向于采用新的技术。任何一种有前途的技术都会引起这个群体的注意。

  先行采纳者。不管这项技术是否在主流技术中取得成功,这个群体都将会采用新的技术来提升竞争优势。

  实用主义者。一旦新的技术进入主流应用,或是有足够陡峭的增长曲线来保证技术将得到广泛采用,那么实用主义者就会积极采用新的技术。

  保守派。只有新技术成为必须的时候,他们才会考虑采用新的技术。

  怀疑论者。这个群体可能很晚才会采用新的技术,或者也可能永远只使用某一特定技术。

  Moore指出,技术应用的关键之处在于团队中是否存在实用主义者。因为实用主义者需要新技术大规模的应用,这个中间群体希望看到其他务实派在团队做出承诺之前就使用新的技术。这是一个类似于《第二十二条军规》书中所描述的现象,因为务实派们都会相互依赖的存在。出于这样的原因,在先行采纳者排列在技术专家之后和务实派之前,你会经常在市场接受度曲线中看到一种下降的趋势。Moore将这种下降称之为鸿沟倾向,并且这种想法应出于围绕任何新技术的风险讨论的中心。

  Moore解决方法是,把重点放在跨越鸿沟的过程中。通常来说,你很难通过一个巨大的飞跃跨过鸿沟。你需要有一个目标明确的细分市场。Java技术首先通过Applet程序进入网络客户端,之后转向服务端的计算、移动终端、以及其他类似于移动计算以及企业架构的应用,最终为网络带来强大冲击。

  在《超越Java》一书中,我认为存在于程序设计语言之间的鸿沟特别严重。我们大多数人都认识到在Lisp语言上投入精力将大幅提高生产率,但是同时也会导致更难找到合适的程序开发人员、教学资源、类库以及组件等。同时我们还将不得不付出更多的花费来进行一些必要的整合工作。出于这个原因,大众市场只会以大约每十年的时间周期更换主流的编程语言。在服务端编程语言方面,可以清晰看到这种趋势的存在。COBOL和Fortran语言出现于1954年到1961年之间。C语言则诞生在上世纪70年代初期,C++是出现在上世纪80年代中期,Java语言则出现在1996年。我应当把C#语言算做整合高效的Java语言克隆版本,虽然这样的说法可能会引发一些争辩。许多其他的语言在此阶段中诞生,但是上述语言仍旧没有一个能够占据统治地位。伴随的风险是阻碍新编程语言被广泛采用的最重要原因。

  Java的风险概况 


  使用Java语言曾经需要克服很大的风险。当时,大多数服务端的编程都在使用C++语言。C++是一门高效的操作系统语言,非常适用于应用程序开发。C语言家族在这方面的表现相当出色,因为客户机/服务器端编程以及用户界面开发需要程序性能与适应性良好地结合在一起,在当时其他的编程语言都无法符合这样的要求。为了克服伴随采用新编程语言而来的风险,Java需要以下的三个条件均成立:

  C++开发者不得不经历一番辛苦的学习过程。指针的存在(由于缺少编译时的安全性)导致各种各样难以消除的缺陷。内存管理使得内存泄漏成为家常便饭。C++对于大多数程序开发者来说,显得过于复杂。这些问题增加了针对于C++语言的风险评估。

  Java需要解决一些C++语言无法处理的工作。Java语言所具有简洁、灵活的特性以及众多C++所不包括的类库支持。这些要素减少了针对于Java语言的风险评估,并可以保持开发团队小型化最终从根本上提高生产力。

  Java需要一个催化剂。随着网络爆炸,Applet应用普遍被嵌入在NetScape浏览器中,使得C语言开发者不得不转向去开始使用Java语言。C++因为和Java语法的类似,可以简单地进行过渡。Java得以迅速获得数量庞大的用户群,并且在同微软的竞争中逐步提升这样的过渡。

  Java的膨胀要比我们以前所见的任何一次技术浪潮都要迅速,同时也可能比我一生所见的任何技术都要庞大,然而Java的发展蓝图却一直保持清晰。为了建立新的语言,原有的语言已不适应开发者的需求,新的语言必须要克服原有语言的缺陷,并最终以某些催化效应迅速聚集起数量庞大的用户群。

  Java作为Internet应用语言在客户端迅速得到立足。借助于灵巧的Applet应用程序,由于Java提供了对于应用开发者极有帮助的特性,使得Java快速转移到服务器端开发,这些特性包含有:

  内存管理

  干净的继承模型

  更好的面向对象功能

  便携性

  Internet类库

  安全

  ……以及其他许多特性。在我看来,Java一直以来都是最为成功的编程语言。随着Java不断的改进,使用Java语言变得越来越安全,并最终在Internet应用中统领着服务端开发的市场。商业投资,开发者社区,各种教育培训,开放源代码的框架,以及各种各样的信息发布都使得使用Java开发的风险降低。上述几点清晰地解释了Java取得成功的原因。

  一旦新的程序开发语言跨越鸿沟,开发语言相关的风险则会随着市场占有率的提升显著减少。

  Java则拥有一个令人赞叹的成功过程。但是程序设计语言没有仍旧停留在不确定的技术发展水平之上。所有成功语言都会产生技术膨胀,因为它们必须去适应使用者不断变化的需求。成功的编程语言无法像其他的语言一样快速的适应变化,他们必须保持一定程度上的向后兼容,来满足逐步增长的用户基本需求。随着技术滞后与语言膨胀的产生,另一种形式的风险预测逐步形成。为了新的风险预测,由于风险与程序开发者高效完成工作的能力相关,使得风险与市场占有率的降低有必然的联系。

  到目前为止,我已经开始关注于新生技术的市场风险。在Java诞生十周年之际,另一种形式的风险评估成为必须。就像《人月神话》、《死亡之旅》和《人件》等许多有影响力的书籍中鼓吹的那些风险一样: 


  低下的生产力将导致更庞大的团队规模和更长的时间周期

  风险随着项目的规模而增加

  风险随着团队规模的扩张而增加

  质量风险,以Bug的数量来衡量,随着代码行数的增加而增长

  成本的增长导致风险的增加

  综合成本随着复杂性的提高而增加

  随着程序设计语言或者编程范例的使用有了积累,相对于技术发展水平,语言将会与生产力相关联。项目团队需要增加规模,开发者需要编写更多的代码来解决相同的问题。所有这些因素本身就会增加风险。所有的因素将会导致必然的结论。

  由于市场主宰地位的终止,相对于技术发展水平来说,生产力风险与开发语言相关性将会增加。

  在Java语言的范畴中,这些情况是否以及如何发生是一个将会引起激烈争论的话题。当然,Java仍然是解决整个一系列企业问题的最佳语言,比方说非常大型的项目,或是比如双相提交或核心对象关系映射等具备特定需求的问题。针对于Java的商业投资从来没有这么强过,并且Java社区一直是保持持续高涨。但是根基中的缺陷逐渐开始显现出来。

  Java的企业级JavaBean框架,WS-*风格的网络服务,以及JavaEE的复杂性和宽松度已受到越来越多的批评。James Duncan Davidson,servlet的创始人之一,曾表示Java不再像从前那样方便易用。目前很难给一个普通的Java开发者,讲明白如何解决最一般的编程问题:比如有后台数据库支撑的网络应用。出现的相关证据是,已经出现了很多使用其他语言的开发框架,最为出名的就是Ruby on Rails,在处理小规模问题时具备极高的生产力。资深Java开发者James Duncan Davidson,Mike Clark,Justin Gehtland,Stuart Halloway以及其他许多开发者都证明,在关键的小型项目中使用了Rails之后,获得了非常高的生产效率:具备后台数据库支撑的绿色网络应用。当然,我的个人经验也是可以轻松地使用Ruby on Rails构造、部署并维护这样的应用。

  这些报告将会引起广泛的争论,就像是早期关于Java生产力的那些报告一样。还记得,在Java开发广泛普及之前,Java首次出现在各式的小型应用中。开发人员的生产力是驱动Java早先增长期的重要标准。请谨记Moore关于新技术出现的理论。跨越鸿沟最好的方式不是通过一次大的跳跃,而是每次只前进一个小的阶段。

  我坚信复杂性和松散的开发效率是使得Java目前正在经历风险的原因。

  Ruby与生俱来的风险

  比起其他新生的开发语言来,Ruby并没有什么特别之处。缺少商业投资,有限的开发资源,还缺少开发经验,这都为新生的程序设计语言带来了风险。下面是一些我遭遇到的较大的风险。

  人才的缺乏。很难找到熟练的Ruby开发人员。根据Java的发展情况来看,这样的现状将会很快有所改观,但是就目前来说,如果你计划在很短的时间内组织一个人数较多的Ruby开发团队,其困难程度远比组建相同的Java团队要大得多。

  缺少经验。许多LAMP相关的语言已经建立了记录跟踪机制。Google使用Python;许多主流的.COM公司使用Perl或C语言。目前仍没有使用Ruby打造的旗舰级应用,来展示Ruby语言强健的可拓展性,或是复杂的企业级集成。我们只是不知道Ruby是否可以解决某些特定类型的问题。 


  部署和配置策略。Ruby on Rails已经出现将近一年的时间,所以在部署和配置方面的经验还不如竞争语言那样丰富。

  缺少类库支持。Ruby远不如Java语言拥有这么多丰富的类库支持。

  缺少商业投资。你需要花费很大的力气才能找到Ruby的咨询、培训或承包的机会,并且这些大多数还并不存在。

  还有其他许多类似的风险。然而,你可以有效地降低使用Ruby语言的风险,比如采取绩效挂钩的风险预测。虽然开发和部署大型Ruby应用的相关知识积累仍然十分有限,但是你可以在适当的着眼点不断学习新的知识。对于PHP、Perl和Python等LAMP相关语言,业界有着非常丰富的知识积累。在应用部署机制、Web服务器以及非共享可拓展策略等方面都是一致的。

  在考虑参与开发的人手时,不要低估你通过对员工进行内部培训来建立高效团队的能力。对于使用Spring、Eclipse、Hibernate和WebWork进行Java开发的新手,我的训练计划常常是为Ruby on Rails开发者指定培训计划的五倍。如果你开始使用具有类似于Ruby特性的开发语言,比方说Perl,Python或Smalltalk,它们可以帮助你很好地起步。如果你打算从零开始培养一个程序员的话,培养一个使用Ruby的开发者,远比培训Java开发者使用最新的一大堆各种框架要合算的多。

  想一想那些众多的函数类库,有多少是你真正需要的?如果你需要分布式处理,双相提交,那么就使用Java编程。如果您需要与Microsoft Office的宏完美地整合,那么就使用.NET。但如果你想编写操作系统整合脚本,或编写基于数据库的绿色Web应用,那么Ruby则正是你所需要的。并且你可以经常编写要用到但手边没有的任何程序。我曾协助一家公司工作,他们在两个星期内编写了自己的数据库驱动程序,但仍然比完成项目其他工作所用的时间要多。我还认识一个使用Ruby在四小时内修补现有代码,为程序拓展Oracle支持的开发者。Thoughtworks在很短的开发周期内就发布了RBatis,即Ruby版本的实体关系映射工具iBATIS。

  所以当你站在全局考虑时,会感觉到使用Ruby的风险往往被夸大了,尤其是在Java并没有带给你一切所需资源的时候。自己真正去尝试使用Ruby语言,是把这些风险纳入控制范围之内的最好方法。使用Rails开发一些实际的应用,并站在实践的角度上发言。而不要盲目迷信别人的说法。

  神话 vs 事实

  Rails是银弹。

  人们曾经在Rails项目上失败过,并且还将会有更多失败的教训。如果你在没有具备必须技能的情况下使用它,你也将可能面临失败的命运。

  与之类似的说明是,如果Java语言不是导致失败的问题根源,那么Ruby将同样不会是你的答案。大多数软件开发问题的出现是与特定技术无关的。如果你正在遭受打击,Ruby on Rails的采用只能加快你遭受打击的速度。

  选择Ruby颇具风险,因为你无法预测到错误。 


  采用任何新的语言,最主要的风险是你将预测到错误,并且错误停滞在使用的类库之中。这的确是一项相当重大的风险,但是这个问题决不仅局限于Ruby语言之中。在Java语言里,你需要就主要类库的使用做出决定,其中任何一个都可能带给你复杂臃肿的代码。你是否会为声明事物选择Spring或EJB 3等技术?Java的持久层架构是不是一个正确的选择,或者Hibernate就是最终的解决方案?关于Web MVC分层的正确选择是什么,是逐步衰落的Struts框架,还是其他更易用的框架?

  在Ruby语言之中,选择Web开发框架则相对简单许多。你将很可能与Rails一起工作。语言动态的特性同样各层之间的结构更为简化,通过特定的约定来使得开发配置比Java实现更为明晰。

  为Java项目招募人手总是更为容易。

  Java拥有数量庞大的开发者群体,但是开发社区之间有着巨大的分歧。如果你想使用一个综合的Java工具集,你的选择是十分有限的。即使你选择了像Spring这样的流行框架,你的团队必须还要学会使用针对给定项目所需的各种类库。在这种情况下,Java的核心力量,过多的函数类库,将会给项目带来副作用。相反,大部分的Ruby开发者都知道Rails框架。此外,你通常需要更多的Java开发者去处理类似的任务。有时,招募Java的开发人员要容易得多。但有时,情况也并不是这样。

  Rails无法拓展。

  Ruby on Rails其实有很好的延展性。它的缓存模型非常强大,并且非共享的架构在LAMP社区中多次被证明是非常有效的。实际上,我们知道Ruby on Rails完全可以适应较大型应用的要求。我们不知道Ruby on Rails是否可以承受大规模的应用部署。没有固有的架构使我相信这是一条死胡同。对于典型的应用,总之错误的潜伏期是存在于数据库端。

  Rails的整合选项十分有限。

  Rails对于基于ReST的Web服务有着良好的支持。Ruby同样通过JRuby项目提供对于JVM的支持,以及提供对于微软的CLR运行时的支持。同时Ruby也提供了良好的消息传输支持。最后,为项目选择最好的工具将会帮助你始终处于良好的状态。优秀的开发团队可以在Java和Ruby项目上同时获得成功。

  总结:你可以承担什么样的角色?

  如果你正在考虑使用Ruby,那么在你身边将会有很多有用的信息。与其他同时在有效使用Java和Ruby的开发者交流。阅读关于开发框架的资料。查找从Java到Ruby的迁移资料。如果你并不想放弃Java,只是想寻找轻量级的开发体验,那么去了解一下那些可以为你带来更多相关体验的项目,比如说RIFE、JMatter或Wicket项目。如果你认为Ruby可能是一个好的选择,那么要留心以下的建议:

  为项目选择合适的工具。Ruby on Rails并不是银弹,ROR是一个针对以数据库为后台的高度精简的Web应用开发环境。与新的数据库模式配合较好,或者你可以通过变更来适应Rails的各种固有优点。

  细心计划开发团队的热身阶段。你不需要在Monster.com站点投放广告并在三日之内为项目招募齐全开发人员。但你可能需要考虑培训你部分或全部的开发者,并且招募几个顶尖的Rails开发者,或是请求某些项目咨询来帮助你把项目启动。

  了解你使用传统方式的结合点。通常,项目中最头疼的部分是定义与外部系统的交互。你最初证明概念的工作需要与某些接触点交互,至少是要明确你在何处对项目感觉到满意。

  如果你还是不确定,那么做一个先行者,或是遵从保守派的观点。缓解风险最佳的方法总是优秀的判断能力。

  关于作者

  Bruce Tate居住在德克萨斯州的奥斯丁,是一位山地自行车和橡皮艇爱好者,同时也是两个孩子的父亲。Bruce已经撰写了9本编程方面的书籍,其中包含两本Ruby的书籍以及五本Java相关的书籍。Bruce还是RapidRed公司的创始人,公司专注于包含Ruby和Rails在内的轻量级开发技术,并提供开发、资讯和培训等业务。Bruce是一位世界范围内广受称赞的优秀演说家、程序员、培训师以及技术顾问。

 
来源:赛迪网技术社区    作者:佚名