栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【软件构造课程笔记】第五章

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【软件构造课程笔记】第五章

系列文章目录

第五章:设计规约


文章目录
  • 系列文章目录
  • 一、编程语言中的函数与方法
    • 1.方法
  • 二、 规约:程序的交流
    • 1. 程序文档(举例)
    • 2. 规约
    • 3. 行为等价性
    • 4. 规约的结构:前置条件和后置条件
  • 三、 设计规约
    • 1. 规约的分类
      • (1). 规约的强弱
      • (2). 规约的确定与不确定
      • (3). 规约的操作式与声明式
    • 2.图形化规约
    • 3.设计一个好的规约
      • (1). 内聚性coherent
      • (2). 返回值应该信息丰富
      • (3). spec应该足够强
      • (4). spec应该足够弱
      • (5). 应该使用抽象类型
      • (6). 前置和后置条件


一、编程语言中的函数与方法 1.方法

方法是程序的积木,可以被独立开发,测试,复用,使用方法的客户端,无需了解方法内部具体是如何工作的–“抽象”

下图给出一个方法的例子,我们可以看到,可以分为方法的规约与方法的实现体两个部分。

二、 规约:程序的交流 1. 程序文档(举例)


在上面我们给出了java API documentation
其中包含了许多信息:

  1. 类的继承关系class hierarchy 与实现的接口 interfaces
  2. 直接的子类direct subclasses,对于接口interface来说,是interface的实现类。
  3. 类的描述
  4. 构造器摘要
  5. 我们可以调用的所有方法列表
  6. 对于构造器和方法的细节描述
    (1). 方法的返回类型,名称,参数,已经抛出异常
    (2). 整体的描述
    (3).对参数的描述
    (4). 对返回值的描述
2. 规约

规约其实描述了程序与客户端之间达成的协议。 在调用的过程中,双方都要遵守。

规约的好处:
方便开发者消除误解,理解代码与定位错误。

  1. 精确的规约可以有助于区分责任
  2. 客户无需阅读调用函数的代码,即其中的具体实现,只需要了解规约,知道如何使用即可
  3. 规约可以隔离变化:当修改程序后无需通知客户端,客户还可按照之前的方式继续调用
  4. 防火墙:防止恶意篡改程序
  5. 解耦:无需了解具体的实现
3. 行为等价性

4. 规约的结构:前置条件和后置条件

前置条件(requires):对客户端的约束,在使用方法的时必须满足的条件。
后置条件(effects):对开发者的约束,方法结束时必须满足的条件。
契约:当前置条件满足,后置条件必须被满足。
对于java来说:

  1. 静态类型的声明是一种规约,可以根据此进行静态类型的检查。
  2. 方法前的注释也是一种规约,但是需要我们人工去判断是否满足。
    (1). 对于前置条件可以用@param来进行描述
    (2). 对于后置条件可以用@return @throws来进行描述
    例如:

需要强调的是在规约中只可以提及参数与返回值,而不可以去透露任何本地变量与私有属性的信息。否则就会出现内存泄漏的情况。

三、 设计规约 1. 规约的分类 (1). 规约的强弱

规约的强度S2>=S1:
S2的前置条件更弱,后置条件更强
可以用S2代替S1

而在下面的这几种情况中,它们的强弱无法比较。


(2). 规约的确定与不确定

确定的规约指:给定一个满足precondition的输入,他的输出是惟一的,明确的。
不确定的规约指:同一输入可以用多个输出

(3). 规约的操作式与声明式

操作式规约:伪代码,给出方法的具体实现流程。
声明式规约:没有内部实现的描述,只有始末状态。

一般情况下不应该使用操作式的规约,操作式的规约是为了解释maintainer的实现。

2.图形化规约


如上图所示:
每一个在上图中的点都代表着一个方法是实现。
程序员可以在规约的范围内自由选择实现的方式。
客户端无需了解具体使用了哪一个实现。
更强的规约,表达着更小的区域。

结合在上一讲中对规约强弱的区分:

3.设计一个好的规约 (1). 内聚性coherent

spec描述的功能应该单一,简单,容易理解。

(2). 返回值应该信息丰富

不能让客户端产生歧义。

(3). spec应该足够强

太弱的规约,客户不够放心。

(4). spec应该足够弱

太强的spec,在很多特殊情况下无法实现,给开发者增加了难度。

(5). 应该使用抽象类型

在规约中使用抽象类型,可以给方法的实现体和客户端更大的自由。
在java中,使用抽象类型指的是使用interface类型。

(6). 前置和后置条件

在正式执行前,要检查前置条件是否被满足。
不写前置条件,就要在代码内部实现check;
如果实现代价太大,在规约中加入前置条件,把责任交给客户端。

归纳:
是否使用前置条件取决于:

  1. check 的代价
  2. 方法的使用范围:
    如果只在类的内部使用该方法(private),那么可以不设置前置条件,在使用该方法的各个位置进行check。
    如果在其他地方使用该方法(public),那么必须设置前置条件,若客户端不满足则抛出异常。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/924579.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号