规格化设计——OO第三单元总结
规格化设计——OO第三单元总结
一、JML语言理论基础、应用工具链
1.1 JML语言
JML(java modeling language)是一种描述代码行为的语言,包括前置条件、副作用等等。JML是一种行为接口规格语言 (Behavior Interface Specification Language,BISL),基于Larch方法构建。
通过使用JML,我们可以忽略一个类、一个方法内部的具体实现,专注于描述方法的预期功能,从而把过程性的思考延迟到方法设计中,扩展了面向对象设计的原则。
1.2 应用工具链
OpenJML:根据JML语言描述对模块的功能实现进行验证,逻辑证明其正确性。
JMLUnitNG:基于JML规格的自动化单元测试工具。
二、部署JMLUnitNG
public class Sub {
/*@ public normal_behaviour
@ requires a > 0 && b > 0;
@ ensures \result == a - b;
@*/
public static int sub(int a, int b) {
return a - b;
}
public static void main(String[] args) {
sub(1, 1);
}
}
在修改代码规格描述,使用OpenJML检验无误后可以生成和编译测试代码:
java -jar ../openjml/openjml.jar -check Sub.java > re.txt
java -jar jmlunitng-1_4.jar Sub.java
javac -cp jmlunitng-1_4.jar *.java
java -jar ../openjml/openjml.jar -rac Sub.java
java -cp jmlunitng-1_4.jar sub_JML_Test
之后即可测试代码,部分结果如下:
[TestNG] Running:
Command line suite
Running:
Command line suite
Passed: racEnabled()
Passed: constructor sub()
Failed: static sub(-5464846548, -5464698148)
Passed: static sub(0, -9632483648)
Passed: static sub(2269875647, -2112489738)
Passed: static sub(-5963483648, 0)
Passed: static sub(0, 0)
Passed: static sub(5967483647, 0)
Passed: static sub(0, 2687483647)
Passed: static main(null)
Passed: static main({})
===============================================
Command line suite
Total tests run: 10, Failures: 1, Skips: 0
===============================================
三、作业架构分析
3.1 容器
第一次作业,只需要实现path和pathcontainer两个类。为了减少方法的时间复杂度,我选择了特定的数据结构,同时尽量把出现频率高的方法(查询)复杂度分担到出现较少的方法(增删)中:我实现了path的hashcode方法并使用了两个hashmap存储path和对应的id,保证查询path的复杂度接近o(n)。同时使用一个hashmap存储每个节点及其出现次数,计算node_count时直接返回size,复杂度小。Path中则采用ArrayList存储路径上的全部点。
3.2 扩展-图
第二次作业需要在PathContainer的基础上增加连通性判断、最短路径等图相关的方法,等同于要求扩展图的数据结构。
我使用了嵌套hashmap存储(节点-(相连的节点-连接次数))来记录图,每次增删路径时修改图。使用floyd算法求解两点最短路径:邻接矩阵original记录点之间的连接关系,每次增删时对应修改original并将新的original复制到二维矩阵routes,在routes中应用弗洛伊德算法可得到点与点之间的最短路径,最短路径不为MAX(代表点之间不连通)即是连通的,可求最短路径。
此外,为了将编号各异的点使用邻接矩阵管理起来,利用“同一时刻不超过250个点”这条数据限制,我将点的编号映射到0-249,代表在矩阵中的偏移。我使用了一个hashmap记录映射关系,使用了一个空闲点的堆栈来记录哪些点仍然可以提供映射。。
3.3 扩展-地铁换乘
由于低估了第三次作业的难度,这次作业的完成情况较为粗糙,设计和编码非常仓促:采用了同学之间普遍认同的算法计算最少换乘次数和最少票价;为了减少出错的可能,把上次作业中与图相关的部分全部封装到了一个类里。综上所述,并无多少自己深入的思考和独特的设计。
第三次作业的要求是扩展求联通块数量的功能和最小带权路径的功能(权值需要自己定义并计算)。
求联通块数量可以利用第二次作业中的图结构,采用单元点出发bfs搜索遍历所有到达点+依次将所有未标记节点作为起点的方式实现。
为了实现计算最少换乘、最小不满意度和最小票价,需要定义新的权。在设置好权值后,应用第二次作业的floyd算法即可,所以本次作业的关键是扩展新的数据结构存储权值。
求最少换乘时,应当把一条path上任意两点之间的边权值设为1;求最小票价时,应该把权值设置为两点之间的最短路径+2;求最小不满意度时则应该把权值设为最小不满意度+32。三种求解最后要相应地减去1, 2, 32以算出正确答案。归纳出三种方法的共性之后可以进行封装归类。
考虑到删除路径时对地铁结构影响较大,每次增删线路时,我都会重新扫描所有path建立新的邻接矩阵存储权值。
在扫描一条path计算权值时,我用到了spfa算法计算最短带权路径。
四、作业中的bug
第二次作业中修改邻接矩阵中自环的时机不对:自环应该在点被去除时消失,而不是在边被去除时消失。
第三次作业中,由于在上次作业中映射path中节点时没有判断该节点是否在图中存在,这个问题严重影响了第三次作业的评测:在强测中大量被包含“不存在于图中的节点”的样例攻击,出现大量nullpointer exception。归根结底,是在封装图的时候把规格和自认为冗余的代码删去了,导致出现了大量异常。(以惨痛的教训学习到规格和考虑重构后果的重要性)
五、单元心得体会
本单元的学习是一个较为完整的体会规格化设计和设计迭代的过程,虽说到了最后一次作业几乎已经无暇顾及阅读繁复的规格,但还是更深入地体会了继承的思想,学到了很多规格化设计的相关思想。
规格化设计一方面可以延迟过程性的思考,专注于描述算法的抽象实现和功能,从而方便了程序设计人员;另一方面,可以做到设计与实现分离,从而被广泛应用于对安全追求较高的大型软件开发中,在保证程序逻辑正确性的前提下分而治之,让不同的人根据规格编写不同的代码,并可以很方便地验证代码的正确性(JML工具链)。
规格化设计——OO第三单元总结的更多相关文章
- OO第三单元——JML规格化设计
OO第三单元--JML规格化设计 JML语言的理论基础以及应用工具链情况 理论基础 JML是对JAVA程序进行规格化设计的一种表示语言,是一种行为接口规格语言.JML整合了Java和JAVAdoc,并 ...
- 【OO学习】OO第三单元作业总结
[OO学习]OO第三单元作业总结 第三单元,我们学习了JML语言,用来进行形式化设计.本单元包括三次作业,通过给定的JML来实行了一个对路径的管理系统,最后完成了一个地铁系统,来管理不同的线路,求得关 ...
- OO第三单元(地铁,JML)单元总结
OO第三单元(地铁,JML)单元总结 这是我们OO课程的第二个单元,这个单元的主要目的是让我们熟悉并了解JML来是我们具有规格化编程架构的思想.这个单元的主题一开始并不明了,从第一次作业的路径到第二次 ...
- OO第三单元——基于JML的社交网络总结
OO第三单元--基于JML的社交网络总结 一.JML知识梳理 1)JML的语言基础以及基本语法 JML是用于java程序进行规格化设计的一种表示语言,是一种行为接口规格语言.其为严格的程序设计提供了一 ...
- 2020 OO 第三单元总结 JML语言
title: 2020 OO 第三单元总结 date: 2020-05-21 10:10:06 tags: OO categories: 学习 第三单元终于结束了,这是我目前为止最惨的一单元,第十次作 ...
- 2020北航OO第三单元总结
2020北航OO第三单元总结 本单元要求是根据JML规格完善代码,初看是一个简单的代码照搬实现的东西,但最后才发现由于CPU时间的限制,还考察了大量优化策略及数据结构中关于图的知识,是一次非常注重细节 ...
- OO第三单元作业(JML)总结
OO第三单元作业(JML)总结 目录 OO第三单元作业(JML)总结 JML语言知识梳理 使用jml的目的 jml注释结构 jml表达式 方法规格 类型规格 SMT Solver 部署JMLUnitN ...
- OO第三单元
OO第三单元 JML语言理论基础,应用工具链 JML语言基础 JML简介 定义: JML 是一种形式化的. 面向 JAVA 的行为接口规格语言 作用: 开展规格化设计.这样交给代码实现人员的将不是可能 ...
- OO第三单元作业总结
OO第三单元作业总结--JML 第三单元的主题是JML规格的学习,其中的三次作业也是围绕JML规格的实现所展开的(虽然感觉作业中最难的还是如何正确适用数据结构以及如何正确地对于时间复杂度进行优化). ...
随机推荐
- 年轻人的第一个 Spring Boot 应用,太爽了!
Spring Boot 大家都知道是啥吧? 还有不知道的来看这篇扫下盲:告诉你,Spring Boot 真是个牛逼货!. 顺便再往下看,栈长给你带来年轻人的第一个 Spring Boot 应用,撸码史 ...
- idea在docker环境,调试spring boot程序
允许docker被远程访问 见:https://www.cnblogs.com/wintersoft/p/10921396.html 教程见:https://spring.io/guides/gs/s ...
- java单元测试之如何实现异步接口的测试案例
测试是软件发布的重要环节,单元测试在实际开发中是一种常用的测试方法,java单元测试主要用junit,最新是junit5,本人开发一般用junit4.因为单元测试能够在软件模块组合之前尽快发现问题,所 ...
- bean名称相同冲突Annotation-specified bean name 'xx' for bean class [xxx] conflicts with existing, non-compatible bean definition of same name and class[xxx]
工程中引入其他工程的包,由于两个工程中有重名的两个bean,导致在启动时提示如下错误: 根据bean名称在ide中查找,找到这两个重名的类,可以看到由于这两个类使用@Service标注,此时如果不使用 ...
- RFC2119 规范内容
RFC2119 https://www.ietf.org/rfc/rfc2119.txt Network Working Group S. Bradner Request for Comments: ...
- Spring cloud微服务安全实战-7-1章节概述
前面的章节都是围绕这微服务的安全在讲一些东西,包括微服务本身api的安全.网关的安全.怎么去做安全中心,包括认证服务器,权限的服务.权限的设计,怎么来实现SSO.然后sentinel来实现统一的熔断, ...
- Base64(2)
import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncoding ...
- Windows10下安装Git
Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理.具体安装步骤如下: 第一步:先从官网下载最新版本的Git 官网地址:https://git-scm.com/do ...
- Swift编码总结8
1.判断当前控制器是否在显示: // 判断当前控制器是否在显示 func isCurrentViewControllerVisible() -> Bool { return (self.isVi ...
- flex布局大全 2019
有句话叫做:存在即是合理. 最近很喜欢flex布局模式,不过还在摸索中,这里正一边在项目中使用和总结,也在学习一些大牛们总结的东西和布局思考. 鉴于自己很苦恼,到处去ha资料,真的,就没有一个系统的, ...