`

是否需要重复发明轮子--说说开源组件的使用

阅读更多

 


     这不是一个全新的话题,“不要重复发明轮子”已经成为了软件开发领域里的一个金科玉律了,但是,我在这里提出我的问题:“当别人发明的轮子不适合你的时候怎么办?”,是削足适履,还是换别的轮子?,希望和大家共同探讨。
 
     我算是比较早研究开源组件的,早在10年前,我就有有闲了就去sf.net去逛逛,看看有哪些东西我可以借鉴,我可以使用,来减少自己产品开发和项目开发的工作量。但是又经过了十年,这十年里使用过很多技术和组件,现在回头看看,的确又是一番感受。
 
     和大家有所不同的是,我这些年里,不是从事B/S开发的,基本上从事的是C/S模式的服务器和客户端开发,而且,所面向的客户也不一样,都是在金融、信息安全领域,运行在关键业务中,和开发网站、论坛、信息管理系统还是有很多不同的需求场景和技术要求。所以,有很多东西和别人的理解不一样。
 
     我觉得说实话,就我用过的开源组件来看,没有几个很好用的。话是狂妄了一点,但是都是真实的教训得来的,当然,也希望朋友们有以教我。我认为,开源组件因为其特点(社区维护,非商业)这一特点,也带来和很多问题。
1、文档比较少。经常看到要使用别人的一个包,结果一直调试不通。Java的开源组件,看到最多的项目中只有JavaDoc文档,里边的内容,要多简单有多简单。
 
     我看过的开源项目,jetty文档算是非常好的了,但是也是web服务的部署文档多一些,当作API可就远远不够了。前一阵子对JNA发生了兴趣,当时想用JNA在windows上弹出一个MessageBox(调用windows库中的MessageBox函数),结果怎么也出不来,导出找文档无路。
 
     OpenSSL的文档更别提了,因为用的人还算比较多,原始资料里没有的东西,在网上有人遇到过写出来了,还能参考一下。
 
2、版本不兼容
 
       JQuery算是比较成熟的框架了,通用性也算是非常不错了,但是还是有人为它的兼容性感到非常痛苦,包括我在网上看到的有人写道:
 

◆JQuery的不能向后兼容。每一个新版本不能兼容早期的版本。举例来说,有些新版本不再支持某些selector,新版jQuery却没有保留对它们的支持,而只是简单的将其移除。这可能会影响到开发者已经编写好的代码或插件。

◆JQuery的插件兼容性。与上一点类似,当新版jQuery推出后,如果开发者想升级的话,要看插件作者是否支持。通常情况下,在最新版jQuery版本下, 现有插件可能无法正常使用。开发者使用的插件越多,这种情况发生的几率也越高。
 
       我自己之前使用过一个PKI行业的开源组件BouncyCastle,算是这个行业里最最知名的开源包了,但是也因为这个包痛苦过很多次。
 
      有一次,新的版本的包修改了一个数据包的解析类,接口没有变,输出内容(输出内容是一个数组)也基本没有变,只是数组元素做个一个排序(天知道是按照什么规则排的序),而我之前的很多基于BouncyCastle的代码都是处理这个数组的第一个元素[0]的,因为我数据打包时,是将自己的数据放在[0]位置上的,之前的BouncyCastle也都是和打包时顺序一致的方法返回,谁料想到了这个版本变了,结果我的程序在处理上就都错了。。。。
      最可恨的是,关于这个改变,没有任何地方提及。知道测试时发现了错误才知道。为了这个问题,我特意到邮件组中(我一开始就加入了BouncyCastle开发者邮件组)去问为什么要加排序,是考虑到什么场景,排序的规则是什么,结果没有一个人回答我。。。。
 
 
       使用开源组件的人,可能很多都遇到过这样的问题,组件出了新的版本,新的版本比旧的好,因为有新的功能特性,效率好一些,且改了旧版本的一些bug,但是除了这些,新的版本还改了很多东西却没有在文档中提及,换上去,发现代码编不过去(这还算好的呢),编过去也是很多地方都运行不过去了(因为即便接口没有变,但是接口运行的上下文、处理方式和返回值可能都变了),于是,开发者或者选择一个接口一个接口的测试,或者修改自己的代码适应开源组件的新版本(要是都是自己的代码还好,关键有些代码是项目或产品的遗留代码,或者新版本使产品或项目的另一个开源组件不能正常工作),或者继续使用旧版本。

3、有bug自己改不了,社区也不理
 
     程序总会有各种各样的问题的,有bug没有关系,最要紧的是影响面尽可能小。不要造成用户正式环境的事故。再有就是有bug的话,社区能不能修改?不能修改的话自己能否修改?如果社区不给修改,自己又不能修改?那么怎么办?
 
例如,sun Java的一个bug,在我的之前文章中提到的,从1.4到1.6,还是没有修改,自己也改不了,怎么办?处处绕着走。
 
例如,前几年做得一个产品,使用了数据库连接池,一直都很正常。结果某一天发现,Oracle连接存储的光纤坏了,发个一个查询的SQL,就一直等待,没有反应(也不出错)。其它连接请求就分光了池化的连接,直到到达最大连接数,然后新的连接请求就等待释放,可是Oracle只是等待而不释放,直到程序耗死。
 
当时我看了几款网上开源的数据库连接池组件,基本都没有对已分配出去连接的时间控制问题,而且当时看的连接池的源码,好多好多,没有设计文档,估计改的时候也会非常艰难;所幸产品里用的是我自己写的连接池,所以我们花两天时间改了一版。
 
基于以上的这些问题,我之后使用开源组件谨慎了很多。
 
4、客户原因
 
     我曾经遇到过一些客户,我提供给他们的产品,要求把一个API(一些jar包组成)给他们,在他们系统中调用,这个时候,客户提出,所有的包,都要是我们公司颠倒的域名,原则上不允许出现其他包和类(人家考虑不要污染他的应用环境的类路径),我们当时的API引用了一些开源产品,结果我好费了一通口舌才让人勉强同意。
     
         所以,我主张,在产品(项目的话还好一些)中使用开源组件,应该本着一些原则:
 (我并不排斥使用开源组件,毕竟好的开源组件能大幅度降低开发工作量)
 
1)尽量不要重复发明轮子,但是别人造的轮子不合适也不要惧怕发明轮子这种工作;自己做,其实也不是困难到哪里去。因为你自己做,不需要考虑开源组件那么多,仅适合你自己或团队的使用就行,需求比较简单。
 
2)不要有取巧心理。世上没有免费的午餐,现在用了别人的开源库,看上去没有任何代价,实际上代价会像挤牙膏一样一点一点付的(对有责任心的产品架构师和开发者务必注意)
 
 
3)尽量挑选文档齐全的开源项目,挑经历过时间考验的项目,挑活跃度比较高(是为了有bug改的快一些)的
 
4)在使用开源库之前,至少团队内部要评审,征得大家一致同意
 
5)要进行全方位的测试,功能、边界、效率、资源占用等等方面
 
6)考察组件的内部特性(可读性、可理解性、可持续性),尽量采用代码可读性和可理解性好的组件,以便有问题自己能够查找和修正;
 
7)稳定的使用组件,不要频繁更新版本,以防版本更新带来兼容性问题。
 
8)尽量使用简单而小型的组件,不要使用大而全的组件。尽量不要使用依赖关系非常复杂的组件
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
     
 
 
 
 
 
 
 
 
 
 
 
 
 

 

3
2
分享到:
评论
2 楼 windshome 2013-07-21  
如果我没有那么大养家糊口的压力,也许真的会投身到某个看好的开源项目里,帮着提高质量,改善文档不足,兼容性不好的现象,让开源产品、开源组件有接近商业产品的品质,赢得好的口碑。可惜,生活压力太大了------无奈.....
1 楼 leecong1p 2013-07-21  
确实,主要问题就是开源组件的支持能力普遍不如商业化的产品,我们尽量去选择成熟、活跃度高的框架。当然,开源本身的性质就决定了它们可能无法具备足够的资金扶持与专门的团队维护,所以开源精神鼓励尽量多的参与者奉献自己的力量。
你最后的几点建议非常受用,再次感谢。

相关推荐

    一个开源通用的应用程序框架2版 (待参与)

    我们是不是一直在做重复发明轮子的蠢事?Delphi让我们搭建一个程序变得容易,我希望通过我们的努力,让我们搭建一个项目更容易,利用我们可以想到的任何办法,不管是框架源代码、模版文档、代码生成工具甚至是我们...

    Console Component:创建可测试的命令行界面-开源

    控制台组件简化了美观且可测试的命令行界面的创建。 控制台组件允许您创建命令行命令。 您的控制台命令可用于任何重复性任务,例如 cronjobs... 它没有重新发明轮子,而是使用 Symfony EventDispatcher 组件来完成工作

    ptyhon django入门.rar

    由于Web开发需要一组类似的组件,因此您可以使用框架。这样,您就不必重新发明轮子。这些任务包括身份验证,表单,上载文件,管理面板等。 安装Django 要在系统上使用Django,请使用以下命令: C:\Users\lifei>...

    webos框架介绍

    Webos完全基于开源的轻量级容器Spring为基础,遵循spring的哲学: 1. 简约。...2. 不重新发明轮子。 将开源世界的组件进行有机整合,使之形成一个既遵循SOA设计理念,又方便应用程序人员开发的框架。

    code-relay:代码中继网站的来源。 代码中继最快,最简单的方式为开源做出贡献!

    本着Web开发的精神,我们重新发明了轮子,并使用React / React-dom服务器创建了一个自定义构建系统。 也就是说,我们使用React组件编写了整个站点,这些组件我们会提前生成并用作纯HTML。 在./scripts/

    python项目地址.txt

    Django是一个高级Python框架。它是一个免费的开源框架,用Python编写,遵循...由于Web开发需要一组类似的组件,因此您可以使用框架。这样,您就不必重新发明轮子。这些任务包括身份验证,表单,上载文件,管理面板等。

    TemplateApp:具有完整本地化功能的Lazarus模板应用程序项目-开源

    它节省了时间,因为您不必重新发明轮子,并且可以防止错误,因为您已经拥有的东西可能已经过测试。 有关更多信息,请参见/help/index.html或Wiki页面。 TFK如果您喜欢我的工作,请给我买啤酒(或碳酸饮料):...

    java版商城源码下载-dawdler-series:dawdler-series是超高性能:rocket:rpc的一个解决方案,其特点简单、高效(运行,启

    为什么要重复的发明轮子?请看下面的dawdler之美,dawdler早期应用在linuxsir开源社区上(如今的www.linuxsir.org 由于公司原因已不再是java语言开发的了),2008年之前采用ejb3.0通过jboss4.x版本进行,2010年采用...

    java8集合源码-uedi:Java应用程序的令人不安的简单依赖注入

    如果你碰巧浪费时间重新发明轮子,至少让它变得方正。 由于您可能已经注意到哪种语言在此存储库中占主导地位(提示:Java )并阅读了“依赖注入”,因此您可能会问自己“为什么”。 这是一个非常好的问题,这是一个...

Global site tag (gtag.js) - Google Analytics