在我职业之初,我想得最多的是:当调用一个方法时,传入的参数,我是进入该方法前检查呢?还是进入到该方法后检查?特别是在某个方法中,为了保证该方法能顺利执行,之前的条件检查、if…else…简直是噩梦。所以我会想:至于吗?有必要这样做吗?哇,这个问题让我纠结了好长时间。其实,问题本身并不难,只是需要抽象出一个理念,或是原则,然后一直这样做。后来,我为自己定个原则:在进入方法前,进行严格检查;而进入到方法后,只进行简单检查。也就是说,如果符合方法的需求,就执行,否则什么都不做,直接返回。之后,无意间看到“契约式设计”才意识到,我这样做原来有理论基础的,只是之前不知道而已。

因此,当我们不断前进时,的确需要时不时地看些理论,这样就会加深我们对问题的理解。

本文内容 概述

历史

描述

与软件测试的关系

概述

契约式设计/契约式编码(Design by Contract(DbC)/Programming by Contract,以下简称 DbC )是一种设计计算机软件的方法。这种方法描述了,软件设计者应该为软件组件定义正式的、准确的、可验证的接口规范,它扩展了抽象数据类型(abstract data type,ADT)对于先验条件(preconditions)、后验条件(postcondition)和不变性(invariants)的一般定义。这些规范称为“契约(contracts)”,它是一个比喻,类似于商业契约/合同的条件和职责。

(注:软件组件的概念比较广泛,不要想得过于狭隘)

因为,契约式设计(DbC)是美国的 Eiffel Software 的注册商标,所以,很多开发人员用 "Programming by Contract","Contract Programming" 或 "Contract-First development"来代替这个词。

历史

The term was coined by Bertrand Meyer in connection with his design of the Eiffel programming language and first described in various articles starting in 1986 and the two successive editions (1988, 1997) of his book Object-Oriented Software Construction. Eiffel Software applied for trademark registration for Design by Contract in December 2003, and it was granted in December 2004. The current owner of this trademark is Eiffel Software.

Design by Contract has its roots in work on formal verification, formal specification and Hoare logic. The original contributions include: A clear metaphor to guide the design process

The application to inheritance, in particular a formalism for redefinition and dynamic binding

The application to exception handling

The connection with automatic software documentation

描述

DbC 的核心思想,用一个比喻就是:基于相互的“义务”与“权利”,一个软件系统的要素之间如何互相合作。这个比喻来自于商业活动,“客户”与“供应商”达成的“合约”而来。例如: 供应商必须提供某种产品(这是供应商的义务),并且有权期望客户付费(这是供应商的权利)。

客户必须支付费用(这是客户的义务),并且有权得到产品(这是客户的权利)。

双方必须满足应用于合约的某些义务,如法律和规定。

同样地,如果在面向对象程序设计中的一个类的例程(方法)提供某些功能,那么,它要: 期望所有调用它的客户模块都保证某个进入的条件:这就是例程(方法)的先验条件—客户的义务和供应商的权利(方法本身),这样,它就不用去处理不满足先验条件的情况。

保证退出时给出某个属性:这就是例程(方法)的后验条件——供应商的义务,也是客户的权利(调用方法的主要权利

进入时假设,退出时保证,维护某个属性:类的不变性。

契约(contract )就是这种义务和权利的形式化。可以用“三个问题”来概括 DbC,这也是软件设计者必须反复问的: 期望什么?

保证什么?

维护什么?

很多语言都使用这样的断言。然而,DbC 认为契约对于软件的正确性至关重要,它们应当是设计过程的一部分。实际上,DbC  提倡首先写断言。

契约的概念可以扩展到方法/过程。每个方法的契约通常包含如下信息 可接受和不可接受的输入的值或类型,以及它们的含义

返回的值或类型,以及它们的含义

错误和异常的值或类型,以及它们的含义

副作用

先验条件

后验条件

不变性

(不太常见)性能保证,例如所需的时间和空间

在继承结构中,允许派生类弱化先验条件(但不能加强),加强后验条件和不变性(但不能弱化)。这些规则很接进 Liskov 替换原则(behavioral subtyping 一种特殊形式)。

所有类的关系在“客户”类与“供应商”之间。在不违反“供应商”结果状态的情况下,一个“客户”类可以调用“供应商”的特性(功能)。接下来,“供应商”也有义务在不违反“客户”状态需求的情况下向“客户”提供一个返回状态和数据。例如,一个“供应商”的数据缓冲区要求,当调用删除功能时,缓冲区中要有数据;然后,“供应商”向“客户”保证,当调用删除功能,数据项必须从缓冲区中删除。其他的设计契约是“类不变性(Class Invariant)”。“不变性”保证(对本地类),在执行完每个功能后,类的状态被保持在一个规定范围内。

当使用契约时,“供应商”不用去验证是否满足契约条件。通常的看法是用安全网的契约校验,直接让代码“严重失败”。DbC 的 "严重失败" 的性质把调试的契约行为简化为清晰地规定每个过程的意图。这与防御性编程有明显的区别。在防御性编程中,当先验条件被破坏时,供应商去负责如何解决。更多的情况是,在 DbC 和防御性编程中,“供应商”抛出一个异常通知“客户”先验条件被破坏,客户必须解决如何响应这个信息。DbC 使得“供应商”的工作更简单了。

(注:比如,项目中,当我们认为某段代码可能会出错时,会加入 try{}catch{}finally{},或是只要不符合先验条件,就让程序直接返回 null。)

DbC 也定义了一个软件模块的正确性标准: 当“客户”调用“供应商”之前,如果类不变性(class invariant )和先验条件为真,那么服务完成后,类不变性和后验条件也为真。

当“客户”调用“供应商”时,软件模块不应该违反“供应商”的先验条件。

因为,在程序运行期间,不能违反契约的条件,所以,它们作为调试代码保留,或者出于性能原因,在产品版本中移除。

DbC 也可以用于代码重用,因为每段代码的契约都被完全地文档化。对于这个模块的行为,一个模块的契约可以被看作软件文档的一种形式。

与软件测试的关系

单元测试隔离地测试一个模块,来检查,如果它的子契约符合,那么它是否符合它的契约。集成测试检查各个模块是否可以很好的协同工作。

java契约式编程_契约式设计 Design by contract相关推荐

  1. 华山论剑之契约式编程与防御式编程

    背景 事情的来由还要从几十几亿年前的一次星球大爆炸说起,sorry,背错台词了,是从几天前讨论接口返回数据和几个月前讨论课件本地数据结构说起,简单的说,就是碰到约定好的内容出现异常,是我们在程序中内部 ...

  2. 契约式编程与防御式编程

    背景 事情的来由还要从几十几亿年前的一次星球大爆炸说起,sorry,背错台词了,是从几天前讨论接口返回数据和几个月前讨论课件本地数据结构说起,简单的说,就是碰到约定好的内容出现异常,是我们在程序中内部 ...

  3. java链式编程_Java 链式编程 和 lombok 实现链式编程

    一.链式编程定义 链式编程的原理就是返回一个this对象,就是返回本身,达到链式效果. 二.jdk中 StringBuffer 源码 我们经常用的 StringBuffer 就是 实现了链式的写法. ...

  4. Java Review - 并发编程_读写锁ReentrantReadWriteLock的原理源码剖析

    文章目录 ReentrantLock VS ReentrantReadWriteLock 类图结构 非公平的读写锁实现 写锁的获取与释放 void lock() void lockInterrupti ...

  5. Java Review - 并发编程_原子操作类LongAdder LongAccumulator剖析

    文章目录 概述 小Demo 源码分析 重要的方法 long sum() reset sumThenReset longValue() add(long x) longAccumulate(long x ...

  6. Java Review - 并发编程_ 回环屏障CyclicBarrier原理源码剖析

    文章目录 Pre 小Demo 类图结构 CyclicBarrier核心方法源码解读 int await() int await(long timeout, TimeUnit unit) int dow ...

  7. java契约式编程_第三单元总结——JML契约式编程

    OO第三单元博客作业--JML与契约式编程 OO第三单元的三次作业都是在课程组的JML规格下完成.完成作业的过程是契约式编程的过程:设计者完成规格设计,实现者按照规格具体实现.作业正确性的检查同样围绕 ...

  8. java契约式编程,关于契约式类论文范例,与基于契约式设计的VeriJava编程语言设计相关毕业论文开题报告...

    本论文为关于契约式类论文怎么写,关于基于契约式设计的VeriJava编程语言设计相关毕业论文开题报告,可用于契约式论文写作研究的大学硕士与本科毕业论文开题报告范文和优秀学术职称论文参考文献资料下载.免 ...

  9. java链式编程_Java链式编程学习

    Java链式编程 在使用jquery时肯定对它的链式编程惊艳到,慢慢的其它语言这种编程模式也逐渐增多.其本身并不复杂,在调用方法时,方法最后返回对象本身,以达到链式编程的效果. 链式编程比较简单,只要 ...

最新文章

  1. R使用LSTM模型构建深度学习文本分类模型(Quora Insincere Questions Classification)
  2. UVa1316 Supermarket(贪心)
  3. WeightedRandomSampler 理解了吧
  4. 怎么把rmd改成html,在Rmd中的htmlTable - 转换为Word docx
  5. Web前端优化需要注意的点
  6. LeetCode(9) - Palindrome Number
  7. Hadoop之Shuffle机制详解
  8. codeforces B. Fox and Cross 解题报告
  9. 上架APPStore需要准备哪些材料?
  10. 全国80几所重点大学ftp资源库(经常逛逛可能有惊喜哦)很难收集的,知道其他的友友可以留言完善...
  11. input的type属性的修改
  12. muduo for v210
  13. php中重写和final关键字的使用
  14. 20175221 2018-2019-2 《Java程序设计》第一周学习总结
  15. iis出现HTTP 错误 403.14 - Forbidden Web问题
  16. android:EditText属性/去边框
  17. umiJs_React学习笔记
  18. azure微软文字转语音工具​AzureTools​使用
  19. matlab读取数据流,【OpenBCI】(1):Matlab实时读取数据流(labstreaminglayer)
  20. 常用的ODI映射与过滤命令

热门文章

  1. 电力系统潮流计算程序实现C语言版(动态节点+稀疏技术)
  2. Web3创业具备创新爆炸式增长的所有要素
  3. PowerApps共享应用(初次尝试)
  4. 一、Mavlink协议
  5. 单网卡同时上内外网的路由设置
  6. 好久没有写博客了。。。说说最近的感悟即学到的东西。。。
  7. 回转半径的计算公式_一种计算船舶回转半径的方法
  8. wavelet introduction
  9. 产品经理必备的五款办公软件
  10. 不到 20 人的互联网公司,该去吗?