Post

开源项目,其实你有多种参与方式 Draft Version 1.1

介绍了自己开发 CnBeautifierWizard 开源项目前后的故事。

开源项目,其实你有多种参与方式 Draft Version 1.1

(Originally posted to CSDN on Dec 22, 2005)

――CnBeautifierWizard的前世今生

众多的开源项目在最近的这几年明显的改变了我们使用电脑的习惯。像Linux操作系统,或者Firefox浏览器之类的实用程序,普通用户也可以在日常使用。当然,还有像ANT,Bugzilla等等专门为程序员设计的贴心帮手。对于普通用户来说,使用这样的开源项目仅仅局限于运行程序。但是对于程序员来说,除去使用产品,其实还是有多种机会参与到开源项目。这其实是提高自己难得的机会,不过,这种提高不仅仅限于编程技术一项。

第一层次――基本用户。这也就是最简单的参与方式,提提建议。其实对于为数不少开源项目来说,真正缺少的不是真正编程人员的参与,而是用户的反馈和配合。最初认识一些开源项目的时候,我就常常采用的这种方式,积极发表自己的看法――感觉对于培养自己对于新事物的敏感度很有帮助。

第二层次――贡献者。你可以参与项目的推广(用户服务,论坛讨论,使用答疑等等)――这会让你有机会了解更多人的想法,换一个角度来看待这个项目的意义和尚存的问题。对于文笔还不错的同志们来说,参与对于项目现有文档的修改,特别是用户使用手册的编写,都是对这个项目莫大的帮助――毕竟很多项目的主要人员精力放到了设计和编码上面,实在没有时间做这个。而实际上作为整个项目中与最终用户最贴近的一环,这些零碎的东西会使参与者今后编程时眼光里带有一点不一样的东东――越是了解用户的感受,越会促使你写出人性化的软件。

第三层次――高级贡献者,你可以尝试去理解代码,写写补丁之类的,或者DIY出来一个给自己的特别版本。那可就是一桩乐事了。常见的是不少热心人一见到某个好的国外开源项目,就会把它汉化出来。

最高层次嘛,当然是参与到项目的内部测试和编码,成为开发人员或是测试人员了。

关注开源项目才几个月,感觉自己已经得到了不少锻炼,走过了几个层次了。这里就把这段经历作为一个例子来介绍一下。

与SBT以及AStyle的相识――第一层次的尝试

去年用Delphi 8的同时,自己很用心的学习了一点C#(毕竟它是一门很不错的语言)――自然也是在Borland的产品C#Builder帮助下。在Delphi下面有一个叫做GExperts的开源项目,是一个很有名的IDE专家组插件。那时关于C#Builder也已经有一个类似的一个项目,叫做SharpBuilderTools,我是从Borland Developer Network上面的Code Central下载的,包含全部C#源代码(后来知道它其实也是SourceForge上面的一个项目)。

相比起GExperts,SBT功能似乎还要强大一些,大大方便了我的C#学习。最常用的还是它带的一个Code Beautifier(代码美化专家),可以美化C#代码。大概也是由于发现了SBT,那段时间C#的学习看起来比Delphi .NET的学习有趣得多(因为那时Delphi 8除了GExperts,几乎没有别的插件)。后来分析SBT代码的时候才发现它实际上巧妙地新建了进程,以命令行来调用外部的程序。比如代码美化的工作,其实是由AStyle.exe完成的(AStyle还可以美化C/C++/Java的代码)。这种机制虽然技术上不甚高深,却是非常之实用――SBT的作者David,无需自己动手来从头写什么美化代码之类的功能,而是将更多的时间花在对SBT架构的改进工作上面,从最近的一两个版本可以看出。

在SBT短短的发展史中,一些成功的开源项目或免费软件,像NANT/ANT,AStyle,NUnit,Microsoft FxCop,NDoc,Ultrapico Expresso,WinMerge,在不同的版本时先后投入了SBT的怀抱(不知道下一个会是什么,期待ing)。这种方式颇有些像鲁迅先生所言的”拿来主义”,不是吗?SBT越来越像是一个平台了,一个将众多好东西集成到Borland Developers Studio(Delphi 8/2005,C#Builder)的插件平台。不过这样的开发,还是有一个很小的副作用,就是用户在使用SBT部分功能的时候如果发现bugs,却是其他项目的bugs,并非SBT的问题――我就在使用中发现了AStyle美化C#代码时的一个小问题,并且给那个项目写了一份详细的bug report。虽然这一步很小,这也算是我参与开源项目所跨出的第一步了。

感谢SBT的作者David,他把拿来主义使用得恰到好处。

与JCF的缘分――跳级的愉悦

先花些篇幅谈一下代码美化。估计对于程序员来说,除了手动美化比较麻烦,寻找可以自动美化代码这类好东东比较费时间之外,确实只有不少优点:

一,在美化代码的时候会很清楚地展现出代码结构(一般看缩进就可以看出哪里少写了什么的样子),甚至有时会暴露代码中的潜在问题(有的美化工具还会认真分析代码)。

二,有利于学习、交流。假如大家的代码乃是同一样式,那么看别人的代码就会方便多了。

三,”人靠衣装,码靠美化”,感觉美化之后的代码才是真真正正的好作品,而没有美化的则是不堪入目――记得那些劣质书籍的范例吗?

四,为了方便大家之间的交流,对于各种语言都有不错的标准可以参考,也有不少美化工具。VC自带的那个美化功能,相信不少C++程序员都经常使用。而C++BuilderX,Eclipse,Visual SlickEdit,CodeWright等等都自带有这样的功能。第三方的代码美化工具更是数不胜数。

代码样式问题也是越来越受到人们重视的。很明显的例子是SUN公司在Java诞生之初就给出了一个很好的样式要求(见相关文档)。而Microsoft也是如法炮制的给C#定了一个规范。虽然这些不属于语言的标准范畴。但是由于比较正规的企业一般会以很成熟的代码样式要求其员工,所以实际上形成了行业、企业的事实标准。因此我们应该从初学时就遵守一定的代码规范。各式各样的自动化美化工具,只是一种很好的辅助。

这里不妨说说自己使用Code Beautifier的历史。还在用Delphi 7的时候有一日在学校附近的书店里面看一本学习Delphi的书(该书很厚,当时按照网友的推荐目录来看,却不是什么好书)。它的附录里面提到了一个叫做Delphi Formatter Expert的代码美化工具,看起来这个工具好像确实很有用的样子,所以返回寝室里就立即下载了一个用起来。可是后来改用Delphi 8学习.NET开发了,而DelForExp那个官方站点N久没有新版本的消息,所以不得不回到手工调整的时代(用惯了自动的,再搞手动就苦不堪言)。

所以有一天,懒懒的自己突然来了灵感――为什么不利用SBT的平台,自己动手集成一个Delphi代码的美化专家到Delphi 8里面呢?在SBT的基础上开发,难度显然小了许多――是有点跳级了,直接跳到了第三层次,嘿嘿。

顺便提一下。自从原本代号Galileo的Borland Developer Studio在C#Builder中第一次现身,它就比起上一代Delphi 7的IDE多出了一套支持.NET语言的OTA接口。也就是说,BDS的用户可以开始使用任意的.NET语言(C#,VB.NET和Delphi.NET等等)来给BDS写插件了――Delphi 8基于BDS 2.0。相比起Delphi 7/C++Builder 6那个时代只能用Delphi给C++Builder写插件来说,这毕竟是一个很大的进步。如果你愿意尝试,好像还可以在VS.NET里面给BDS写插件和调试(先搞到和BDS目标版本一致的Borland.Studio.ToolsAPI.dll文件,然后加入到项目的引用就好了)――在技术上面没有什么特别的障碍。这使得SBT可以装到Delphi 8上面,但是仅仅凭借AStyle并不能美化Delphi代码。

DelForExp是第一个被否定的选择――试了一下,也查看了它的帮助文件,确定它不像AStyle那样支持命令行调用。然后自己在SF.net浩如烟海的项目里面很幸运的遇见了JEDI Code Format,来自南非的Anthony的一个Delphi Code Beautifier开源项目。

有了SBT的示范,不久我便很成功地把JCF像AStyle一样集成到了SBT里面。不过第一个版本的时候写的还是C#代码。这样一来我机器上的SBT”特别版”就可以美化两种语言了,也很适合后来发布的Delphi 2005。于是把我写的东西发给了SBT的作者David,希望可以集成到SBT下一个版本里面。

为了证明用Delphi做.NET同样优秀,后来我还用Delphi .NET重写了一个独立的插件程序,名唤JCFExpert for Delphi 8/2005,放到了2ccc.com。不过,大概是国内Delphi 8/2005的用户很少吧,一直没有看到什么用户回应。在广大Delphi 2005用户的要求下,JCF官方很快也出了针对Delphi 2005的新版本。我给它加入了一个自动重载文件到IDE的改进,算是在第三层次又干了一点活。

针对JCF for Delphi 2005的问题,我今年曾经前后与Anthony联系了三四次。在最近的两个月里,JCF的版本号从2.08飞速跳到2.10,基本完成了对于Delphi 8/2005引入的新语法特性的支持。如此迅速的转变,可以看成是JCF迎接Delphi .NET时代的大动作吧。(本文完成许久之后的今天,版本号已经是2.13了。而AStyle也到了1.44 Beta。)

相信JCF的使用人数在不久的未来会超过DelForExp,成为Delphi程序员的宠儿。

与CnPack的相识和CnBeautifierWizard的诞生

本人于2003年注册了DelphiBBS(大富翁论坛)的帐号,但是至今还几乎没有去过太多次,反而总是用这个直通车帐号上2ccc.com了。所以,对于起源于DelphiBBS社区、现在发展得如火如荼的CnPack,我一直是不知道的。反而是由于比较喜欢上CSDN,在C++/C#/.NET/Delphi等等好多自己喜欢的版面上转转的同时,在看别人的回帖的时候偶然看到了关于CnPack的东西介绍――大概是哪位热心的用户在做推广吧。现在用了CnPack也有不少日子,感觉CnWizards确实有些功能是非常实用和贴心的,蛮喜欢的。也像学习SBT一样学习里面的代码。特别是有中文文档可看,确实是难得的亲切。

像对待SBT一样开始想着把Code Beautifier加到CnWizards里面,有以下两方面的原因:

其一当然CnPack给我留下了这样暂时填补空白的机会。仔细察看了CnPack的文档。看得出最初几位令人崇拜的头头们是认真考虑过添加这个功能的,而且搞不好会是CnPack的一个亮点。但是Wizard文件夹下面到现在还是只有一个未完成的Code Formater子项目。这样搞得不少CnPack的用户在其官方的BBS上面不停的要求。看得出需求是很旺盛的。

另一方面的原因,则是因为今年自己到了做毕业设计的时候。由于用的是C++Builder 6(这东西很好用,像极了Delphi),而它又不像C++BuilderX/VC那样自带一个好用的Code Beautifier――C++BuilderX这个功能很是贴心的。所以,才动了把AStyle的功能利用起来的念头。转念一想,何不把JCF也一道加上呢(毕竟Delphi插件可以安到C++Builder上面)?――这就是做CnBeautifierWizard的最初念头。

由于CnWizards已经有了良好的架构,我这一部分的代码基本上只要照着原有的MSDN专家的框架来移植自己最初的JCFExpert代码就好了――像注册IDE菜单之类的工作都由继承体系中的基类在底层完成了,真是”好的架构决定项目成败”。虽然自己原来的代码是基于.NET Framework写的,但由于功能简单,移植没有很大的障碍,很快就有了一个雏形可以自己先享用――Delphi语言的Win32和.NET开发其实差异是最小的,不像C++或VB。唯一花了心思的地方是创建进程调用JCF和AStyle的部分。在之前的Delphi学习中,自己还没有机会做进程控制,因此一开始遇上问题,比如不知道自己调用的Jcf.exe进程何时退出当然。回头分析,这个问题源于自己习惯了使用ShellExecute和WinExec,却从来没有用过CreateProcess――很低级的问题。在SBT中,这种调用进程的函数是放到叫做RunProcess的公用单元里面的,而且进行了一定的封装,使得使用起来很方便,而在CnPack里面,我发现必须自己动手――可见CnPack的公用单元(Code Library)还是很扩展空间的。也多亏自己还曾经买过一些书,很快从中找到了范例,写出了CnBeautifierWizard的第一个版本。

不过现阶段这个专家还有很多问题存在的,比如没有在注册合适的快捷键,没有加入菜单图标(因为CnPack里面如何做到这个的我暂时还没有学会),功能也不是很强大(只能格式化当前文件)。面临着本科的毕业设计答辩,这件东西的进一步改进,是暂时要放一下了。所以匆匆在CnPack的BBS上面发表了这个很初级的东西。

新时期的问题

写上面这几部分的时候自己正在等待CnPack开发组的回音,希望自己与CnPack的缘分在将来会引发新的故事。到5.30打开邮箱的时候,就发现了Passion大人热情的回复。除了正常的说明函,他还额外针对CnBeautifierWizard另外回复了一封信说明了CnPack的”项目管理委员会(PMC,Project Manager Committee)”讨论之后的结论――考虑到已经有JCF,DelForExp提供了很好的IDE插件,CnWizards再增加这个东西有点画蛇添足。

其实写回复的时候,自己没有什么不快,因为这个问题我也认真考虑过。正如前面所说,不论是自己改写SBT,重写JCFExpert,还是在BBS上面发表CnBeautifierWizard代码,很大程度上是在享受Open Source带给人的种种乐趣――学习原本不会涉足的知识,体会霎那灵感的妙处。那些代码原本只是自己机器上的玩具,禁不住别人在帖子里面反复哀求似的提出需求,所以才发布出来。现在做到别人满意,自己还有什么奢求呢?而且对于为数不少的用户,特别是Delphi初学者来说,在没有特别指导的情况下很难凭空了解代码美化的重要性,更谈不上了解认识相关的美化工具了――我们多数人都是后知后觉。所以,多给他一个认识代码美化效果的机会,乃是为了帮助他更好的学习和使用Delphi/C++Builder(正是基于这样的考虑,才在这篇文章里面罗嗦了几次)。因此,今后有空还是会改进CnBeautifierWizard的代码,毕竟,发出去了不维护,和DelForExp的作风就一样了,不是吗?需要这个东西的同志们应该还是可以在bbs.cnpack.org上面找到。

由于在Delphi上面还有很多东西要学,所以这次申请的乃是CnPack辅助开发组的工作――自己还不愿不小心献丑。也许没有了许多人羡慕不已的check-in代码的权利,但是,作为我这样一个才开始开源之旅的人,做个老实的贡献者并没有什么不好的。继续贡献吧。

今天你贡献了没有?每个人都会有机会。

2005–5–30

附一:2005–10–16

在结束了这篇文字之后,自己确实就开始忙本科毕业设计的论文写作和答辩了。没有想到是这样的麻烦。折腾完了之后人也瘦了很多。这样漫长的两个月,自己给自己放了暑假。七月里我病得连电脑也上不了了,惨兮兮的。八月才恢复了一点元气,开始继续编程之旅。那时开始就在打算JCFExpert的未来。毕竟是自己花了精力的东西,像宠物一样的舍不得。于是断断续续的开始了下一个版本的设计。由于《程序员》杂志上一些文章的鼓舞,我也开始利用假期的空闲,体会一些软件工程的东西。所以,在准备JCFExpert下面一个版本的时候我决定采用一些合适的方法论来指导。我自然不会什么CMM呀,RUP的,只不过听同学介绍过XP,所以裁减着XP来设计自己的方法论(后来才知道这就是时髦的Agile――敏捷编程的核心呢!嘿嘿)。

简单的需求分析是自言自语的结果。我终于让自己对于这个小东西的未来有了一个初步的设计:我本人依然不会努力的学习Parsing文件的技术,那个太专业了。所以,要继续使用”拿来主义”。同时,JCFExpert的使命应该是伴随着Delphi IDE的发展而发展。那么,DeXter时期的JCFExpert也应该支持多种语言(Delphi/C#/C++)。这样的话,AStyle的支持肯定要加入。然后,就需要一个更合适的名字来代表这个东西。CBC就是我最后选择的名字――Code Beautifier Collection。

其他一些重要需求都列在了下面:将插件架构升级到David的SBT v3.1.0.0;加入更多的选项和特性。在九月发布的CBC 2.0中,已经在第一点和第三点上有了很大的进步。但是升级架构的工作是在十一期间才最后完成的。升级架构确实是比较麻烦。不过David的代码写得很漂亮,所以让我从一开始就对自己充满了信心,从来没有太消极。这一段修改过程还让我学会了使用.NET的TRACE和ASSERT,在CBC现阶段的代码里面你可以清楚地看到(感谢《Writing Solid Code》一书的指导,我对于Solid一词有了更深的了解,书中的一些观点真是超越了程序语言藩篱的真知灼见,让我受益匪浅)。同时,我发现自己居然突然间可以看懂Design Patterns那本书了。真是找到了捷径呀(不过我还参看了BDN上面最近的一篇文章――Managing Change through OOAD by Ken Sipe,希望有兴趣的人士参考)!

CBC 2.1确实是一个重要的Milestone,这主要是体现在架构上面(也是我架构思想成熟的标志吧!)我以为将来在要扩展CBC会比半年前简单方便的多了。这个版本其他的改进,则是体现在文档上面。我决定加强文档的工作是因为我最近在指导两个特别的学生。一个是我的表弟张珂,正在念初一,我给他做家教。另一个是陈正熙,与我同在华工读研,由同一个导师指导。由于项目的关系,他需要学习VC开发。我虽然不了解VC的MFC框架,却可以在架构层次和Windows平台开发两个方面给他答疑解惑,同时教授一些软件工程和编程习惯给他。给他们讲解的虽然是完全不同的领域,然而理智告诉我其实核心都是一样――不就是介绍方法论吗?感觉为了教好这两个学生,我整个人的思维都得到了有生以来第一次很彻底的梳理,知识也变得有条理多了了(要是早有这种机会,说不定现在我就不在华工了――玩笑)。这也让我有了许多可以转化成文字的想法,在Docs文件夹下面,几天时间就积累了不少文字。这种感觉确实是很舒服的。要倾吐,才可以让自己更健康的。

这样的快乐心情,使我开始准备过一个格外不同的生日了。CBC 2.1的发布,肯定是一份完美的礼物了。Happy Programming!

附二:2005–10–16

只是CnPack方面的一些东西让我觉得很难处理。

八月末发布的那个新版本我一直在用,很不错的,界面和功能都得到了加强。这让我对于自己无法发挥作用有了一些遗憾。但是,依然没有见到Code Formatter的影子。所以,我只好在其BBS上面独立发布我自成一体的插件CBC了。虽然显得好像做广告,但是看得出来其实很多人还是有需求的。CnPack显然是面对着用户们太多的需求而开始迷失了。CBC却是船小好掉头。

我依然坚持自己的观点,独立的搞出一个Formatter是可以的,但是,CnPack应该在自己独立解决Parsing以及美化的问题之前,提供一个合适的替代方案。可以想象,一些用户对于美化工具有着急切的需求。我也给出了我可以提供的两种解决方案――CnBeautifierWizard和CBC。

另一个是CnPack的架构问题。确实GExperts是一个很好的参考范例,但是我觉得GExperts还是有它的局限性的。首先,GExperts诞生得太早,所以带有太多古老的Delphi弱点。比较显著的,一是一个Unit里面N多的类型。二是没有采用包结构来实现类似CodeRush的二次开发平台。不幸的是,这两点都被CnPack继承了。而我作为参考的SBT架构虽然在一些方面也不是太成熟,却至少克服了第一个弱点(仅仅是个人观点)。当CnPack达到了下一个里程碑时,我真的希望项目组可以尽快地开始架构的进化(我想这个过程说不定已经开始了,因为我很早写的那个CnBeautifierWizard已经和新版本CnPack的架构不兼容了)。

还是希望自己可以多一些OSS方面的经验。所以,期待着CnPack给出合适我的工作呢。等待中。

附三:

实在是因为学了一些BDS OTA(C#做OTA,很顺手)之后不想再学Win32 OTA,加上CnPack没有打算接受CnBeautifierWizard,所以,CnBeautifierWizard也被我搁置了。我现在把全部的功能都移植到了Code Beautifier Collection里面了。如果你希望CnBeautifierWizard重回CnPack,那么请与我联系,让我知道究竟这个东西有多大的使用面。我会考虑在某个将来的空闲里面重做CnBeautifierWizard。

© Lex Li. All rights reserved. The code included is licensed under CC BY 4.0 unless otherwise noted.
Advertisement