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

 


     这不是一个全新的话题,“不要重复发明轮子”已经成为了软件开发领域里的一个金科玉律了,但是,我在这里提出我的问题:“当别人发明的轮子不适合你的时候怎么办?”,是削足适履,还是换别的轮子?,希望和大家共同探讨。
 
     我算是比较早研究开源组件的,早在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)尽量使用简单而小型的组件,不要使用大而全的组件。尽量不要使用 依赖关系非常复杂的组件
 
 
 
 
 
 

 
 
 
 
 
 
 
 
 
 
     
 
 
 
 
 
 
 
 
 
 
 
 
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值