工作时偶有所思,留下点感悟。
契约的重要性
软件部件之间的交互方式就是契约。契约包括传递给软件部件的参数,以及软件部件何时何种情况抛出错误。契约和现实生活中零件的规格极其类似,软件契约的无法达成,就和零件规格不一致一样,无法正常协同工作。因此,在契约的情况下,只需要考虑软件部件和其他部件之间的契约(接口),软件部件的内部实现变得不太重要。每个软件部件都有其自身严格定义的自责,系统应当能够定位这些功能和职责,从而当部件发生错误时,只需要修复该部件的错误,即可使得整个系统的错误得到修复。
因此,在设计时需要考虑契约因素。每个部件只要符合契约即可,不应该考虑其他不需要关心的因素。例如,数据库访问类正常工作的条件是数据库正常工作,在数据库访问类无法正常工作的情况下,如果数据库无法正常工作,则应当去尝试修复数据库,而不应当去要求在数据库访问类中处理这种错误。如果数据库无法工作,数据库访问类理当无法工作。这就是契约。
使用契约手段设计软件,需要有良好的错误检测手段,以便当系统发生错误时快速方便定位出具体错误位置。
契约设计的最难点在于对契约的定义。通常,如果部件与部件之间的交互仅仅是简单的几个数据类型传递则相对来说好办一些。如果部件和部件之间交互的对象是一个非常复杂的对象,而该对象内部某些方法是不稳定的,则这种情况下作为参数的对象内部发生异常错误就很难界定这种错误是那个部件导致的。因为对于复杂对象,在使用该对象之前描述该对象所期望的内部状态是困难的。例如:工作流对象内部包含太多内容,就很难一次性描述需要那些东西来避免空指针的情况。此外还有对于软件构造过程中,不同的对象,其契约要求是不一样。例如:方法的契约要求通常是参数是否设置正确,组件的契约要求则通常是其它组件内部设置符合要求。
软件必定会朝简单化、组件化、契约化方向发展。从目前的阶段来看,在软件的各种层面上都有契约的概念。早起Windows平台下开发插件、到 Java 中一系列的开发规范、到面向服务的开发结构 SOA 都是某种契约。
先设计后实现
动手做软件之前需要对软件需求进行深入了解,然后进行概要以及详细设计。切忌不作设计就立即动手搭建系统。任何随意的行为都会导致随意的系统,随意的系统往往错漏百出。因此,设计时使用契约原则,进行概要设计,详细设计。
测试驱动开发
使用测试来驱动设计是比较困难的。最难的点在于:如何设计所有的测试,测试的细致程度如何?最简单的测试是软件的大目标,即:软件能够正常运行。但对于一个巨大的软件项目,单元测试显然是一个巨大的工作量。如果考虑减少工作量,那么单元测试又很难覆盖所有的测试点。显然,这里需要寻找一个哲学的平衡点,找到那些关键的测试点进行测试,设计较好的测试。
5,197 次阅读