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),那么可以试读一下这本书。

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