OO第四次博客作业
对比测试与正确性论证
这一阶段的两次作业分别通过编写测试代码和书写正确性论证文档检查了ALS电梯程序的正确性。
直接测试的方式曾经是过去自己检查自己代码正确性最常用的方法,因为这种方式最为简单直接,但只限于发现实际结果与预期结果不符的情况。
第13次作业所要求的测试与过去自己所做的测试有明显的差异,需要对每个方法,根据方法的规格进行测试,避免了原来测试的盲目性,并且使用junit自带的一些功能可以一次跑多组测试样例相比手动测试节省了大量的时间。
但是测试毕竟只是测试,只能证明程序有问题,而不能证明程序没问题,特别是在规格写的并怎么详细的情况下,根据规格设计的测试代码也就无法完全验证程序,即使把代码覆盖率和分支覆盖率都做到100%,也不能说明程序是完全正确的。
而写正确性论证文档可以做到几乎全覆盖,我在写正确性论证文档的过程中,经常发现自己原来规格中写的不怎么全面的地方,而且还找到了程序结构以及逻辑上的一些不合理的地方,并进行了修改,正确性论证实际上是对自己所写程序的一次解剖,可以深入程序的细节进行分析,然而代价也是巨大的。
为了这两次作业我重构了之前的ALS电梯作业,把整个程序设计得尽可能简洁,即使如此这个正确性分析文档最终写成后体量仍然十分庞大,有一万两千字三十页,写了几乎是整整两天,写完以后自己都不想看(心疼一下检查的老师)。
OCL语言调研
OCL(object constraint language)对象约束语言,一种用来进行约束定义的,形式化的无二义的语言。包含四种基本语言要素。
- 类型(基本类型,高级类型)
- 操作
- 表达式(由操作数和运算符构成)
- 语句
OCL中涉及到上下文,不变量等一系列规范,为了保证无二义性,相比我们所使用的JSF更加复杂和精细化,OCL中本身定义了基本数据类型和一些高级数据类型,还有运算符和表达式中的一些书写规范,几乎算得上是一种编程语言,这也正对应OCL的实际含义。
OCL和JSF中都有对前置条件和后置条件的说明,可以说JSF是一种极大简化以及自由化了的OCL。
第十四次作业UML图
UML类图
UML顺序图
UML状态图
总结
知识点
从第一部分的Java面向对象基础开始,到第二章的多线程,再到第三章规格化设计,再到最后一章的测试与论证,第一第二章之间还算有些联系,但是跨度极大,有些偏离面向对象的轨道,第三章开始直接跑偏,第四章在第三章基础上在顺着这条跑偏的路继续狂奔。
第一章是课程的基础部分,让我们对Java语言和面向对象有了初步的认识。紧接着从第二章开始就踏入了一个未知领域,多线程编程,这与我们过去所编写的程序大不相同,在学习了多线程编程之后,许多过去用单线程无法解决的问题迎刃而解。第三章开始谈设计,但是说实话我并不知道这些所谓的设计原则以及烦人的JSF在我们的作业中能有什么体现,更多的感觉是在没事找事。第四章在第三章的基础上根据规格进行测试以及论证,从这算是看到了一些设计原则以及jsf的用处。
回头来看,OO课程的知识体量十分庞大。
进步总结
程序结构和质量上的进步是明显的,过去我写的代码一直十分臃肿,前几次作业的代码中也有体现,虽然功能正确,但是结构上十分混乱,属于典型的想一步写一步,然后回过头来修修补补,最后的程序可读性极差。
随着程序体量不断增大,原来的编写方式难以适应,在ALS电梯作业中体现尤为明显,那次作业的代码继承自上一次作业本来就很臃肿,再加上编写过程中考虑不周,完成后bug不断,再加上代码结构混乱debug十分困难,仿佛是在补丁上打补丁。从第二章开始转变了模式,先设计再编写。先打一个基本框架或是流程,然后根据这个框架进行细节扩充,不仅缩短了编写代码的时间,也减少了bug的数量,同时debug的过程也相比原来更加简单,代码的质量有了明显的提升,但是多线程本身的不确定性也带来了许多问题,如何发现bug成了关键。
谈到设计,上面所说的设计与第三章讲的设计模式没有任何关系,在我看来第三章的内容十分鸡肋,浪费时间浪费精力,根据代码写jsf已经丧失了jsf本来用途,使用jsf描述设计规格远不如流程图结构图的宏观把控,也不能像代码一样准确描述,由于是根据代码写的jsf,转化过程中可能存在问题,代码正确jsf出错的情况层出不穷,再加上jsf可读性极差,我真的是宁愿读代码也不想去看jsf。
至于测试和论证总算是给鸡肋的jsf一点用武之地,junit测试工具可以说是开启了一片新天地,过去的测试过程基本上都是自己构造测试用例然后是轰动测试,偶尔有精力用python写个脚本自动生成一些测试数据来测试,不过这些方法还是比较原始。我深入探究了junit的各种使用方法,收益颇丰。
在互评阶段,阅读别的同学的代码,对自己阅读代码的能力也是一种锻炼,同时也可以发现其他同学在程序设计过程中的优缺点,从而可以在自己今后的程序设计中注意这些问题。
工程化开发
实不相瞒,我对工程化开发没多少理解,仅靠这种一周一次还不停改需求的赶工作业,就算有前期准备也不超过一天,根本不可能有太全局的设计,也不可能完全像课上所讲的设计原则那样实现,这样做只会给自己添麻烦。
一般情况下周六发布作业,白天刚OS,先把OO放一边,周六晚上分析指导书进行初步设计,并解决指导书中的一(da)些(liang)问题,周日早上进一步构思,进一步分(tu)析(cao)指导书,开始搭框架写readme,周日下午和晚上基本可以完成一大半,周一晚上再修个仙基本可以把代码写完,周二周三构造数据debug,顺便再 改 改 需 求,这基本上就是我的开发流程。
期望和建议
在前几次博客作业中相关的吐槽已经写了太多了,在此做个总结。
- 知识面的问题。OO课程涉及的知识面极广,体量完全可以分为两门(甚至三门)3学分的课程,并且课时极少,一周只有两小时,上课基本上只是描绘了一个轮廓(大概占实际知识量的10%~20%),大部分需要课下自学(这也是很多同学觉得OO课上没啥营养的原因)。
- 作业量问题。这与上面的问题十分矛盾,由于大量的知识需要课下自学,这本身需要大量时间,然而巨大的作业量很大程度上影响了同学们自学的热情,被作业压得喘不过气还有什么心思去自学,这也导致了学到的知识非常肤浅,得到的提升也很有限,更具体的描述在我的第三次博客作业中,在此不再赘述。
- 难度问题。这个问题是由上述两个问题所共同导致的,在多线程电梯以及IFTTT两次作业中表现尤为明显,当然早就学习过多线程的大佬们可以忽略此问题。多线程电梯给我印象颇深,那一周正值清明假期,我硬是在宿舍守了两天,学习多线程的相关知识,然后才开始编写代码。不过回头来看这两天真的非常值,认真阅读了《Java并发编程实践》中的三个章节,对其他章节的部分重要内容做了简单浏览,这让我很快适应了多线程编程,并且对可能遇到的各种问题有个基本认识,在编写过程中就会绕开这些可能的问题,所以在后来的多次作业中基本没有碰到由多线程的并发性造成的bug。然而这是由于那次作业正值清明节,有这个时间让我自学,这在其他周是根本不存在的,而且清明节部分同学想出去放松放松,并没有学习相关知识,导致了接下来的两次作业雪崩,这并不能怪同学们,这是课程设计上的问题,假如多线程的第一次作业不是在假期间布置,问题可能比现在还严重得多。
- 需求问题。这个我已经无力吐槽,是由于指导书和同学共同造成的。改需求对于先写完的同学的影响极大(我这种每次周一甚至周一之前就先写完的真的是每次看到改需求都忍不住想骂人),对于后写完的同学倒是没多少影响,而且后写的同学经常会提出一些十分细节的问题,正顺应了教程组希望找机会改需求的心理。从而导致最后同学们都变聪明了,一开始都不写,都拖到最后几天突击,从而减少改需求的几率,同时也让先写的同学去踩踩雷,找个安全区出来。感觉这门课就是在变相鼓励拖延症。经过长期磨炼,总结出来一个真理,指导书说不清楚的最好就别问,readme就好了,皆大欢喜,实在说不清也早点问,不要等到每次星期二了才临时抱佛脚,但是理想和现实总是差距很大,总会有人在ddl之前一两天还去问,然后就成了强制要求。如果下一届还是这个机制,在此提醒阅读到此文的学弟学妹们不要重蹈覆辙。
- JSF问题。继续沿用我上次博客的说法,用一个词形容JSF,绝对是“鸡肋”,第三部分所学的JSF并没有起到什么实际作用,只是浪费时间浪费精力顺便再引起JSF撕逼大战,直到第四部分开始做测试和论证JSF才体现出了一点用途,更具体的JSF相关吐槽和建议见我的第三次博客作业。
- 互测问题。这估计是大部分同学最关心的问题了。我总结出来一点,敌意和流行病一样,是会传染的。前5次作业还好,我一直处于0分附近,基本不扣分也不被扣分,十分和平。从IFTTT之后开始第一个撕逼风暴出现了,但其影响力还比较有限,由于我的段位都比较佛系,并没有被此次风暴影响,但是这次风暴已经席卷了一部分同学,大量扣分的苗头已经起来了,从JSF加入后变得一发不可收拾,连我所在的那个佛系段位都不太平了,最后三次作业发展到什么情况大家自己都心知肚明。还好已经临近尾声,影响有限,如果后面还有几次作业,不知道撕逼大战会发展到什么程度。这个问题是互测机制的先天性问题,很多同学也在客服群里发表过自己的意见,但是并没有什么万全的方法,目前我也没有想到什么有效的解决方法。
不管怎么说,OO课程总算是结束了,度周如年的日子已经过去了,只是希望学院改变折磨下一代的想法(这种心理是极其变态的,只会导致恶性循环),不知为何这种思想还能拿出来大摇大摆的宣传(难不成是为了掩饰课程设计上的漏洞?)。虽然没有报名助教团队,但还是希望能够针对以上问题对课程进行改良甚至大换血,放过下一代。
最后再次感谢在这一学期一起探讨OO相关问题,分享测试数据设计思路的各位大佬们。