契约式设计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的恒定特性非常有必要。

契约式设计(DbC)感想(二)的更多相关文章

  1. 契约式设计(DbC)感想(一)

    契约式设计可以理解为正则编程的一种实践: 如果用我的三脚猫能力将这种实践方法形式化的话,大致如下(如有不正确处,请不吝指正): 1.对于方法Method的precondition & post ...

  2. 重构25-Introduce Design By Contract checks(契约式设计)

    契约式设计(DBC,Design By Contract)定义了方法应该包含输入和输出验证.因此,可以确保所有的工作都是基于可用的数据,并且所有的行为都是可预料的.否则,将返回异常或错误并在方法中进行 ...

  3. JML契约式设计——第三单元学习小结

    一.前言 本单元作业都是关于JML(Java Modeling Language),JML是一种契约式设计(Design by Contract)的语言,契约式设计的主要目的是希望程序员能够在设计程序 ...

  4. 契约式设计 契约式编程 Design by contract

    Design by contract - Wikipedia https://en.wikipedia.org/wiki/Design_by_contract What is the use of & ...

  5. PHP 面向对象编程和设计模式 (1/5) - 抽象类、对象接口、instanceof 和契约式编程

    PHP高级程序设计 学习笔记 2014.06.09 什么是面向对象编程 面向对象编程(Object Oriented Programming,OOP)是一种计算机编程架构.OOP 的一条基本原则是计算 ...

  6. groovy动态类型--能力式设计

    动态类型 动态类型中的类型是在运行时推断的,方法及其参数也是在运行时检查的. 能力式设计 被称作鸭子模式:他有这么一个观点:如果它走路像鸭子,叫起来也像鸭子,那么他就是一只鸭子. 契约式设计 相当于J ...

  7. ASP.NET Web API标准的“管道式”设计

    ASP.NET Web API的核心框架是一个消息处理管道,这个管道是一组HttpMessageHandler的有序组合.这是一个双工管道,请求消息从一端流入并依次经过所有HttpMessageHan ...

  8. paip.自适应网页设计 跟 响应式 设计方法与工具补充(2)o54

    paip.自适应网页设计 跟 响应式 设计方法与工具补充(2)o54 #-----响应式 设计框架 Bootstrap比较热门. Foundation 号称是世界上最先进的响应式前端框架. #---绝 ...

  9. web设计经验<一> 提升移动设备响应式设计的8个建议

    今天看到一些关于web设计的一些建议和设计经验,拿出来分享分享. 第一篇: 提升移动设备响应式设计的8个建议 一.直观性和易用性 在使用移动设备时,对于杂乱.复杂或者不直观的设计造成的混乱不佳的用户体 ...

随机推荐

  1. SSH无密码验证可能出现的问题

    雪影工作室版权所有,转载请注明[http://blog.csdn.net/lina791211] 一.安装和启动SSH协议 假设没有安装ssh和rsync,可以通过下面命令进行安装. sudo apt ...

  2. 什么是cookie?session和cookie的区别?

    1.cookie数据存放在客户的浏览器上,session数据放在服务器上. 2.cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗   考虑到安全应当使用session ...

  3. mysql17---增量备份

    mysql增量备份: 全备份是: (增量备份一定要看日志的时间和位置节点) mysql数据库会以二进制的形式,把用户对mysql数据库的操作记录到文件中,不用使用定时器了.当用户希望恢复的时候,可以使 ...

  4. 文件上传Apache

    Map<String, Object> rtnMap = new HashMap<String, Object>(); // 获取文件 String tempPath = re ...

  5. jfreechart应用2--柱状图(作者:百度 被风吹过的日子)

    jfreechart应用2--柱状图 二.   柱状图 在WebRoot目录下建立bar目录,用来存放柱状图的各个例子.首先在该目录下建立一个sample1.jsp文件,让我们来看一个简单的柱状图的例 ...

  6. OSD锁定怎么解锁?

    方法是这样的: 先按中间的建关掉显示器电源,关了显示器后按住左键,在按中间的建开机,这时屏幕闪一下就解锁了.在按中间的建打开显示器就行了. 加锁的方法和解锁一样

  7. Python之Split函数

    python中的split()函数用来拆分一个字符串,通过指定的分隔符对字符串进行切割,返回切割后的字符串列表list. split()函数用法: str.split(str=' ',num = st ...

  8. AppDomain加载与释放dll

    AppDomain加载与释放dll 几年前写过同名随笔,但今天应不大适用了.但还有几个朋友留言关注,我重新发布相关代码. 首先我们的目的就是运行期间更新dll,并应用dll.这个过程需要应用 AppD ...

  9. Tensorflow卷积接口总结

    tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None) 这个接口用了这么久,每次都有点迷惑,这里 ...

  10. bzoj4720

    期望dp n久以前做过,再做一遍 你只能决定决策,不能决定结果,这是这道题的关键,因为我们换了教室不一定成功,所以我们应该这样设dp状态,dp[i][j][k],第i天,换j次,换没换,转移: dp[ ...