OO第三次总结
2018-05-30 19:50 毛钰 阅读(230) 评论(0) 收藏 举报第三单元学习总结博客
——14061095 毛钰
一、规格化设计
1.发展历史
在应用程序中,Eiffel语言首先提供了《按契约设计》的概念(也就是规格化设计的原型),它关注的是用程序规定软件模块的权利和责任,以确保程序正确性。用文档记载权利和义务的说明,用程序来校验,这就是“规格化设计”的核心。Design by Contract(DbC,契约式设计)是面向对象软件大师Bertrand Meyer对软件构造方法的一个重大贡献,无论是在形式化的数学证明中,还是在实践运用中,都被证明是大幅改善软件工程质量的有效手段。该方法在Eiffel编程语言中获得直接支持,并且可以通过辅助工具在Java语言中运用。
2.重要性
规格化设计是一种设计计算机软件的方法,这种方法要求软件设计者为软件组件定义正式的,精确的并且可验证的接口,这样,为传统的抽象数据类型又增加了先验条件、后验条件和不变式。这种方法又称为“契约式设计”,名字里用到的“规格”或者说“契约”是一种比喻,因为它和商业契约的情况有点类似,因为双双履行义务就可以双双受益。总的来说,规格化设计可以促成以下优点:
1.更优秀的设计
2.更高的可靠性
3.更出色的文档
4.方便调试
5.支持复用
3.核心要素
规格化设计的核心可以用三个关键词来概括:
前置条件(precondition):为了调用函数,必须为真的条件,在其违反时,函数决不调用,传递好数据是调用者的责任。
后置条件(postcondition):函数保证能做到的事情,函数完成时的状态,函数有这一事实表示它会结束,不会无休止的循环。
类不变项(class invariant):从调用者的角度来看,该条件总是为真,在函数的内部处理过程中,不变项可以为变,但在函数结束后,控制返回调用者时,不变项必须为真。
二、根据作业经验总结类和规格的撰写要点
1.理清每个函数的先验条件、函数属性、后验条件并依此加入规格撰写
2.在进入时假定,在退出时保持不变式,并说明副作用
3.在撰写类和方法规格时,最好的办法是先理清程序逻辑框架,撰写规格(和伪代码)来实现框架,然后在写代码来实现最终功能。这样可以免除很多的bug和期望外的问题,并且规格和代码契合度会更高。
三、这几次作业的规格和功能bug
因为这三次作业未出现任何规格互测报错,仅出现了一次功能不完整的互测报错,故不列表,下方为bug描述
第九次作业公测->随机行驶时未选择流量最小边运行
“在周围(3x3范围内)没有其他出租车的情况下,一辆空闲状态的出租车采取了掉头操作,重新走了上一步走过的边。(实际上是不应该有掉头操作的,在这种没有其他出租车干扰的情况下),走过的边流量为1,其他边流量为0(如果有其他可联通的边的话)。测试时候的出租车存在着三条联通边(包括上一步走过的边),然而产生了掉头操作。所以我认为有bug。”
该bug是算法细节问题,对寻路算法进行优化后即解决。
四、 前置条件和后置条件不好写法的改进
|
错误原因 |
改动前 |
改动后 |
|
条件不准确 |
/**@ REQUIRES: none |
/**@ REQUIRES: none |
|
前置条件忽视限定条件 |
/**@ REQUIRES: none |
/**@ REQUIRES: (/all int id, int grade; 0<= id < 80
&& grade > 0) |
|
格式不标准 |
/** @ REQUIRES: (\all int i,j; 0<= i,j < 80; map[i][j] in
{1,2,3}), |
/** @ REQUIRES: (\all int i,j; 0<= i,j < 80; map[i][j] in
{1,2,3} && |
|
线程具体表述不清晰 |
/** @ REQUIRES: (\all int root; 0<= root < 6405) @ MODIFIES: D @ EFFECTS: (\all int i,j; 0<= i,j < 80; D[(i,j)][(root/80, root%80)] is shortest route value from (i, j) to (root/80, root%80)) @ */ |
/** @ REQUIRES: (\all int root; 0<= root < 6405) @ MODIFIES: D @ EFFECTS: (\all int i,j; 0<= i,j < 80; D[(i,j)][(root/80, root%80)] is shortest route value from (i, j) to (root/80, root%80)) @ THREAD_REQUIRES: none @THREAD_EFFECTS: \locked(this.D) @ */ |
|
后置条件表述不清晰 |
/** @ REQUIRES: (\all Point x1,x2; 0<= Point.x, Point.y < 80) @MODIFIES: none @EFFECTS: this.graph[x1][x2] = 1 == \result = true && this.graph[x1][x2] != 1 == \result = flase @ THREAD_REQUIRES: none @THREAD_EFFECTS: \locked(this.graph) */ |
/** @ REQUIRES: (\all Point x1,x2; 0<= Point.x, Point.y < 80) @MODIFIES: none @EFFECTS: this.graph[x1][x2] = 1 ==> \result = true this.graph[x1][x2] != 1 --> \result = flase @ THREAD_REQUIRES: none @THREAD_EFFECTS: \locked(this.graph) */ |
浙公网安备 33010602011771号