OO第三单元“技术”博客
主要针对第三单元的三次作业
JML语言的理论基础、应用工具链情况
JML指的是Java建模语言,全称是Java modeling language,是一种行为接口规范语言,可用于指定Java模块的行为。它结合了Eiffel的契约方法设计和Larch系列接口规范语言的基于模型的规范方法,以及细化演算的一些元素
Design by Contract with JML(由Gary T. Leavens和Yoonsik Cheon撰写)的草案解释了JML作为Java合同设计(DBC)语言的最基本用法,这个草案应该就是JML的使用规范,也就是告诉我们JML应该怎么写,一些关于JML的语法
JML是一个开放项目,有许多使用了JML的开源工具,如断言检查编译器(jmlc),单元测试工具(jmlunit)等
个人认为JML在应用时有这几种情况:(1)代码(接口)实现前,先写好JML,描述好规格,这样能更加精确地描述代码所要完成的任务,实现规格化的设计
(2)代码进行完善,增加新功能时,同时对JML进行更新,这样能减少随着应用程序的进展而引入错误的机会,产生始终与应用程序代码保持同步的精确文档
(3)代码已经实现,根据代码写JML,这样能大大提高代码的可维护性,在别人接手你的项目时不会是一头雾水,知道你写的这些东西都是干什么的,并且加以应用
(参考)
部署JMLUnitNG/JMLUnit,实现自动生成测试用例, 并结合规格对生成的测试用例和数据进行简要分析
尝试学习使用jmlunit,但是没学会。
看了讨论区的帖子,写了一个很简单的Test,可以用JMLUnitNG生成这些文件:
可能自己的操作有误,许多文件都有错误,错误也没太看懂,不知道该怎么处理...
用javac编译生成文件,报了100个错误,好像是运行Test_JML_Test就会自动生成测试样例。这部分实在有点懵,在网上查了很久也没查到,好像关于JML的东西不是很多
架构设计梳理,迭代中对架构的重构分析
这次作业的架构相比之前应该是比较清晰的,因为主要的业务部分官方已经给出,而且具体要实现的类也给了,我们只需要根据JML实现接口定义的方法完成他们。不像之前从头到尾都得自己写,写着写着可能就变得一片混乱......
这三次作业是对于node,path功能的不断扩充,从最基本的容器,到一个图,一个地铁系统;从一个比较虚的东西逐渐扩展到实际生活,难度也逐渐提升,但一切还是基于这两个小东西。同时因为用到了接口,每次在写新的Myxxxx类时可以进行许多代码的复用,只要复杂度(使用的算法)没什么太大问题,应该可能大概也许不需要重构吧。如果需要重构应该也不是完全的重构。三次作业,主要有三个类,以第一次的PathContainer为基础,每次的类在此基础之上不断进行完善,他们相互独立但是又相互联系,每个类都能够相对独立地实现自己的功能。还有一个path类,主要用来管理path自己的node,也实现了各个node、path的独立。看了标程,也能看出整体的架构是基于功能进行设计的,这样才能实现各个部分功能独立,大大增加了代码的扩展性和可维护性。但不仅如此,标程对层次的划分也很细节,比如数据结构层、缓存、建模层等,我在写的时候把这些都揉在一起了,就显得有些臃肿,这确实很值得学习。“设计父类时,应该充分考虑未来的扩展性”(来自README),我这方面的意识比较垃圾薄弱,经常有一种“应该没什么能扩展的”的念头。一是因为只是为了完成作业,比较懒,二是没接触过真正的项目、工程设计,对于这种未来可能的需求没有具体的概念。这一点现在可能影响不大,但在以后实际应用时一定有很大的帮助
还有一点就是在每次写新的应用类时,可以继承上一个类并且实现新的接口,也可以不继承,只实现接口然后CtrlC + CtrlV......一开始我是直接复制的,虽说没什么限制可以根据个人喜好选择,但是这样会使一个类很臃肿,而且功能的独立性不强,可维护性比较低,没有体现出OO的特点。
第一次作业UML类图如下:
第二次作业:
第三次作业:
根据作业分析代码实现出现的bug和修复情况
这次的作业主要有两种错误:WA和TLE,好像还出现了一种MLE的错误,可能是写算法的时候内存开的太大了之类的......
首先是第一次作业,一开始写了两个版本,一个是单纯地用Arraylist实现,另一个用HashMap实现。因为之前对HashMap使用的比较少,习惯用Arraylist,怕HashMap写错,因此提交了Arraylist的版本,结果有几个点TLE了。但提交HashMap版本后依旧是TLE,最后发现是没写一种类似缓存的东西,如对于不同node总数的记录,避免每次执行命令时都要计算一遍,这样的复杂度非常大,数据量一大肯定顶不住。不过事实也是如此,自己在写代码时对复杂度的关心程度不是很高,总是想着“能实现就好,对了就行”,以后还是得注意一下复杂度这个东西,以及避免一些无用的重复操作,不然总有一天会出错
第二次作业是彻彻底底的炸了,强测15个点全是WA,然后发现是算法开始之前忘初始化了......虽然只是缺了几行代码,但导致了程序全部出错。这个问题在之前学C时也犯过,除了自己不够细心之外,也说明了自己的测试数据太弱,量不够,针对性也不够强。这种错误不容易发现,还容易蒙混过关,因为有时候可能会碰巧正确,但终究是个遗患
第三次作业一开始不太会写,只会求个连通块。最后几天在讨论区看了看同学提供的一些思路,才会写一些。这回主要是建图,图建出来的话后面的就比较简单了,我的建图只建对了一半,对于一条path中出现相同的重复的node会出错。在讨论区发现可以把每条path单独作为一个图,跑Dij,再和其他path构成一整个图,对于不同的问题,只需要修改不同的权值。(讨论区是个好东西,得多看)
对规格撰写和理解上的心得体会
通过这三次作业,还有两次实验上机,对JML有了一个初步的认识,也对所谓的规格有了比较确切的认识。
在面对比较庞大的工程时,往往都是每个人负责不同的部分,最后将这些部分整合在一起,完成整个项目。就如同这一次,我们负责完成的MyPath,MyPathContainer,Myxxxx类。这些类中的每个需要实现的方法,在接口中都有相应的JML进行规格描述,我们则根据规格中叙述的前置条件,后置条件等进行完善即可。在完善时,我可以清楚地知道,每个方法的作用是什么,可能带来的结果是什么,我只需要注意我的实现方式,以及代码逻辑的正确性。就像指导书中说的“只要代码实现严格满足JML,就能保证正确性”。JML像是一张蓝图,就像OS中的Makefile在代码实现之前,就已经布置好各部分(方法)的用途。但是也因此产生了一个问题,如果JML写的有问题怎么办。其实这个问题不是特别大,比代码写错了debug简单一些。因为我们在完善这个方法时,首先就已经大致推测出这个方法的作用了,在根据JML实现时也会带入自己的思考,思考这样写到底能不能达到目的,像这几次就有一些同学指出了官方JML可能带有的问题,并且进行了改正。如果代码已经完成,结果在某一天发现有错误,那这个错误可能就很难找出来了
同时,因为有了JML的规范限制,在想增加程序功能时也显得更容易,代码的可扩展性得到了提高。另外,从这几次作业中也感觉到,想写出一个正确的完整的JML还是非常难的,而且写起来会非常复杂,甚至比代码难。比如说起来很简单的“从A到B的最低票价,最少换乘”,JML写起来就要写好几行。但也因为有了JML,代码实现就变得简单了一些,代码和JML相辅相成
总之,规格化设计对我们今后的帮助一定会很大,在面对一定规模的设计时,一定要想起规格化这个东西,别总是按照自己想的去做(别带着一种“我这样写他能看不懂?”的心情)
OO第三单元“技术”博客的更多相关文章
- oo前三次作业博客总结
第一次作业 实现多项式的加减运算,主要问题是解决输入格式的判断问题. 输入实例: {(3,0), (2,2), (12,3)} + {(3,1), (-5,3)} – {(-199,2), (29,3 ...
- BUAA_OO第三单元总结性博客作业——JML
一.JML 在第三单元的面向对象课程中我们第一次接触了JML语言以及基于JML规范的规格化设计.在之前一系列关于面向对象思想的学习认识中,我们知道了Java是一种面向对象的语言,面向对象思想的一个重要 ...
- OO第三次总结博客
规格化设计的发展历史 (因为很难寻找,所以参考了下别的同学的调研结果) 规格化设计与结构化.模块化设计密不可分,伴随着OOP语言的发展,规格化设计思想逐渐形成体系,慢慢完善. 20世纪60年代,程序的 ...
- OO第二单元优化博客
OO第二单元优化博客 第五次作业没有性能分,但是,我在这一单元的宗旨就是写一个日常生活中 最常见的那种电梯,所以第五次我没有写傻瓜电梯,而是直接写了个\(look\),和第六次基本相同. 总计一下lo ...
- OO第一单元优化博客
OO第一单元优化博客 第一次作业: 合并同类项+提正系数项+优化系数指数0/1=满分 第二次作业: 初始想法 一开始是想以\(sin(x)\)和\(cos(x)\)的指数作为坐标,在图上画出来就可 ...
- 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: 学习 第三单元终于结束了,这是我目前为止最惨的一单元,第十次作 ...
- ******IT公司面试题汇总+优秀技术博客汇总
滴滴面试题:滴滴打车数据库如何拆分 前端时间去滴滴面试,有一道题目是这样的,滴滴每天有100万的订单,如果让你去设计数据库,你会怎么去设计? 当时我的想法是根据用户id的最后一位对某个特殊的值取%操作 ...
- 技术博客(初用markdown)。
技术博客 菜鸟教程在这个网站我学到许多有趣的东西,并且弥补了我之前的一些不足之处. 以下为我学习到的内容 输出不同的三位数 以下为代码和输出结果 *** #include<stdio.h> ...
随机推荐
- 学习进度-10 python爬虫
学习爬虫的第一个案例是小说爬虫. 小说爬虫首先是解析小说页面源代码,在页面源代码中可以看到小说每章节的内容链接 爬虫的代码: import requests import re url = 'http ...
- C语言三种整数类型
1,int 是 C 语言的基本整数类型,可以满足我们处理一般数据的需求. C 语言还提供了四个可以修饰 int 的关键字:short.long.signed,以及 unsigned. 利用这四个关键字 ...
- Windows 10工程版本泄露全新设计的操作中心圆角样式
早些时候微软错误地向Windows 10所有测试通道推送内部工程版本,该版本构建后尚未经过微软内部测试. 当然本身微软也没准备推送所以该版本里很多新功能未被关闭,而成功升级的用户则可以立即查看这些功能 ...
- python merge、join、concat用法与区别
由于合并变化较大,以后函数可能会修改,只给出一些例子作为参考 总结: merge.join 1.当没有索引时:merge.join为按照一定条件合并 2.当有索引.并按照索引合并时,得到结果为两者混 ...
- 7.8 Varnish Log
- 吴裕雄--天生自然java开发常用类库学习笔记:观察者设计模式
import java.util.* ; class House extends Observable{ // 表示房子可以被观察 private float price ;// 价钱 public ...
- JuJu团队11月30号工作汇报
JuJu团队11月30号工作汇报 JuJu Scrum 团队成员 今日工作 剩余任务 困难 于达 提供类似generator的数据产生接口 改进代码 对julia不够熟悉 婷婷 和队友一起 ...
- Python 编写代码 检查是否遵循PEP 8标准
实际上并非必须遵守PEP 8,但是它已经成为一个默认的.约定俗成的规则,可以使代码风格更统一,提高可读性. 由于最近一直在学习Ubuntu,因此此处仍然以Ubuntu为例,介绍一下规则检查工具,它能帮 ...
- 剑指offer自学系列(三)
题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变,例如{5,1,4,2 ...
- GNS3 模拟icmp端口不可达
R1 : conf t int f0/0 no shutdown ip add 192.168.1.1 255.255.255.0 no ip routing end R2 f0/0: conf t ...