2009年5月18日星期一

鹳·垃圾站

剖宫产有一个好处,就是如果有一天孩子问妈妈:“我是从哪里来的呀?”,妈妈只要在肚子上的那条“遗址”上一指就非常明白了。
估计像我这样年纪的人,小时候问父母这个问题所得到的答案大多都是“拣来的”,不同的只是拣的地方不大一样罢了。我是在拉圾站被拣来的。我有个朋友是在垃圾箱里拣的。据说她们家门口有一年换垃圾箱,她还跟在后面边跑边喊:“别拿走!那是我出生的地方!”
在西方文化中,“白鹳”(White stork)用来像征生孩子这件事。如果有小孩问:"Where did I come from?",她妈妈或许会说: "The stork brought you to us"。刚刚出生的小孩儿在前额附近会有一条红印,在英语里被煞有其事地称为“stork bite”。其实是婴儿的静脉在发育中,通常18个月内就消失啦。
最后插播一则广告:我老婆在淘宝上开店,卖小宝宝的衣服啊什么的,大家多支技她一下吧:)

看上去现在正是一个"stork season",衷心祝愿老婆大人生意兴隆!


2009年3月22日星期日

另类穿越小说·电子生涯

这次不知道是不是火星了。
前几天在查资料的时候偶然间发现了一部很另类的网络小说《电子生涯》。之所以说它另类,是因为它的作者显然是一个程序员,而似乎其读者除了程序员也不大可能会有其它人了。小说描写2004年的一个程序员被雷劈到了1966年的美国,然后开始在计算机行业创业的穿越故事。里面充满了计算机软件、硬件,软件工程等术语,以及计算机及其相关数学的发展史。篇幅很长,真不知道作者写这种东西的动力在哪里。其故事有一定的趣味性,但太专业了,除非你对“计算机革命史”真的有兴趣,否则一定找不到太多阅读的乐趣。呵呵,说到计算机革命史,想当年在学校的宿舍里熄灯以后我也是个布道者啊:-)

我是在google“瀑布开发模型”,“Winston Royce”时偶然发现这部小说的,为了写那篇“倒霉的温斯顿•罗伊斯”。后来我读了小说的那个部分。主人公范含想要根据记忆(他的记忆非常准确,因为他的电脑被雷劈到脑子里去了)组织人力在1967年开发现在很流行的数学计算软件matlab,于是他要找到一种开发模式。小说里依然固执的称罗伊斯为瀑布开发模型的创始人,这也是没办法的事,众口铄金啊。里面还比较客观的分析了各种开发方式的利弊,指出瀑布模型是一种不合理的开发方式。我发现作者的确是行业中的明白人,因为他理所当然的帮小说主人公选择了瀑布模型做为他这个项目的开发方式。这样做是非常合理的,因为:
1.所有的风险都是已知的,范含作为一个现代过去的人,对于matlab用都用过了,对于可能的风险一清二楚;
2.所有的需求都已经非常明确,不会有新的,或者变化的需求了;
3.没有市场压力。虽然是个很有市场的软件,但在那个年代,没人指望马上用上这个东西,也没人在做同样的东西;

不知道在现实世界里有没有能满足上面任何一项要求的项目。如果有,那么不用瀑布模型来开发就是傻子。嘿嘿,如果下次有人强调瀑布模型的好处,我就可以说:“大师,你穿越了”。

2009年3月21日星期六

在线HTML编辑器 - Tabel

很多天没写博客啦,因为这几天一直忙着在写一个在线编辑HTML的小工具,用javascript。好多年没用啦,写起来很吃力。现在总算有了个差不多的版本了。嵌入了这段javascript代码的本地HTML文件可以直接在IE里进行编辑并保存。主要是一些表格操作,因此我给它起名叫“tabel”。项目的地址为:

这个工具对你可能没什么用,除非你使用Robot Framework 。Robot Framework是由诺基亚西门子网络(NSN)发起的开源软件,是一个不错的测试自动化工具。正确的使用robot framework可以写出可读性很强的测试脚本,这些测试脚本甚至可以取代需求文档。可以很方便的使用Python或java语言对其进行扩展,适用于从大型嵌入式、分布式系统的功能测试,到有图形界面的桌面系统的用户测试等很多测试领域。NSN很明智的把robot framework开源。因为软件开发中所使用的工具的成败就在于这个工具的成熟度和比软件工程还要长的生命周期,而想要做到这一点,把工具开源是一个好办法。如果它真的是个好工具那么自然会有很多人用它,并不断的改进。甚至在我自己没事时随便写写程序也会使用这个framework进行一下功能测试。

问题是robot framework的test case文件是用HTML写的,里面都是一些表格。要编辑这些test case其实只用到很少的一些HTML编辑功能,如果用word或者open office有点大材小用,而其它的编辑工具似乎也都不太合手。在开发IDE如Eclipse里目前还没有能用的开源所见即所得的HTML编辑插件。于是我就写了这个东西。在打开html文件以后,直接就可以进行编辑和保存,也不用写什么eclipse插件了。

目前,这个小工具还只支持IE(一部分因为IE安全性差)。接下来我还想实现如copy/paste等功能。

希望这个小东西能对和我有一样需求的人有用。

2009年3月17日星期二

解耦合手段之七:Liskov代换原则

周二,美国计算机协会宣布,来自麻省理工学院的女教授芭芭拉·利斯科夫(Barbara Liskov)获得本年度图灵奖以及25万美元的奖金,她的贡献是让计算机程序更加可靠、安全和易于使用。(新闻
Barbara Liskov 是美国第一位获得计算机博士学位的女性。她的研究为模块化编程和面向对向编程的产生奠定了基础。除此之外,Barbara的另一个为人们所熟知的供献是她定义了Liskov substitution principle ,我们且称之为“Liskov代换原则”。它为子类型化或者说面向对向中的“继承”定义了重要的原则。
Liskov代换原则的原文是挺难看懂的:
Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T.

幸好有Bob大叔做好事,早就写了一篇相对容易理解一点的文章来解释Liskov Substitution Principle:
使用指向基类(超类)的引用的函数,必须能够在不知道具体派生类(子类)对象类型的情况下使用它们。

举一个例子:
有一个基类Rectangle(矩形)。按常理来说,正方形(Square)也是一个矩形,那么Square类可以从Rectangle类继承而来。而事实是这样的么?假设有一个函数:
void g(Rectangle& r)
{
   r.SetWidth(5);
   r.SetHeight(4);
   assert(r.GetWidth() * r.GetHeight()) == 20);
}
很显然,这个函数对于传入的基类Rectangle变量来讲是正确的。然而如果传如入的变量是Square类型就不正确了。因此,Square与Rectangle之间的继承关系违反了Liskov代换原则。
那么为什么会这样呢?从常识(或几何定义)的角度来看,正方形是一个矩形;然而从行为的角度看,正方形不是一个矩形!因为正方形的行为与矩形有所不同。如果一定要让正方形继承于矩形,那么正方形的行为必须修改矩形的行为。可以看出,这同时也违反了“开闭原则 ”。

Liskov代换原则与“契约式设计(Design by Contract)”也有很紧密的联系。在Design by Contract的模式下对于一个类的方法有precondition(先决条件)和postcondition(后置条件)两个概念。Precondition是为了使用这个方法而必须事先满足的条件;Postcondition是这个方法必须保证它被使用以后成立的条件。由Liskov代换原则我们可以得到:
.子类不应要求比基类更高的precondition。
.子类不应弱化基类的postcondition。
例如上面的Rectangle类里SetWidth方法的一个postcondition是矩形的Height不应发生变化。这个postcondition在Square中就不能满足。

发现中文维基中没有Liskov代换原则的条目,把它补上:


2009年3月5日星期四

倒霉的温斯顿•罗伊斯

温斯顿•罗伊斯(Winston Royce, 1929–1995)地下有知,一定会感到非常懊恼。因为他被人们公认为是瀑布开发模型的创使人。

几乎所有的讲软件工程的书或文章中提到瀑布模型时都会加上引用“... waterfall model [Royce70] ...”。这篇Royce写于1970年的文章被称为“瀑布模型的摇篮”:



如果读一读这篇文章,你会发现,这些引用的人并没有真的花点时间去读一读它。因为Royce的这篇文章只是想说明瀑布模型并不能工作。在文章的最后Royce甚至指出应该采用迭代的方式进行软件开发。


瀑布模型的一个简单的例子就是:


需求分析->可行性分析->高层设计->详细设计->编码->底层测试->系统测试->发布->维护


这样的一个顺序开发模式。


瀑布模型的流行不仅因为他看上去很合理,另一个主要的原因是它受到了美国国防部(Department of Defense)的追捧。后者要求它的合同商采用瀑布模型进行开发。美国国防部的指导精神随之影响到了北大西洋公约组织(NATO),瀑布模型想不流行都不行了。其结果,对美国国防部而言是导致了其超过50%项目的失败。然而与Royce同期甚至更早的软件科学家们更多的提倡迭代开发,如冯·诺依曼。


与瀑布模型同出一辙的“V模型”,其实质都是一样的,是一种理想化了的软件开发模型。对于可预测性强的生产制造业,如生产汽车,的确很适合这种生产模式。然而对于具有很强的不可预测性的新产品开发,如生物学研究、新药的研发等,就不合适了。同软件开发一样,这些研发工作都更适合用迭代的模式来“生长”出来。




在中文维基中“瀑布模型”条目中对Royce对这个模型的供献描述并不准确,去修改了一下:

百度百科里仍是把Royce作为瀑布模型的提出者而不加解释,由它去吧。
另,美国国防部已于1994年放弃了瀑布模型。


2009年3月4日星期三

Craig Larman来访小结

Craig Larman这次来我们这里一共三个星期,期间我花了一些时间参与大师Coach研发部门的各项活动,并与大师讨论了一些关于Agile和软件工程的问题。感觉学习到了不少东西。

生活中的大师是非常浪漫的,这不是本文的重点。在工作中的大师是非常严谨的,常常引用一些已有的论文或研究结果,当谈到个人观点时总是很小心。

大师比较强调工程师的软件设计能力。当然,他也反对BDUF(Big Design Up-Front),但他认为,一定的事先Design还是需要的。例如在一个迭代周期伊始,team应该组织一个Design Workshop,来讨论和决定一些Design的大体状况。当然大师也重调不断的refactoring。大师说:“TDD can also make very bad design.”他要说明,仅依靠某种开发方式是不会自然而然的得到好的design的,关键是要有设计的能力。大师甚至引用禅宗的道理来比喻软件设计(http://terry-yinzhe.spaces.live.com/blog/cns!92560BAA05230C71!315.entry)。





大师还讲解了一些需求分析的方法。这些方法多是在他帮不同的team组织backlog grooming与sprint planning I时引入的(backlog grooming与Sprint Planning I是Scrum中的两项活动,这两项活动的一个共同目的是澄清需求)。并且大师给出了切实可行的ATDD方式,包括:
1.如何用user story的方式来描述需求
2.如何把user story拆分成合适的大小
3.如何把user story用use case、表格或UML的方式来详细描述
4.如何把前面需求分析的结果用workflow或者data table的方式用pseudo test script来描述等。
在sprint中间(或者说一个迭代周期内)就以这些test script的通过为目标进行开发。大师强调“需求”与“设计”间的区别,要求需求分析一定要尽量面向最终用户。(http://terry-yinzhe.spaces.live.com/blog/cns!92560BAA05230C71!376.entry

大师强调,瀑布开发是限制软件交付能力的主要因素。但他引用COCOMO模型来说明,在一个项目中人的因素最重要(http://terry-yinzhe.spaces.live.com/blog/cns!92560BAA05230C71!407.entry)。在批评有些人对Scrum中有“所有的人能做所有的事”这种理解时明确的指出,我们要的是specialist,不是generalist,当然最好是generalized specialist(http://terry-yinzhe.spaces.live.com/blog/cns!92560BAA05230C71!355.entry)。


大师还谈到了应用agile的目的。他说,agile的目的不是提高生产力,或者提高质量,agile就是为了agile,“The purpose of adopting agile is to be agile”。Agile的目的不是用更少的人做更多的事,并且做得更好。这些目的都是通过提高人的能力或者其它软件工程手段得到的。Agile的目的是关注客户价值,提高交付能力和灵活应对改变等。从而,使企业有机会及时为客户创造更多价值,并不断改进。因此他说,“be agile”比“do agile”更重要。也正因此,大师也说,与其学会agile的方法,不如学会agile的思想。大师称之为thinking tools,主要包含了:System Thinking、Lean Thinking、Queuing Theory等。这些思想方法全部包含在他与Bas Vodde合著的《Scaling Lean And Agile - Thinking And Organizational Tools》中。

当然,大师的言行不止于此。最后引用他给我在他的《Applying UML and Patterns》这本书上的留言:
“May all your objects be suitably coupled.”
-- Craig Larman


软件成本估算模型COCOMO

这两天研究了一下软件成本估算模型COCOMO,顺便在中文维基里添加了COCOMO条目:

http://zh.wikipedia.org/wiki/COCOMO






完全是从英文的wikipedia里翻译来的。当然,要了解COCOMO恐怕要读完那本《软件成本估算:COCOMO Ⅱ模型方法》才行。不过我并不是真的对这种枯燥而又形式化的东西有兴趣,只是想了解一下COCOMO模型中对影响软件开发的各种因素的评估,因此,我想简单了解了下也就够了。

COCOMO模型(Constructive Cost Model)的中级公式引入了一系列影响开发成本的因子,包括:


  • 产品属性
    • 软件可靠性需求
    • 应用数据库的大小
    • 产品复杂度
  • 硬件属性
    • 运行时的性能约束
    • 内存约束
    • 虚拟机稳定性
    • 回复时间的需求
  • 人员属性
    • 分析能力
    • 软件工程能力
    • 应用经验
    • 虚拟机的经验
    • 编程语言经验
  • 项目属性
    • 采用的软件工具
    • 采用的软件工程手段
    • 对开发时间的要求



把所有的因子相乘就会得到总的“工作量调整因子(EAF)”。我对这些因子的最大值和最小值的比率做了统计。似乎结果说明就总体分类而言,人员因素对软件开发的影响远高于其它因素。

就具体影响因素而言,“产品复杂度”似乎是最大的单一对软件开发影响的因素,其次是人员的分析能力和软件工程能力。

因此似乎可以得到这样的结论:对软件开发影响最大的是人的因素,其中人的分析能力与软件工程能力尤其重要。产品复杂度也是影响软件成本(工作量)的重要因素。 同时,值得注意的是“对开发时间的要求”,即软件项目的工期压力对软件工作量的影响微乎其微。这也说明了,管项目的人催得再紧,对其结果也不会有什么大的改变。
Craig Larman在引用COCOMO模型时也指出,人的因素远大于其它因素,包括排名第二的产品复杂度。并且他指出,这些因子是在同一种软件开发模式下得到的(例如瀑布模式),软件开发模式(例如采用迭代开发)对软件开发成本的影响比这些因素都要大。