2008年12月25日星期四

中文类名

彩色UML图可以用即时贴在白板上设计,也可以使用支持UML图的工具画出。但是使用工具要注意一点,就是设计好的模型应该打印出来,贴在墙上,让经过的人都可以驻足观看,发表意见。这就是敏捷方法学中的信息辐射原理。沟通无时无处不在。

这样做的好处是明显的。每个人都有机会熟悉全部的业务流程,以达到对系统的一致理解。有疑问,早提出。特别是领域(业务)专家,可以不断想起点什么要补充的。

但是有一个问题:类名应该使用英文吗?

和用户沟通有一个重要的原则,要使用用户熟悉的语言和图表。画用户看得懂的UML图。如果用户英文不好,如果用户平时都讲中文,所有的领域词汇都是中文,那么用英文的类名画出的彩色UML图挂在墙上就有点小麻烦了。

有一个改进方案,在类名后面用括号注明中文意义,如:OrderMaking(下订单)类,这是一个红色的时刻-时段。

还留着英文类名是为了写程序的方便。这样我们维护了一个映射关系,即中文领域词汇和英文类名的映射。当然,也可以创造性地使用拼音,如:XiaDingDaning(下订单)。

但是我记得以前试过,在Java里可以直接使用中文类名。所以又试了一下。

public class Main {

public static void main(String[] args) {
下订单 这次下订单 = new 下订单();
这次下订单.确定();
}

}

class 下订单 {
public void 确定() {
System.out.println("Good!");
}
}

哈,可以运行!也许业务层代码这样写更好玩。

2008年12月18日星期四

用例和特征

Alistair Cockburn在他的《编写有效用例》一书中指出,“海平面用例”的特点如下:
  • 一个人、一个地点、一个时间(2至20分钟)
  • 完成了就高兴地离开
  • 参与者(如果是职员)做了很多这样的事,可以要求获得加薪或升职
在特征驱动开发中,特征集是
  • [action](ing) a(n) [object]
例如,“进行一次产品销售”

所以在大致上,我们可以将特征集与“海平面级用例”对应起来。因为如果“销售员”完成了很多“进行一次产品销售”或做得很好(销售额大),就有理由提出升职或加薪要求。

在特征驱动开发中,特征是
  • [action] the [result] [by|for|of|to] a(n) [object]
例如,“计算一次销售总额”。

虽然做很多的“计算一次销售总额”不能导致升职或加薪,但这个特征对于客户来说显然是有价值的。所以在大致上,我们可以将特征与“水下级用例”对应起来。

在特征驱动开发中,主特征集是
  • [object] management
例如,“产品销售管理”。

“天空或汇总级用例”反映了多个人的目标,例如“保险购买、支付和理培”。所以大致上,我们可以把主特征集和“天空级用例”对应起来。

2008年12月7日星期日

彩色书中文版上市了


彩色书中文版终于上市了!

Peter Coad是我仰慕的前辈大师。大约在1997年,朋友李亮向我介绍了他和Edward Yourdon合作的《面向对象设计》。那是一本小册子,我一看就喜欢上了。全是经验之谈,没有东抄西抄。原书是1991年出版的,中文译本是1994年出版的。

没想到多年以后,以这样的方式接近大师。彩色书的原书是1999年出版的,距现在也快10年了。一年以前,我向推荐华章推荐引进这本书。今天,终于与中国的开发者见面。

在2000年左右,敏捷方法学开始兴起。过了几年,我注意到了敏捷方法学中有一枝是特征驱动开发(FDD)。这种敏捷开发方法有一个特别的地方,它强调整体对象建模,即前端设计。而且采用了一种极有特点的彩色UML建模的方法。然后我看到这种方法背后大师的名字。

网上关于彩色UML的内容不多,但我还是设法搜集了一些。这些年,我一直在研究Java、工作流、开发方法学、UML建模方面的内容。等到我看到FDD和彩色UML,这些内容忽然就贯通了,有一种醍醐灌顶、任督二脉打通的感觉。

好的东西就是你从未想过拥有,但是一旦拥有,就别无所求。彩色UML给我这样的感觉。

有一年Martin Fowler到上海,在交大和林德彰教授讨论软件开发方法学,还发生了一件趣事。林教授把传统方法学比喻为楷书,把XP比喻为草书,认为先要打好楷书基础,然后才能学草书。当时我提出,敏捷方法中的FDD注重前端设计,同时又保持轻量级方法学的特点为,可能是行书。会后,一个白人老外专门跑过来跟我交流,说谢谢我提到彩色UML和FDD,并说他们的公司在张江,在开发时就采用这套方法学,效果很好!

曾经跟华章的编辑开玩笑说,这本书不引进,是中国计算机出版界的羞耻啊。现在我要对他说,功德一件!

2008年12月4日星期四

服务治理

几年前,为了尝试JDK 1.5中的并发包,我写了一个多线程的爬虫程序,利用线程池来分析B2C网站上的商品价格,希望可以做一个shopping.com那样的比价网。

并发200个线程,每个线程从待爬URL队列中取得一个URL,取回网页,进行分析,找出其中的价格信息,再找出其中的URL链接。开发过程很正常,但在测试中遇到了问题。在爬了7万多个网页之后,程序开始越来越慢。凭感觉判断,有一些线程“死”掉了。

多线程的调试并不是件容易的事。这个问题很“难”再现。不是普通意义上的难再现,它每次都会出现。但要跑到7万多URL时,才会出现。我试过将线程池退化到1,想找出什么样的URL会导致线程死掉,但这个代价太大了,因为速度很慢。当时的IDE也缺乏对多线程调试的一些支持。而且即便有支持,可能也不太适合这种情况。后来因为种种原因,那个程序就不了了之了。

最近接触的SOA治理和彩色UML的内容给了我一些启发。我们需要关注服务执行的健康状况和服务执行的时间。例如,我们可以进行这样的改动:

在每个线程领取URL时,记录一个时间戳。在它完成这个URL处理时,再记录一个时间戳。再利用一个线程,对未完成的URL定时检查它的健康程度。如果在很长的一段时间内它还没完成,那么它就有问题。这样我们可以找到嫌疑URL。我们可以对这种URL单独测试,看看是否因为程序的原因,不能处理这样的URL。

或者,我们可以把对应的线程任务杀掉,直接跳过这些有问题的URL。

程序在设计时,要考虑运营维护需求,其中包括迅速故障疹断和纠正能力。这就是传说中的“可用性”需求吧。

2008年11月30日星期日

从SoftCon归来

两天的中国软件技术大会结束了,收获不少。

潘加宇的“提升技能,准备过冬”是很有启发的,提出的一个公式让人印象深刻:利润 = 需求 - 设计。需求是客户愿意付钱的东西,满足需求越多越好,就可以收越多的钱。设计是实现的成本,是费用。如果可以用一个简单、灵活、有弹性的设计来不断满足客户日益增长的需求,你的利润空间就大了。

由此让我重新思考了架构的意义。架构的弹性,即适应变化的能力,确实是好的设计的核心。业务架构和技术架构都很重要。周日午餐时遇到上海某证券信息公司的技术人员,聊到他们的系统,需要支持大量(30G左右)数据的高并发查询。目前已采用了全内存的方式,但持久仍然使用的是关系数据库。痛苦的地方在于,每次重启要将30G数据加载到内存,这个时间非常长,而且客户是不能忍受的。只好做了双机的架构,切换之后,再重启其中一台。如果有一个好的架构,这样的痛苦和成本,就不必承受了。从文本文件加载数据的速度大约可以是1秒钟1G,这样重启的时间可以压缩到1分钟之内。如果客户仍然不能接受,还可以上双机高可用方案。数据库是个好东西,但不是每种场合都适用。

把数据加载到内存后,再使用LINQ这样的解决方案,就能够提供方便的查询。企业信息管理人员,应该好好考虑一下架构迁移。

本次大会的另一个收获就是和徐锋住一个房间,发现我们有许多共同的兴趣,包括软件、围棋和阅读经典。谈到深夜。有朋自远方来,不亦乐乎!

2008年11月23日星期日

对象初始化和Giuce trick

在使用POJO组件对象时,常常需要在对象实例化之后,调用该对象的某个初始化方法。例如,

PersistentLayer.init()

我们在持久层里准备一些初始的业务数据,如第一个超级用户和一些数据字典。
在Spring框架中,提供了这种post-constructor的初始化方法调用机制,但Guice却没有。Guice甚至不理会无参构造方法。(两点说明:1. 在构造方法中完成初始业务数据的准备不太妥当,构造方法应该保持简单,尽量不要加入业务逻辑。2. Guice不执行无参数构造方法,我只是简单试了一下,确实如此。Guice的这个feature肯定有自己的考虑,需要读源码确认,并查一些资料,了解背后的设计考虑。)

这个问题困扰了我们半个小时,考虑过两种绕过去的方法。

一是在封装Guice的Factory中,对对象实例进行处理,如果对象有init()方法,就执行一下。这种方法并不漂亮,涉及泛型、反射,有点复杂。

二是在应用代码中每次请求PersistentLayer时,调init()方法,设置一个静态开关变量,记录是否已经初始化过。同样,这种方法不漂亮,涉及了很多重复。将一个隐含的假定(使用PersistentLayer时,必须先调用init()方法)扩散到了应用代码的各个地方,这种重复是不能容忍的。

最后找到了一个解决方案,即使用Guice的“绑定到实例”的能力。在MyModule.class中,

PersistentLayer pl = new PersistentLayerMemImpl();
pl.init();
binder.bind(PersistentLayer .class).toInstance(pl);

网上有人提到“Guice目前来说还只是个玩具”,提出如下问题:

“不可否认Guice是一个设计精巧的IoC容器,速度也很快,但是这个容器连最基本的对象生 命周期管理都没有,也就是要提供JSR-250里面javax.annotation.PostConstruct和PreDestroy的功能,有人提 出用无参数的@Inject方法来模拟init,这样明显是对Annotation的滥用,用构造参数注入然后在构造方法里面做初始化,这虽然是一种解决 方法,但是有的情况下对象可能需要reinitialize,这样还是需要把初始化单独做为一个方法,用finalize方法来做destroy更不可 取,没法控制什么时候执行.这个问题去年三月就有人提出来了到现在还没有解决,Guice的开发者还是不够活跃,这里这么多人捧Guice,不知道有多少人正式用在项目中.”

我想这种方法也许是一种解决方案。

2008年11月20日星期四

2008 SoftCon

确定作为演讲嘉宾参加11月29、30日的SoftCon中国软件大会。北京的朋友们来找我吧!

2008年11月16日星期日

信息渠道

一般来说,最成功的人,是拥有最好信息的人。这里的“一般来说”指的是任何年代,任何行业。

厉害的师傅,教出厉害的徒弟,因为师傅那里有最好的信息。出门靠朋友、多个朋友多条路,因为朋友那里有好信息。做投资的人很清楚这一点,做生意的人也清楚这一点。

这样看来,信息技术课应该是最基础的基础课,重要性甚至在语、数、外之上。要学好一门学科,或者要掌握一门技术,信息来源是决定因素。

企业的信息系统是最重要的系统,让决策者有正确的依据,做出informative decision。CIO是个重要的职位,推动整个企业的信息化建设和水平。

对于个人来说,建立起自己的信息渠道尤为重要。每天读报?每天上网?每天听广播?每天读博客?参加培训?参加技术交流?

Internet的进步在于,降低了信息交换的成本,尤其是Web 2.0。

确定一个目标,然后组织好信息渠道,帮助你实现该目标。

2008年11月9日星期日

XML很好,JSON更好

在一些情况下,JSON的好处是一目了然的。这里有一篇简单介绍的文章:What is it and why use it?

在设计配置文件时,我们可以使用ini的方式、properties文件的方式、XML的方式,现在又有了JSON的方式。我们可以有一个Config接口,再有一个ConfigJsonImpl实现。一个典型的边界类。

这个故事告诉我们:XML虽好,也不应该到处用。在应用中,要把对XML的使用封装起来,集中在一起。以便于在出来更好的东东时,将它替换掉。

同理,JDBC虽好,也不能在应用中到处使用,要把它封装到持久层中,以便有机会把它替换成别的什么东西。

假定我们使用一种特定的技术,让这种假定出现在应用程序中尽量少的地方。这符合伟大的“高内聚,低耦合”原则。


2008年11月6日星期四

以架构为中心

架构,根据OMG在MDA中的定义,就是指系统由哪些组件组成,以及这些组件之间的相互关系。关注这些问题的人,称为架构师。业务系统由哪些子系统组成,这些子系统之间的相互关系如何,就是业务架构。在技术层面上,采用BS的三层架构,这是指技术架构。

RUP是强调架构的。在早期的RUP文档中,指出RUP的特点是:用例驱动、以架构为中心、迭代增量式开发。很正确。谁说不是呢?换句话说,就是:业务需求驱动、关注设计的优秀性、早发布常发布。以架构为中心的理由是,好的架构具有弹性,可以容纳将来可能的变化。

Java是强调架构的。Java提供了极为灵活的架构,所以为后来的发展提供了巨大的可能性。可以添加新的特征,而不用伤筋动骨。

在考虑类的设计、类之间的协作 关系时,也是在设计架构。好的类设计为将来的特征添加提供了可能性。以前面文章中提到的彩色UML设计为例:

将来可能添加的特征包括:
列出某个店的所有员工
列出所有的店和店主
列出某个员工的任职经历
列出某个店的历任店主
列出曾经担任过店主的所有员工
......

彩色UML设计保留了完备的信息,在今后系统需要添加新的特征时,不需要改设计(架构)。这就是弹性。

Matin Fowler有点反对架构的意思。 YANGNI (You are not gonna need it) 。甚至说做过架构师的人他一律不招。如果我没有错误理解他的意思,那他基本上是错了。我们可以重构,架构可以演进,但我们追求的是一次做对。总是惦记着错了可以推倒重来是不好的。就像小学生,用橡皮上瘾。就像下棋,老想着悔棋。应该像中国书法和绘画一样,追求一笔下去,就不能改,也不用改了。就这么点追求,不过分吧?

人无远虑,必有近忧。完全不为明天考虑,不为将来可能的变化考虑,这是什么样的人啊?

一篇关于彩色UML和FDD的文章

网上看到一篇关于彩色UML和FDD的文章:Domain Modelling using color UML

个人觉得,执着于标准的四种颜色RGB值,有点过了。选择看起来舒服的四种颜色,不要偏太远就行了。

也用了即时贴,贴在了白纸上。看来把墙改造一下是很有必要了。可选方案有:1、毛玻璃墙或隔断。2、彩钢板的墙。彩钢板的墙有一个额外的好处,可以用吸铁石吸住一些纸张,例如书法绘画作品。

将墙面作为一个信息幅射源是很好的主意。任何人走过来,看到这些信息,都可以发表意见。这是敏捷的沟通和反馈价值观。不幸的是,国内许多软件公司的墙面是空空的,什么都没有。

最后总结了3点不好的地方,值得商榷。
1. 项目早期需要哪些人参与?
领域专家、业务人员的早期介入,持续介入,是项目成功所必需的。避免了做出客户不想要的产品,增加了客户满意度,让客户对系统开发的工作量有正确的认识。IT人员和业务人员之间的沟通是最难的,他们讲的都不是同一种语言。而沟通正是项目成功的关键。XP的C3项目,最后也是死在沟通上。

2. OOAD的人才缺乏怎么办?
请人。请OOAD的专业人士做培训和现场指导。让开发团队迅速地成长起来。

3. OMG,我们在做大的前端设计,What a shame!?
我们要背负不敏捷之名吗?Martin Fowler说,设计已死。他在面试时,凡是做过架构师的人,一律不招。我认为,他有点走极端了。敏捷不是目的,只是手段。目的是项目取得成功,皆大欢喜。下棋讲究局部战斗计算,同样也讲究大局观。布局不好,中盘将陷于苦战,最后可能不必收官。

2008年11月5日星期三

指定角色

彩色UML建模方法中,黄色的角色是个相对较难理解的概念。角色表明获得某种资格,可以参与红颜色的时间-时段(多数时候就是业务事件)。例如,绿色的一个“产品批次”,它有一个黄色的角色“库存产品批次”,那么,它就可以参与库存的一些操作,如移动位置,出库等等。

角色很多时候可以代表职位,如“销售员”、“门店经理”。程序通过这些角色,来实现功能权限的控制。

绿色的Party-Place-Thing获得角色的方式不尽相同。例如“产品批次”通过“入库”操作,就获得了“库存产品批次”的角色。而对于代表职位的角色,通常会通过某种“指定角色”的动作。

这种角色指定,有时候会比较复杂,本质上是创建一个关联类的实例。例如,为某个门店指定一名门店经理。

2008年11月2日星期日

TestNG书的中文版上市了

TestNG书的中文版上市了。

这本书首先告诉了我们为什么除了JUnit之外,还需要另一个Java测试框架。TestNG的多项设计,确实是出于作者在实战项目中的经验,值得称道并研究。

两位作者向我们澄清了一些测试中的模糊概念,例如“如何正确看待测试覆盖率?”“先写测试代码有多好?”作者给我的印象是:放弃一切教条,实战最为重要。

对J2EE环境下真实项目的测试,Spring框架在测试中的作用,这些问题恐怕都是Java开发人员每天都在操心的问题。这本书指出,世面上已经有不少讲测试驱动和敏捷开发的书,但其中的例子不是Money类,就是保龄球计分问题。而开发者在真实世界中面临的问题要麻烦得多,面临更多的折衷和选择。这本书介绍了许多目前流行的Java框架在测试中的使用,无疑会对开发者带来较大的启发。

Cedric现在在Google,参与了Android项目。我们也可以看到著名的批评家Hani在正式出版物中想说些什么。

如果你读过Kent Beck的《测试驱动开发》,觉得有启发,又还有很多疑问,如果你在实际工作中需要编写开发者测试代码(不限于Java),那么可以试读一下这本书。

从某种角度来说,容易测试的设计才是好的设计。这本书是我向出版社推荐的,也是我想向大家推荐的。

2008年10月30日星期四

彩色UML建模-白板、马克笔和即时贴



David Anderson曾贴出过用即时贴在白板上进行彩色UML建模的照片,但是我找不着了。

结果什么都不是,重要的是得到结果的过程。这张图是IT人员和业务人员半天讨论的结果。这远不是最终结果,在开发过程中,还会有进一步的改善。

UML的最初意图是方便IT人员与业务人员的沟通,通过彩色UML建模的方法,我觉得大家对沟通的效果是相当满意的。

一般的文具小店很难买齐4种颜色的即时贴,我们就缺了蓝颜色,史泰博上有卖。

以后会议室的装修应该在墙上装彩钢板,可以作为投影屏幕,可以用磁铁在上面吸住一些纸张,也可以用即时贴在上面进行彩色UML建模。开发办公室似乎也应该这样。

2008年10月29日星期三

Terracotta - Java社区的力量

Terracotta 是Java社区力量的一个例子。它的Demo令人印象深刻,Case study也很打动人。

我能想到的是,做一个NAM集群,使用HSQL/H2/Derby这样的内存数据库,传统应用的速度要飞起来了。

或者使用 prevayler 的方式做持久,两台服务器组成一个16G内存的系统,成本也很低。

或者Apache Directory Server + HSQL/prevayler + Terracotta,建立快速的LDAP集群。

谁出钱请我去玩一下?呵呵。

2008年10月27日星期一

控制风险和把握机会

朋友问我为什么“软件如棋”,我的意思是“控制风险和把握机会

项目失败的风险有很多,关键是要意识到,并采取措施防止它变成灾 难。就像下棋,对手危胁你一块棋的死活时,你不能浑然不知。大龙不是一刀被砍死的。大的灾难就像麻绳,由许多细小的纤维组成。要对风险足够敏感,这需要知 识和经验。武士所感受到的杀气,有经验的程序员感受到的坏味道,Yourdon所说的“死亡行进”,都是对风险的感知。控制好风险,就立于不败之地。

如果你不主动进攻风险,风险就主动进攻你。

机会,就是你有可能将一些风险提前消灭掉。你有机会杀死对方的大龙,这盘棋就愉快地结束了。后面的风险都被你成功的提前化解了。例如复用一个成熟的产品,可能帮你消除沟通需求、编码、查错、测试、时间进度、成本等等许多风险。机会稍纵即逝,必需时刻准备着,要赢得漂亮。

先为不可胜,以待敌之可胜。

软件就像下围棋,在大量复用的情况下,每个项目都不一样。

人生也如棋。

有人问我Java到底是哪里好

程序员有一个很朴素的想法,希望自己写的软件被尽量多的人使用,所以Java的承诺是很诱人的,它保证你写的程序能在主流计算平台上运行。这将世界上大量的有想法的程序员聚集在了Java旗下。一个公司里面的牛人再多,也比不上公司以外的牛人多。另一个可以匹敌的社区是c/c++社区,但这个社区被分化成了linux c/c++和windows c/c++。

有了强大的群众基础,才会有天才选手冒出来。今天的Java,百花齐放,异彩纷呈。这可能让初学者感觉眼花缭乱,但这种情形正是高手所喜欢的。你可以有选择。就像Spring,可以选择不同意Sun的推荐J2EE架构,设计另外一套应用程序架构。

Java的社区足够开放,让所有好的想法不会消失。POJO组件的想法、Xdoclet的思路、组件必须容易进行单元测试的观点,集中在一起,让EJB改头换面。O/R mapping催生了Castor,但最后成就了Hibernate的辉煌,进一步又促成了JPA规范。在这些不断出现的创新中,我们看到了一个充满活力的、良好的生态环境。

在这个生态环境中,程序员如鱼游入大海。

在贴近硬件和操作系统的地方,是c/c++的领地。在浏览器中,是js的地盘。