最近一直在忙着帮堂兄写一个软件,用来从一大批股票资料的文本文件里面抽取出有用的信息以进行分析查询。这是属于我自己用Java真正从客户需求到完成发布版本的一次小练习,其实从中可以分析总结出一些经验。

一、收集需求

我本身对股市扔处于一无所知的阶段,而堂兄虽未算很专业的资深人员,但至少是在证券公司工作的前线人员,对股市知识的了解比我更熟悉。研究需求的过程其实挺反复的,我们彼此对需求的把握都不准确。有以下的原因:

1.他虽然有初步的想法知道想做什么,但是具体怎么做却不确定。比如说要从什么地方取数据,取多少的数据是合适,算出来的结果是否有用,过滤出来的结果是不是准确有效,这些结果要经过我先做出来给他看,他再想怎么调整这样的反复过程去细化需求的。

2.我一来对领域知识(就是股市的知识)不了解,二来对收集需求缺乏经验,很难判断他提出的需求准确到什么程度,每每以为他提出来的已经足够了,然后发现又还要继续细化下去。我在需求的把握上没有很清楚地用正确的方法学,如果可以再结合Use Case可能会更好一些。

3.在界面上不知如何设计一个原型,很多时候只能凭空解释。在获取需求的方法上,我还没有一套能够与之适应的工具。

到最后,我觉得在这个收集需求的过程,最成功的地方其实是在于我们能够快速反馈并不断进行沟通。由于双方的时间都比较自由,一遇到问题马上提出马上收到反馈,互相更熟悉了对方的工作方式和思维方式,有效的沟通比什么方法学都重要。

二、技术调研

原来在公司做的都是J2EE大型企业网站应用,快速开发的小软件则不适合使用那一套重量级的框架,一来显得很臃肿,二来修改不方便。因此在着手开发的时候,我还不得不花了很多时间去查资料和尝试,最后才找到适合用的第三方库。

在选数据库的时候,因为已经很明显不可能选以前网站用的那种数据库服务器,连最轻量级的MySql都要几十MB,所以就想办法找了些轻量级的开源数据库。像常见的Hsqldb,还有sqljet,smallsql等,一开始不知道这些具体有什么限制,文档也不是十分丰富,所以挑选就找轻量级的,能够快速实现储存数据和查询功能的,但结果发现有很多细节上却有很大限制的,不是这个功能没实现就是那个功能很复杂,虽然抓破脑袋想怎么能够利用它实现到相应的功能,结果发现还是一个大麻烦。幸好最后找到了H2数据库,在开发上都很接近JDBC的标准,性能也不差,用起来得心应手,不由得概叹那些倒弄各种类库的人,还不如弄出一个功能完备符合标准的版本更佳。

做这个软件还有另一个技术我是必须从头学的,那就是Swing。以前从来没写过桌面应用(Desktop App),虽然平时看了很多跟界面组件相关的什么Ext啊,GWT啊,事件驱动设计模式啊,多线程啊什么的,但是到写的时候,还是必须去找本入门的教程来一边看一边做。而且不管一本书写得多好,都不可能写得完整的。大部头如《Core Java》,或者是各种入门教程,技术的细节还是必须在用到的时候通过各种手段去查,技术文档,Cheatsheet,搜索引擎,图书馆找书,看别人源代码等等,这些是实在的学习方式。这里题外话说一点的是,面试里面喜欢问技术细节的面试官,如果他们通过考题只知道考察你的知识点,若答不出来则否定你的能力,那样的面试官基本上可以无视了,他们基本上不可能在工作中发现你的优点。总之,我用了一个星期的时间翻阅资料,把我软件的界面砌出来了,我对Swing还有很多不懂,但至少目前我够用了。

三、开发过程

开发过程里有几个地方是值得注意的,与平时的项目不一样。

这次我的目的是想尝试快速开发出一个能交付的产品,也考验自己做项目管理的能力。实际上前面查阅资料也已经花掉了不少时间,我要是一开始做项目计划的话,肯定做出来的计划是要延期好久。想要把项目管理做得好,就必须要将每一个任务都想得很细,每个步骤都算准了时间,但实际上这个过程对个人经验的要求是最高的,想当初前同事转到做项目经理之前,都是对整个项目内容和流程都有较深的了解才能把时间安排好的。不然,即使你把每个任务都想出来了,但执行的时候会遇到很多未知的麻烦。

另一个方面是设计以及重构的过程。一开始写的时候,我情不自禁就沿用了以前的那种建模的思维,设计领域模型,然后加数据读写层的方法,然后写文本的过滤分析,抽取数据导入数据库,然后再写查询,写界面,这个路线其实基本上还是正确的,但是实际上有些代码并没有写得很简洁的,有时只是为了在模型上好看,结果写起来就要多花了时间。后来越来越感觉到提高编程效率的重要性,于是就把提高编程效率摆在第一位,不考虑过多的设计模式了,本着这种极简主义的思想,破除所有条条框框,只留真正有用的设计,重构又再修改,发现这样反而写出来的软件足够简单,修改也十分方便。由于只有我一个人维护,而且在需求到成品里面我有很大发挥的空间,这时候这种自由度就是以前的开发中无法能及的了。我甚至不怎么需要些测试用例,因为用例本来就很简单,跑一下程序就知道结果了,如果要设计并维护测试用例反而要花更多的精力呢。

我记得敏捷开发的方法里面有说过一个叫做“加速度”的概念。在写这个软件的过程中,有很明显的感觉。当什么都没有的时候,实现第一个完整的功能是很久的,将近两周的时间。而当我交出第一个版本之后,堂兄又给我提了一些意见,之后我就进行修改,再出第二第三个版本的时间,即使是增加新功能,都是一天就可以完成了。实际上随着开发过程的不断改进,开发的效率会慢慢地提高到一个较高的水平,如果能够统计到这些数字展现出来的话,就更可以看出这种趋势了。

四、交付过程

虽说这是一个自己做的软件,用户暂时也只有堂哥一个,不过代码控制和打包发布也还是要做的(可能是由于我上一份工作的职业病吧 :) )。因此要发版本的时候,还是赶快在外面找了些svn host,用来放自己的代码和做版本控制,然后再加上ant build脚本,这一套开发的框架就完备了。最后,还是不要补上一份说明文档。原本想着, 反正用户只有一个,就不用写文档了吧,直接qq语聊有什么事把它搞定就好了。结果发现,讲一遍始终还是没有写一份文档来得实际。讲一遍,教他安装,用的是个把小时的时间。我写一份完整的使用文档,也就是两三个小时的时间。写好之后,他随时可以查文档翻阅,比起找我解决就省很多时间了,也减轻我很多后续的工作量。

如果你是一个效率至上的人,你就会想尽一切办法去减去冗余,提高效率。在做的过程之中不断地反思和重新设计,这样才是软件演化的过程。我认为做其他事情也是一样,不存在一个完美而正确的计划,所有事情的发展都是一个演化的过程,这也是我觉得很难跟那些只看计划的人沟通的地方,关键还是在于执行的过程,如果硬要我给出一个计划的话,我只能狠心一点往大了吹。