契约式设计6大原则的理解

在《Design by Contract原则与实践》中,作者定义了契约式设计的6大原则:

  1. 区分命令和查询;
  2. 将基本查询和派生查询区分开;
  3. 针对每个派生查询,设定一个后验条件,使用一个或多个基本查询的结果来定义它;
  4. 对于每个命令都撰写一个后验条件,规定每个基本查询的值;
  5. 对于每个查询和命令,采用一个合适的先验条件;
  6. 撰写不变式来定义对象的恒定特性。

前面5个针对operation层面而言,不论是面向对象也好,面向过程也好,函数式也好,都可以适用。最后1个针对data层面而言,特别适用于面向对象等有着数据的组合的模式。细分下去,前面2点是对于operation对对象状态的改变的分别,而3、4两点是后验条件的原则,第5点是先验条件的原则。

1、区分命令和查询

  根据operation是否改变对象的状态,将operation分为命令和查询两类,这个应该直接在命名上就体现出来,比如查询应该使用getXXX等,一眼看到就知道这个是查询,不改变对象状态,那个是命令,会改变对象状态。这个分类除了让我们能一眼就看出operation的特点之外,还是整个DbC在Operation组合的正则性的基础。如果划分错误,则可能破坏Operation组合的正则性(比如将一个命令操作当成查询操作来处理)。

2、将基本查询和派生查询区分开

  对查询进行细分,有的查询可以有其它查询组合,有些是不能由其它查询组合而得的,前者为派生查询,后者为基本查询。

  对于基本查询,它是不需要后验条件的,是默认 assert(postcondition) == true的,因为它是原始的,primitive查询,而派生查询是由基本查询组合而成,这中间涉及到了作者的逻辑,需要一个后验条件,以确保这个逻辑是正确的。

  因为基本查询是确定满足后验条件的,所以,如果除了基本查询之外的所有其他operation的后验条件最终都由基本查询构成,那么久保证这些operation的后验条件的正确性和正当性。引申出来就是原则3和原则4:

  PostCondition(PrimitiveQuery) =

    ^ Assert(postcondition) == true

  PostCondition(ComposedQuery)= PrimitiveQuery{1..n}

  PostCondition(Command)=PrimitiveQuery{1..n}

  这就保证了所有operation的后验条件均是正当的正确的。

3、对于每个查询和命令,采用一个合适的先验条件

  每个真理都是在一定的前提之下才成立的。如果某个查询操作不需要先验条件,那么它的先验条件就是any precondition.

  这和前面所说的后验条件结合在一起,保证了Operation的组合的正则性。这里也强调了合适

4、撰写不变式来定义对象的恒定特性

  对象的某些属性自始至终都是需要满足某些条件的。仔细地区分地话,我们应该更加关注那些在command operation里面会改变的属性,确保这些属性一直满足这些条件,从而保证data满足不变式的要求和恒定特性。就C++而言,这点是需要特别留意的,一般建议在子类里面不要直接操作父类成员变量,否则对于保证对象成员变量的恒定特性是很麻烦的,在C++里面还有友元函数,友元类等,建议尽量不要在友元函数、友元类里面修改类成员变量值。对于成员变量的修改建议抽取出一个方法供调用,这样子,对于保证data的恒定特性非常有必要。

最新文章

  1. awk命令速查
  2. css旋转
  3. 大漠绑定测试工具-VB6
  4. [ionic开源项目教程] - 第15讲 ionic用户个人中心登录注册的实现
  5. BZOJ_1497_[NOI2006]_最大获利_(最大流+最大权闭合图)
  6. Swift - 内存泄露原因(循环强引用)及解决办法
  7. mysql行列转换方法总结
  8. webstorm方向键与电脑快捷键冲突
  9. Sql知识点总结
  10. Explanation About Initilizing A DirextX3D Class 关于初始化Direct3D类的解释
  11. Redis自学笔记:5.实践
  12. esLint 配置
  13. Codeforces Round #446 Div. 1
  14. OPENSSL编程 第二十章 椭圆曲线
  15. 如何确定系统上的CPU插槽数量
  16. 病毒木马查杀实战第020篇:Ring3层主动防御之基本原理
  17. LeetCode 167. 两数之和 II - 输入有序数组
  18. virtualbox+vagrant学习-2(command cli)-21-vagrant up命令
  19. ELK收集openstack日志
  20. AOV网与拓扑排序

热门文章

  1. 操作系统学习笔记:I/O输入系统
  2. myecplise、ecplise项目空间优化
  3. JavaScript对象(复习笔记)
  4. Java类加载机制?
  5. RK平台LCD调试说明【转】
  6. 苹果Instruments/Shark性能调试工具概述
  7. Ruby: Call the system and get system information.
  8. request的Content-Type小结
  9. Java-Runoob-高级教程-实例-字符串:10. Java 实例 - 测试两个字符串区域是否相等-uncheck
  10. log4j的1.2.15版本,在pom.xml中的顶层project报错错误: Failure to transfer javax.jms:jms:jar:1.1 from https://maven-repository.dev.java.net/nonav/repository......