一、测试与正确性论证的区别

  从哲学的角度来说,正确性论证与测试的关系就像理论与实践的关系一样。

  使用测试的方法检验程序正确性确实是一个非常方便可行且广泛运用的方法。可以通过几个简单或复杂的测试样例,迅速地校验程序主要逻辑是否正确,运行结果是否符合预期。但是对于较为复杂的问题来说,测试样例很可能并不能覆盖所有的情况,因此我们曾经引入代码覆盖率和分支覆盖率的概念。但是在操作过程中我发现,即使某个不完全的测试样例代码覆盖率达到100%,分支覆盖率高于95%,它仍然并不一定完全检验程序的逻辑是否正确,即使结果符合预期。因此我们很难通过测试样例说明程序一定正确,即使我们使用了脚本生成等自动化测试方法,仍然不能全面地测试程序的逻辑是否完全正确。因此测试这样的方法有着其便捷性,也有着其局限性。

  正确性论证是一个全新的思路,我们把程序的逻辑构造成分支的形式,通过规格总结出在各个分支下程序的预期表现来从宏观的逻辑层面上论证程序是否正确,不去关心程序运行过程中如何实现,只需要满足规格提到的前置条件和后置条件即可认为程序正确。但是对于复杂问题,构建出程序的逻辑分支便已经十分吃力,程序的复杂逻辑很可能在分析的过程中遗漏一些错误,因此这并不是一个万全的方法。

  我们在实践中,应该结合二者进行测试,虽然耗费时间,但是在对程序认知较为深刻的情况下,自然更容易思考到比较偏僻和少见的逻辑问题。

二、OCL语言

OCL语言是对象约束语言,与JSF相似,同样拥有着前置条件和后置条件,但是没有JSF中的Modified属性,有类似的不变式。还有叫做监护规则的约束,即在对象能够从一种状态转变为另一种状态前其值必须为真的约束。

OCL语言和JSF一样,都只关心方法或对象在运行前后的属性状态,不关心具体的实现过程。

三、第十四次作业总结

  以上是第十四次作业的UML类图。

  以上是第十四次作业的时序图。

四、学期总结

  本学期我们首先学习了面向对象语言的初级应用,完成了一个看起来很不面向对象的Java程序——多项式计算,这个程序由于功能简单,导致其类的功能过于集中,Main类用于录入信息,ComputePoly类用来计算多项式加减,确实是难以感受到Java面向对象程序与传统面向过程程序的区别(除了程序中多了几个class关键字)。当然现在看来,这个程序还可以写得更面向对象一点,更完美一点。但是对于一个什么都不懂的初学者来说,用这个作业入门且由于设计需求中对输入的严格要求,大家往往会把注意力集中在java的基本语法学习和正则表达式在Java中的运用之中,反而忽略了面向对象程序的关键。愚以为,这个作业可以进行一些改进以更加地偏向面向对象教学,不过考虑到由于需要公测进行测试,且规范输入格式对之后电梯程序的铺垫作用,设计出这样的作业已经是非常合理了,且暂时也难以想到兼顾二者的作业设计,毕竟对于当时的我来说,面向对象还是一个非常抽象笼统的概念,是需要一个学期的学习才能正确认知的。

  随后我们完成了两次单线程电梯,第一个是傻瓜式电梯,之后我们运用了学到的类的继承,将其升级为有一点点智能的可捎带电梯。到这里,我们已经可以管中窥豹地初步认识到Java面向对象中一大特性之继承的作用以及好处,同时对单线程编程也是较为熟练。

  之后我们便愉快地进入了Java多线程的世界,我们首先再次升级了之前的稍微智能一点的小垃圾电梯,将其改造为非常小可爱的三部电梯同时工作,并且直接进入了多线程阶段,可以真实地模拟时间,简直是太酷了!

  这三次作业让我们发现,在功能升级的时候,总是有一些其他无关类(如Floor类)的代码由于一些不可言状的原因必须进行修改,这是怎么回事!明明很厉害的面向对象怎么会有这种情况出现!难道是我做错了什么!原来随着需求的修改,程序的逻辑有了很大的变化,之前在楼层类中使用了一些属性来记录相应的请求,而在多线程电梯里又用不到了,导致这部分逻辑在方法中冗余,才需要大量的修改甚至是重构。此时我们发现了,类的抽象化做的非常的不好!楼层就是楼层嘛,楼层有楼层的功能,为什么还要用来记录请求信息呢(其实是因为要打印输出),记录请求信息意味着类之间的耦合性变高了,这也就是我们必须要修改除去scheduler类之外的其他代码的原因。

  当这一作业告一段落,我们完成了一个用作过渡的,用来帮助我们学习多线程的线程安全和同步控制的作业——文件系统。在这次作业中,我们学习了诸多线程安全的手段(有且不仅有sleep(200L), sleep(500L)和sleep(1000L)),极大地提升了自己在线程同步控制上的造诣。

  在之后的Taxi作业,我们早早就听说了本次作业将有多次升级,因此我在实现时很认真地思考自己的程序,如何让自己的程序变成高内聚低耦合的神奇存在。又在线程控制上有了很深的认知,使这次作业的线程同步的矛盾从设计层面上被尽量避免。同时又完成了需求提到的并不丰富的功能,其中最困难的部分可能是重新写一个好用的最短路径搜索以替代原本GUI中提供的特别占内存且特别慢的方法吧。

  之后不论是为道路添加流量还是添加红绿灯还是设置VIP出租车,都极大地体现了一个良好的程序构思是多么的有意义,添加流量时由于要修改map类的逻辑,包括最短路搜索,导致需要写不少代码,之后的红绿灯几乎只修改了两三个方法,修改了十几到几十行代码就解决了这个问题。而可追踪出租车更是完美的体现了面向对象程序中继承的优点,程序的其他部分对可追踪和普通出租车的处理完全没有区别,却可以很好地完成功能需求。再加上某个选修课学到的c++面向对象的相关知识,到这,我觉得面向对象程序中继承的运用以及好处已经被我掌握个大概了。

  从Taxi第二次作业开始,我们引入了全新的程序设计理念——规格,这个东西可以很好地统一程序员之间的交流语言,也可以为自己的程序设计提升便利。这一部分与我们之后的几次作业有着极大的关联。

  之后的几次代码量非常小的作业中,我们先后接触了JUnit单元测试、程序正确性论证等概念,这两个概念令我对之前蠢笨的测试方法感到十分羞愧,想起当时百度的时候也曾经看到JUnit的使用方法但由于懒惰并没有深入学习,导致刚开始在对程序测试时,几乎都在使用复制粘贴按回车大法。但是代码量小并不代表作业更轻松,虽然当时的我在身体及意识上对它们都有些不重视,但是在实践过程中,发现当初写的程序简直是太难以接受了,将这样的程序整理出合适的规格实在是过于繁琐。因此,迫不得已地修改了一小部分代码使程序变得好看一点。又由于在第二次电梯作业中对其非常的上心,记得当时很多的逻辑结构,因此很容易就构造出了符合条件的测试集。虽然由于逻辑的复杂,在正确性论证的过程中碰了钉子,但总体来说还算比较顺利。

  从我个人的角度来看,这一路走来,我的工程化能力有着比较大的提升和进步,对面向对象的学习也是非常认真。因此非常感谢OO课程组为我们精心设计的关卡,非常感谢助教在这一过程中对我们的帮助。就我个人来说,相信如果没有OO的闯关机制来辅助我的学习,单纯通过上OO理论课,然后随便布置一些作业的话,我很难对OO这门课的认识有如今的程度。

OO第四阶段总结的更多相关文章

  1. OO第四单元总结及课程总结

    OO第四单元总结及课程总结 一.前言 紧张刺激的OO“昆仑课程”接近尾声,经过一个学期的学习,我的收获和感触颇多,借此博客作业的机会,对自己OO这门课程做一个总结.本博客主要有以下五个方面,一是第UM ...

  2. OO第四单元及学期总结

    OO第四单元及学期总结 第四单元两次作业的架构设计 第一次作业 类图: 树形结构:使用Operation类管理UMLOperation以及parent为该UMLOperation的参数(UMLpara ...

  3. Bete冲刺第四阶段

    Bete冲刺第四阶段 今日工作: web: 昨晚搞得很晚,帮队友搞定了git的问题,仓库顿时干净多了,同时已经基本完成了基础功能的接口 ios: 导入并使用了改善交互的第三方开源库,修正路径BUG 目 ...

  4. OO第四次博客作业!

    oo第四次博客作业 一.测试与正确性论证比较 测试只是单方面片面的证明对于当前的输入程序是正确的,测试只能证明程序有错误,不能说明程序是对的. 正确性论证是程序达到预期目的的一般性陈述,是通过规范化的 ...

  5. OO第四次课程总结分析

    OO第四次课程总结分析 测试与正确性论证的效果差异及优缺点 测试,即使用测试样例来验证我们的程序是否能完成相应功能的过程.测试数据的产生基于前置条件和后置条件,通过执行测试数据检查方法输出是否满足需求 ...

  6. 【OO学习】OO第四单元作业总结及OO课程总结

    [OO学习]OO第四单元作业总结及OO课程总结 第四单元作业架构设计 第十三次作业 第十四次作业 总结 这两次作业架构思路上是一样的. 通过将需要使用的UmlElement,封装成Element的子类 ...

  7. OO第四单元(UML)单元总结

    OO第四单元(UML)单元总结 这是OO课程的第四个单元,也是最后一个单元.这个单元只有两次作业,相比前三个单元少一次作业.而且从内容上讲这个单元的作业目的以了解UML为主,所以相对前三个单元比较简单 ...

  8. OO第四单元博客作业

    OO第四单元博客作业 BUAA_1706_HugeGun 目录 第四单元作业架构设计 四个单元架构设计及OO方法理解 四个单元测试理解与实践演进 课程收获 一点建议 第四单元作业架构设计 ### 第十 ...

  9. OO第四单元总结及学期总结

    目录 OO第四单元总结及学期总结 第四单元三次作业架构设计 第十三次作业 第十四次作业 第十五次作业 四个单元中架构设计及OO方法理解的演进 第一单元 第二单元 第三单元 第四单元 四个单元中测试理解 ...

随机推荐

  1. caffe 安装记录

    为了使用caffe,特地装了linux系统,版本:Ubuntu14.04 X64 可参照 http://www.cnblogs.com/platero/p/3993877.html 这个博客写的更好h ...

  2. 在线调整InnoDB Buffer Pool Size

    InnoDB Buffer Pool主要是用来缓存数据表和索引数据的内存区域,它的默认值为134217728字节(128MB).最大值取决于CPU架构;32位系统上的最大值为4294967295(23 ...

  3. linux学习第十九天(iscsi配置)

    一.iSCSI 服务部署网络存储 服务器配置 添加硬盘,创建分区 l[root@localhost Desktop]# ls /dev/sd*  (系统下查看硬盘信息) /dev/sda  /dev/ ...

  4. Kotlin安卓页面本地存储数据(方法和封装)

    直接上代码 封装: //存储key对应的数据 fun saveData(context: Activity, key: String, info: String) { val sharedPrefer ...

  5. 异步fifo with 读控制

    之前做LDPC编码器时,学习了一下异步FIFO的相关知识,主要参考了http://www.cnblogs.com/aslmer/p/6114216.html,并在此基础上根据项目需求,添加了一个读控制 ...

  6. C++ 信号处理

    原文:https://www.w3cschool.cn/cpp/cpp-signal-handling.html C++ 信号处理 信号是由操作系统传给进程的中断,会提早终止一个程序.在 UNIX.L ...

  7. django学习笔记(2)

    Part 2: The admin site ====> Creating an admin user$ python manage.py createsuperuser   Username: ...

  8. HDU - 3874 Necklace (树状数组、离线处理)

    题目链接:Necklace 题意: 给出一串珠子,每个珠子有它的value,现在给出n(n<=5e4)个珠子的value(1<=value<=1e6),现在给出m(1<=m&l ...

  9. kali更新后窗口不能适应屏幕的解决方案

    终端执行 systemctl restart open-vm-tools 当然,也可以加入到启动项来实现自启动

  10. 内置函数——eval、exec、compile

    内置函数——eval.exec.compile eval() 将字符串类型的代码执行并返回结果 print(eval('1+2+3+4')) exec()将自字符串类型的代码执行 print(exec ...