【MIT软件构造】Designing Specifications

规约的评判维度

确定性(deterministic):对于确定的输入,规约规定的输出的确定性
声明性(declarative):不说明具体实现步骤,只是单纯地说明程序表现
功能性(strong):能用更宽松的先决条件实现更满意的结果

确定性(deterministic)VS不确定性(undeterministic)

考虑下列两个spec的区别


static int findExactlyOne(int[] arr, int val)
requires:	val occurs exactly once in arr
effects:	returns index i such that arr[i] = val

static int findOneOrMore,AnyIndex(int[] arr, int val)
requires:	val occurs in arr
effects:	returns index i such that arr[i] = val

可以看到上面的规约确定性比下面的强,且上面的规约具有确定性,下面的具有不确定性。我们推崇更确定的规约。

声明性(declarative)VS操作性(operational)

声明性:给出此程序的先决条件与结果说明,但不涉及具体实现
操作性:给出此程序实现的步骤与细节

下图规约是操作性的,因为它说明了方法是如何实现的:

static String join(String delimiter, String[] elements)
effects:	append together the strings in elements, but at each step,
 			if there are more elements left, insert delimiter

可以将上述spec改为声明性的:

effects: 	returns concatenation of elements in order, with delimiter 	
			inserted between each pair of adjacent elements

我们推崇声明性的规约。

功能强(Strong)VS功能弱(Weak)

当SP1的先决条件相等或弱于SP2,而SP1的结果说明强于或相等于SP2,则SP1强于SP2,同时SP1的实现方法会没有SP2多。
可以看到下列规约功能性强度从上到下递增:

//	原版
static int findExactlyOne(int[] a, int val)
requires:	val occurs exactly once in a
effects:	returns index i such that a[i] = val
// 先决条件变弱,结果说明不变
static int findOneOrMore,AnyIndex(int[] a, int val)
requires:	val occurs at least once in a
effects:	returns index i such that a[i] = val
//	先决条件不变,结果说明变强
static int findOneOrMore,FirstIndex(int[] a, int val)
requires:	val occurs at least once in a
effects:	returns lowest index i such that a[i] = va

可以用图形化的规约描述,其中每个点代表规约的一种实现方式,规约面积越大,实现方式越多。故功能性越强的规约图形面积越小。
在这里插入图片描述

一些忠告

  1. 尽量独立功能:
static int sumFind(int[] a, int[] b, int val)
effects:	returns the sum of all indices in arrays a and b at which 		
			val appears

上述规约实现了查找和求和两个功能,将其分开为两个方法会提高可读性。

  1. 能区分不同情况:
static V put(Map<K,V> map, K key, V val)
requires:	val may be null, and map may contain null values
effects:	inserts (key, val) into the mapping, overriding any existing 	
			mapping for key, and returns old value for key, unless none, 
			in which case it returns null

上述规约方法返回null时并不能区分元素本身就是null还是并没有找到元素。

  1. 功能性尽量强

尽量减少用户的烦恼,尽量提高方法的价值

  1. 在某些时候,功能性应尽量弱
static File open(String filename)
effects:	opens a file named filename

上述规约太强,程序员将耗费大量精力。因为读文件有很多意外情况,程序员需要一一考虑,此时不如降低功能性。

  1. 应抽象一点
static ArrayList<T> reverse(ArrayList<T> list)
effects:	returns a new list which is the reversal of list,
			i.e. newList[i] = list[n-i-1] for all 0 ≤ i < n, where n = list.size()

上述规约限定类型为ArrayList,改为List会更好。

发布了6 篇原创文章 · 获赞 0 · 访问量 329
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 游动-白 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览