Google 开源了 Contracts 元件给Java社群

Contracts是什么? 在Java中, interface是最常用的设计, 问题是, 给了interface却无法确定使用interface的程式设计师的设计品质, 这是因为interface只是定义功能与其输入与输出, 因此, 不佳的程式设计可能会被暂时隐藏, 却像个不定时炸弹, 不知在那一只不断引用的程式中出问题, 为了能够确保关键的商业逻辑不至处在此种风险之下, 就使用了abstract class来检查输入与输出, 也就牺牲了低耦合的能力了. 这个问题困扰了我很久, 以为没有特别的方法, 昨日看到了contracts的观念, 今天又看到了google释出contracts元件http://code.google.com/p/cofoja/, 发现竟然可以在interface来注记(annotation), 这是java从http://www.eiffel.com/学来的强大功能, 这个功能看起来好像很高深, 在这里分享的目的是希望初学Java的邦友可以在一开始的阶段就使用contracts, 因为这是优质程式设计的习惯.
就拿google上的範例来说明:
interface Time {
...

@Ensures({
"result >= 0",
"result <= 23"
})
int getHour();

@Requires({
"h >= 0",
"h <= 23"
})
@Ensures("getHour() == h")
void setHour(int h);

...
}

未使用contracts的可能长这样
interface Time {
...

/** 取得时间的小时
* @return 小时, 请确认取得的值是0到23的整数.
*/
int getHour();

/** 设定时间的小时
* @param h 一个0到23的正整数. 和getHour()取得的值一样.
*/
void setHour(int h);

...
}

差别在哪? 我可以用contracts透过annotation将商业逻辑加在interface中, 如果程式设计师犯了错, 就可以很精确的揪出错误在哪了. 请注意, 虽然这程式码看起来可以检查输入输出是否正确, 但是contracts不是用来检查输入输出是否正确, 而是用来检验程式设计的错误, 这是很重要的观念.

20110211T1340:
再用另一个例子:
/**
* @param left a sorted list of elements
* @param right a sorted list of elements
* @return the contents of the two lists, merged, sorted
*/
List merge(List left, List right);

以往, 在comment的地方"写得"很清楚, 但是呢, 人有惰性, 每个人的实力都不同, 传进来的和回传的都可能疏忽. 用了contracts, 改成这样:

@Requires({
"Collections.isSorted(left)",
"Collections.isSorted(right)"
})
@Ensures({
"Collections.containsSame(result, Lists.concatenate(left, right))",
"Collections.isSorted(result)"
})
List merge(List left, List right);

不仅清楚的说明了left, right和回传值的条件, 也实际以程式控制了这些条件, 看起来像是unit testing的一种功能, 但是unit testing是在测methods, 而contracts是在interface的, unit testing要对所有的implementations去测, contracts则在interface就管控了品质, 再者, contracts是透过javaagent参数调用的, 关掉javaagent就不会有任何影响.


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章