2007-05-22

Eclipse Tips

1. 在Eclipse中运行DOS

这种方法的好处是连DOS执行窗口也集成在Eclipse Console中。

在上面的设置是,Working Directory的设置非常重要。${container_loc}表示以当前选中文件的上级目录为工作目录。如果你选中的是某个目录,比如说某个包,那么很不幸,它会指向这个目录的上级目录。所以,${container_loc}只适合选中一个文件的情况。

另一个变量${resource_loc}则相反,它总是以选中的文件或目录为工作目录。就是说它适合选中一个目录的情况。如果选中一个文件,运行DOS就会出错,因为文件不能作为DOS的工作目录。

两个变量各有优缺点。由于Java编程中,大部分DOS命令是在工程目录下执行的,所以${resource_loc}会好一些。使用${container_loc}很难定位到工程目录。

2. Mylar导致Content Assist中出现重复的方法提示。

最近发现我的Eclipse 3.3M7中出了个不大不小的问题,就是Java编辑窗口中的代码提示工具把每一个方法都重复的列了两次。如下图所示。

这个问题让我百思不得其解,最后打开java -> Editor ->Content Assist的设置,才发现是新装了Mylar的原因。如下图所示,Mylar为content assist增加了几个同名的Proposal,将这些同名的Porposals任意勾掉一个就解决问题了。

Technorati :

2007-05-11

Spring断想:接口粘合

Spring和AOP像一个强力的粘合剂,将完全独立开发的组件(或说是模块,下同)粘合成一个有机的,完整的,可扩展的系统。正是有了这个粘合剂的帮助,才实现了比较彻底的独立组件开发。

说它是"比较彻底",是因为它极大的减少了组件之间的依赖。在你开发一个组件时,基本上不会因为其它组件没有开发完成,或出现Bug而影响到你的进度。

但是,它并没有完全消除开发时组件之间的依赖,你仍然得依赖于其它组件提供的API接口。为此,我们不得不把一个组件拆成两个jar包:一个component-api.jar,一个component-impl.jar。由于api包内全是公用接口和Value Object,所以它相对稳定,可以早早的提供出来。这样,一个组件如果要使用另一个组件的服务,在开发阶段,只须依赖于api包即可。运行时,Spring再根据服务提供组件的配置信息找到正确的实现类。

昨天,我们在一个讨论会上发现了一个有趣的问题:

组件UIA是一个UI组件,它要求提供一些数据,于时它把自己的要求写时接口ProviderA中。组件C1和C2是两个不同的业务组件,它们的UI中都有使用UIA这个组件,而它们都提供了自己的数据接口ServiceC1和ServiceC2。

ProviderA所要求的方法,在ServiceC1和ServiceC2中都有提供。这个时候怎么做才能使各个组件完独立呢。

一、让ServiceC1和ServiceC2继承于ProviderA。但是这样将导致业务组件依赖于UI组件。有谁知道一共有多少个UI组件需要依赖啊?而且UI组件是最易变的。

二、把ProviderA从uia.jar抽出来,放到单独的uia-api.jar中。这个就未免小题大做了。一个系统少说也有几十个UI组件,难道要生成上百个jar包不成?

三、把所有的UI的要求的API都抽出来,放到一个ui-api.jar中。这样jar包是少了,可是单个的UI组件就失去独立性了。

上面三个方案,不管怎么管理UI组件的接口,都没有解决业务组件依赖于不定数目的UI组件这个问题。

最后,我们采用的方法是:把UI组件视为某个业务组件的子组件,UI组件自己不定义接口。所有对外的接口和对UI的接口,都放在业务组件的api包中。

这样做,业务组件和UI组件都依赖于api包,互相之间没有依赖。当然,这样做,UI组件就不能游离于大的业务组件之外。而我们采用这个方案的原因也在于,我们认定为多个组件提供服务的UI组件是很少的。

显然我们采用的方法只是就事论事的一个折衷方案。并没有解决服务提供者和消费者之间的交叉依赖。

要解决这种交叉依赖,我的思路是再提供一个接口之间的粘合机制。消费者定义自己要求的服务接口,提供者定义自己提供的服务接口。最后用一个配置文件,将二者粘合起来。

目前,Spring还没有提供这种功能。

Technorati : ,

2007-05-04

定制Powerdesigner Profile,实现个性化的双向MDA

Powerdesigner是我最喜欢的建模软件,其功能最全,易用性最好,使用感受最舒服。可扩展性也非常好。 Powerdesigner对MDA的支持很灵活。其实,MDA工具所要做的事情,就是UML模型与代码间的双向转换:从模型可以生成代码;从代码可以生成模型。这里面有两个关键点: 1、模型生成的代码不能是垃圾代码,要正确,还要符合我们所指定的编码规范--尤其是注释。 2、从代码到模型再到代码时,原始代码中的所有内容应当充分保留。不应发生注释或方法体丢失。 我根据特定的编码规范,通过二次定制powerdeisgner的java 5语言成功实现了上述MDA特性。 在powerdesigner中,编程语言完全是一个定制项。其全部特征信息都记在一个后缀名为xol的xml文件中。比如java5的定制文件是Powerdesigner 12\Resource Files\Object Languages\java5-j2ee14.xol 专家级牛人可以通过修改这类文件达到任何目录。对于我来说,xol文件太长,有太多的cdata,不好搞,还是通过powerdesigner中的"edit current langauge"来修改比较好。 在powerdesigner中点击language->edit current language,就会出现语言特性编辑界面。要编辑它比较容易,下面就几个关键特性举例说明。 1、每个java文件最头部的声明性注释。位于文件最顶部,在package和import语句的前面。

2、类注释,也就是javadoc注释,位于类声明之前,import语句之后。Powerdesigner直接支持它。

我们的@version内容不是一行代号,而是一个revision history。所以有必要调整输入框:在上图中将Data Type由String改为Text。这样就可以在一个弹出的多行文本编辑框中编辑缺省值。如下图所示。

如果定制模板,可以引用变量,如%@author%, %Model.Author%, %CurrentDate%等,但上面缺省值编辑中不能引用变量。此外,Powerdesigner对于日期的格式化只是简单的输入缺省格式。

这样在类和接口的属性窗口中,java doc version就不再是一个单行文本编辑框了。

3、最后输入的javadoc注释格式有点不符规范。可修改如下。

这样,最后输出的结果就很漂亮了。

上面的@pdOid是可以删掉的,因害怕影响逆向工程的同步,我没有动它。

4、上面收尾的"*/"没有换行,可以在BaseObject.javaDocComment中修改。

5、Javadoc要求每个包有个package.html。

6、我们不用EJB了,把多余的EJB原型(Stereotype)全部删掉。类和接口下也有,都可以删掉。

Powerdesigner生成java代码的定制虽然强大,但也有不足。比如在模型中给类添加了一些属性,然后让其自动生成setter方法。这些setter方法中的参数是以"new"会前缀的,想把"new"改成"p"基本上做不到。究其原因,是这个方法的声明来自自动生成脚本,我们无从定制。

Powerdesigner的逆向工程功能也很棒!不过要注意两个设置。一是保留@pdOid注释。二是确认是否删除代码中不存在的类、方法和属性。如下图所示。

上面的Deletion缺省是不选中的。就是说不删除模型中存在,但代码中不存在的类,属性和方法及方法中的参数。对于类来说删不删各有所好。对于属性和方法来说有点不合理。对于方法中的参数来说就是个灾难性的错误。

比如,模型中的有个方法someMethod(String parameter),在源代码中、参数的类型由String改成int: someMethod(int parameter),保持名称不变。如果不选Deletion,最终结果会是:SomeMethod(String parameter, int parameter2)。

@pdOid是专为逆向工程服务的。有了它,Powerdesigner就以它为唯一标识来识别类,属性和方法。即使在类、属性或方法的名称发生变化的情况下,它仍能正确逆向的更新模型。

在没有@pdOid时,如果发生类名的变化,Powerdesigner会新增一个类,并删去旧类(当选中Deletion时)。引用这个类的时序图或类图将发生类丢失的现象。

除了定制生成代码的模板外,Powerdesigner也支持自定义逆向工程--从java 代码到OOM模型。如下图所示。

但是,我们并不能扩展Powerdesigner内内置的逆向工程,只能自己做一个全新的。这样做的工作量就太大了。

Powerdesigner已有的逆向工程在注释的转换上存在较大的问题:只支持有限的注释声明。比如Java5中的泛型参数的注释@param <V>就不支持,Powerdesigner会认为不存在这个参数,而忽略这个注释。

这个功能的缺失直接破坏了正向->逆向->再正向的循环--当你再正向时,原来辛辛苦苦写的注释有一部分丢失了。

Powerdesigner是个让人想爱又想恨的软件。它的缺点和优点一样突出:首先就是价格超贵,不是一般的公司能承受的,更别提个人了:( 其次它总是会在重要功能上出现几个麻烦的bug。比如12.1版本,序列图中居然无法从调用方法列表中选取方法。这个bug在12.5中已经解决。我使用的是试用版。 最后还有一个问题就是对java5的新特性的支持还不到位。泛型的注释在转换过程中会丢失。

Technorati :