Shao Fan

关于JAVA与软件工程
posts - 31, comments - 71, trackbacks - 0, articles - 4
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理
   Design by Contract (DbC)的概念已经出现很长时间了,最先是在Eiffel的一个特色,通过DbC来提高软件质量,目前很多语言也都有相应的实现,但是在GOOGLE上搜索中文网页,得到的资源并不是很多.直觉上来说,DbC确实是一个很好的想法,本着拓宽眼界的原则,就简单了解一下吧.
 
    简单的说,DbC通过指定每个方法的前置条件,后置条件来保证代码质量.也就是说,它的假设前提是:"任何一个方法,给予其满足条件的输入,应当得到一定的输出".对于一个方法来说,如果"参数"可看作其输入,返回值可看作输出.那么调用这个方法的人有责任保证给予正确的参数,而当正确的参数给予后,该方法本身有责任给出正确的输出.如果出现错误,那么是调用者的问题,还是被调用者的问题,可以根据前面所说的方法来确认.
 
    在实际使用中,DbC可以用来更方便的找出错误,确定责任.
 
    拿DbC的一个实现, iContract作例子.比如说,有一方法 foo(int a, int b).它要求输入的a,b都要大于零.如果提供的参数满足这个条件,那么它应保证输出大于0.用iContract来表示,是这样的:
 
1 /**
2 *@pre a>0
3 
*@pre b>0
4 *@post @return
>0
5 */

6 int foo( int a, int b ){
7       //其他代码

8 }
 
    另一个方法调用foo:

1 public void run(){
2       int result = foo( 0-1 ); //注意-1不满足条件@pre b>0

3 }
 
 
    没有DbC的情况下,-1的输入可能导致foo内部产生异常,比如说NullPointerException之类的.当我们看到这样的异常时,一般来说无法确定是foo方法本身的bug还是其他原因造成的,可能需要跟踪进去看看才知道.
 
    如果我们用DbC,将这段代码用一个iContract编译工具(这里也就是iContract)编译后(ant提供支持),可以像一般的程序一样执行.当运行到run方法中时,由于调用时给予的参数不满足前置条件,也会产生一个运行时异常,但是区别是,异常产生于方法刚被调用前,因此阻止了错误的继续,并指明了错误是"调用程序run违反了add方法的前置条件",对程序员来说更加直观.显然用这种方式,确定责任更加迅速明确.使用DbC的原因就是,责任明晰,到底是给予的参数有问题,还是程序本身有问题,更容易查找了.契约式设计的精神就体现在于此.
 
    DbC在java上的实现中,iContract比较有名,但是其开发公司似乎人间蒸发了?ant从1.4后也提供对它的支持,但似乎很难找到它的下载,更不用说后续开发和支持了.javaworld上有对其介绍的文章.如果你想了解DbC,这篇文章也是很好的入门材料.
 
   

    不过后来在wikipedia上找到了DbC的另一种实现:JML,全称Java Modeling Language,名字挺吓人的样子.主要由一些大学联合开发,很热闹,资源也相当丰富.其主页是这里.JML不只实现了DbC,还有其他的一些东西,还没仔细看.这篇pdf是一个很好的介绍JML的材料.
 
    此外还有一些书,都可以在Google上找到.总体来说,DbC的学习语法相对简单,学习成本还是比较低的.有兴趣的话不妨一式.

评论

# re: 被遗忘的一种提高软件质量的方法 -- 契约式设计 (Design by Contract)  回复  更多评论   

2006-03-02 09:37 by GHawk
可能现在大规模采用DbC还有些问题:
1. 设计的代价过高。对于很多设计师来说要设计出DbC的OO系统,需要很多的学习和经验。验证设计出来的契约也相对比较复杂。
2. 执行的开销过大,毕竟,在运行时每验证一个Contract就要多消耗一些机器资源。(但是我认为使用DbC所带来的可靠性比起这些开销是值得的。)
3. 缺少语言层次的直接支持。Java的assert关键字还只是个语法糖而已。不过随着AOP的普及,相信在这方面很快会有突破的。

# re: 被遗忘的一种提高软件质量的方法 -- 契约式设计 (Design by Contract)  回复  更多评论   

2006-03-02 09:48 by shaofan2
谢谢,您所知道的有没有哪些项目采用DbC?

# re: 被遗忘的一种提高软件质量的方法 -- 契约式设计 (Design by Contract)  回复  更多评论   

2006-03-02 14:37 by GHawk
这就不太清楚了,这方面的资料和宣传确实很少。
在www.eiffel.com上有一些客户应用Eiffel的成功案例。可以参考一下。

# re: 被遗忘的一种提高软件质量的方法 -- 契约式设计 (Design by Contract)  回复  更多评论   

2006-09-13 06:47 by sp1234
如果把DBC仅仅当作一种优化方法入口参数异常检测代码的方法,我看应该“被遗忘”。因为我可以写异常,然后在调试时“检查调用语句”,这是“很平常”的调试手段,DBC的声明方式与自己写异常没有什么区别,区别似乎仅仅是对异常的时候显示的源代码位置不同而已。

我认为DBC就是这样被淡忘了——没有人对后置条件重视,这说明了没有人重视设计方面的声明手段。

只有注册用户登录后才能发表评论。


网站导航: