OO最终总结

OO最终总结

自己的三次作业的架构设计

第一次作业:

如图所示,直接模仿UML的类图元素,构造MyClass, MyInterface, MyOperation三个类,分别对应UML中的类,接口和操作即可。每个Class中保存了这个UML类的关联信息,操作,接口,属性,属性可见性,父类等,每个MyInterface保存接口的继承关系。总体而言,就是复现了UML中的元素关联。

OO最终总结_第1张图片

第二次作业:

由于查询方法中不涉及类图,状态机和时序图的交互,直接分开建模,相当于在第一次作业基础上新增了两个“模块”,分别是状态机处理和时序图处理。在MyStateMachine中存储状态机的各个状态,中间的转换关系保存到状态类中。通过每一个状态,就能获取到其邻接的状态。其抽象数据结构,其实就是一张邻接表。

对于时序图,其实类似“放平”的状态图,但是由于查询比较简单,偷懒,直接以原始状态保存所有的interaction,所有的lifeline, 将message下放到所有的interaction中,不提前和lifeline对应,需要的时候现场检索。

显然,我的架构很像是“测试驱动开发但是没重构的版本”,标的是“实现所有的需求并考虑性能”,但是没有很好的对应UML图本身元素的关系。(但是第二单元赶上了OS理论课考试连着知识产权法考试...就这么简单粗暴地实现了....也许给老板的建议是不能太催项目的时间,不然....谁知道最终代码的架构长什么鬼样

OO最终总结_第2张图片

第三次作业:

第三次作业其实是在第二次作业的基础上,新增了对于UML的合法性的判断。新增类UMLchecker用于检查合法性,里面有涉及到检查合法性的顶层方法。

其中,R005-R008在实现上最简单,理解规则本身即可。如果想用比较好的架构设计,为了不破坏类的功能封装性,不用边添加边检查,而是可以最后统一检查。但是我又为了一点可怜的性能分牺牲了架构,边判断边添加。这样,添加的代码和判定合法性的代码糅合在一起,很容易泄漏或者写错(血的教训)。对于R001-R004, 算法层面不是本次博客作业的标的,依旧写写架构设计的体会吧。其实除非重构,R001-R004的设计很大程度上已经局限于了前两次作业的已有设计。刚开始时给我的突出感受是,我“被迫”选择了要访问数据保存的类(因为再高,就需要将数据传到类外破坏封装性了),例如R001中,所有的属性和AssociationEnd保存在MyClass中,因此,在MyClass中添加了检查R001的方法。再比如说,类的继承信息保存在MyClass中,接口的继承关系保存在MyInterface中,二者不匹配,而分拆R002显然是个糟糕的设计。因此,我选择了在Umlchecker中实现检查R002的方法。这样整体架构也比较好,UmlChecker不破坏前两次作业已有类的封装性,而是在Umlchecker中独立地进行这些规则检查。由此看来,之前对于R001的实现不好,将R001的实现也移动到UmlChecker中,R003-R004同理。由此,便很好地实现了功能的模块化和结构化。当然,坏处在于,UmlChecker需要不停地调用所有元素的查询方法,在此过程中有一点性能损失。不过考虑架构上带来的好处和需求上对于时间的限制,值得。

OO最终总结_第3张图片

自己在四个单元中架构设计以及OO方法理解的演进

整体来看,第一单元是客观难度上对架构设计要求最高的一个单元,也是主观能力上架构设计能力最差的一个单元。第二单元的电梯,其实在架构设计上有”水到渠成“的,很"自然"的设计感觉.有了电梯,那自然要调度器负责调度,有了调度器,加个主控,这设计就成了。而第三单元,由于JML给的设计太详细了(正如吐槽的那样,JML是把压力全都留给了架构师),设计上挑战性也不强,甚至大多数同学(也包括我)直接照着JML就写了,完全没有设计.第四单元,其实设计上很像"复现UML类图",类图中哪些属性,哪些关联在哪里,就把他存在对应的Java类中, 整体架构设计也偏向"自然设计". 如果要问为什么这么设计, 我只能说,我深刻体会到这是一门发展了这么多年, 被全球广泛使用的语言在"层次描述"上达成的最优解了.

整体而言,架构设计是我整个课程中最差的的能力。正如老师曾经说的那样,架构设计依赖经验, 需要多读书, 多自己写程序, 才能提升能力. 显然, 我的这个环节并不令人满意. 现在看看, 第一单元的难点在于, 架构设计不完全是"自然"的, 其中有构造性的设计. 架构必须同时为"算法"和"层次抽象"服务.诸如迭代化简, 递归求导等, 首先根据算法, 为大体架构设了第一道坎, 诸如" 项", "函数" 之类的东西必须抽象出来, 必须实现求导的功能, 其次, 求导后的结果, 又可能是另外一个层次的抽象. 整个架构的不同层次相互耦合在一起, 需要在我看来比较创造性的,比较好的解耦, 才能实现整体功能的良好运转. 等这个暑假(如果还有这个暑假), 打算认真看一下课程组或者同学推荐的架构设计方面的书籍, 系统提升一下自己在这方面的能力.

对于测试的理解和实践的演进

本单元中, 除了Unit4的第二次作业没有自动评测 (前面写过, 赶上考试, 那一周没有时间)外, 我都进行了相对比较充分的黑箱测试. 第一单元的对拍和数据生成相对简单, 采用Python嵌套一下, 很容易生成复杂表达式. 由于是进行通用计算, 正确性也很好验证.

第二单元, 由于"需求"是确定的, 正确性也是可检验的. 新写另外一个程序, 根据解析作业程序的输出, 判定是否实现了需求(例如,每个乘客是否正确送到了目的地, 是否是先开门再下乘客).

第三单元和第四单元的测试, 只能依赖对拍实现了. 第三单元的jml"形式化正确性检查"或者"自动生成测试数据", 目前还难以实现. 因此, 三四单元测试的我们课程中的难点, 在于如何尽可能地构造覆盖性好的测试样例. 如果是在真正的工作中, 显然, 你不可能有已有的"另一个软件"方便地对拍, 因此, 在真正的工作中, 像是三四单元这样的需求的正确性检验,其实不是很容易。

简要对本学期的测试经历进行总结:
其实测试的主要流程无外乎两个方面:

  • 生成或构造测试样例
  • 判定结果正确性

对于第一个方面,可以采用的方法很多,最常规的,从需求上入手,对需求进行分解,分门别类,构造测试数据,保证测试数据尽可能地覆盖所有的分支。同时,还要对边界数据的正确性进行检验。
对于判定结果的正确性方面,整体而言有以下几种方式:

  • 从需求出发,判断是否满足了需求。其实这种方式,应该是实际工作中软件开发中最常用的,通过人为操作等检验软件的功能是否正常运转。在我们的作业中,体现为了第二单元,通过解析输出,直接判定结果是否满足需求。
  • 直接对比输出,检验正确性。这种方式不仅仅局限于课堂上用的,但是生产中基本无法使用的和同学“暴力对拍”,还有诸如“用另一种更简单(但是可能复杂度更高)的算法实现后对比二者的结果”,用已有的某个库等价实现需求后对比结果,直接人为得到正确的结果等。被广泛使用的JUnit,其实是“人为构造了正确的输出”,然后进行对拍检验。

通过本学期的开发,我认识到,测试无论从实现的难度上还是在整体软件开发的重要性上,绝不是需求实现的“小点缀”,而是和“实现需求”各占半壁江山。本学期课程组的评分标准和测试方法,其实和现实中软件开发的流程很像。只能进行一次的强测,就像是“软件的发布”,一旦发布出去,任何一个bug都可能造成用户体验的损失,虽然可以通过bug修复解决,但是这些损失是无法挽回的,因此在此之前,你必须尽可能地测试,保证结果的正确性。

自己在课程中的收获

基本上已经写在前两点了,初步接触了面向对象的程序设计,体验了一些常见的测试方法,为“软件工程”打下了基础。除此此外,还有一些附加收获,包括:

  • 学习了java8的大部分语法和一些底层原理(人总要恰饭的嘛)。我还在研讨课专门讲了一些java8的高级特性。
  • 入门了多线程程序设计,进行了较好的并发控制。这项技能不仅在真正的工作中很重要,还和操作系统课中学到的并发程序控制方式紧密联系,二者相互促进,加深了自己的理解。
  • 了解了各种设计模式
  • 亲身体验了一下曾今在数据结构中学到的各种容器在不同需求时的性能差异,可以较好地根据需要,选择性能最优的容器。
  • git的使用,idea这个现代IDE的使用,和README的写法,正则表达式的使用等等附加buff。感觉到自己终于向成为程序猿迈向了一大步。
  • 由于在疫情期间只能和同学通过网络交流,对拍需要多人合作,实验题可以交流一下等,收获了好几位朋友

立足于自己的体会给课程提三个具体改进建议

  • (这个建议我在翻去年博客的时候就见过)尽早开放优秀代码,否则时间长了,之前自己的设计思路就基本忘掉了,就不想再倒回去重新看了。与此同时,老师/助教可以考虑写一写这么设计的“优秀”之处在哪里,以及这位同学的代码还有哪些不足的地方。有对比,才有进步。

  • 第四单元的作业和理论课的联系并不紧密。隔壁软件学院采用的方式是,考察大家设计架构/读懂架构后绘制UML图,然后由助教进行打分,我个人觉得,这才是第四单元学习UML的主要目的?如果是设计架构,还能同时考察到大家的架构设计能力,一举两得,还解决了我们的课程中只进行正确性测试,难以对“架构”进行打分评价的问题。

  • (这个建议我也在去年的博客里见过) 互测room太大,读完6,7个人的代码工作量真的太大了,最后很多测试就沦为了黑箱测试。同时,“写的程序的bug少”和“测试能力强”并不等价,根据强测结果划分房间的公平性真的有待考量。

谈一谈线上学习oo课程的体会

讲道理,这课线上学和线下学没什么区别吧,OO应该是本学期所有课中受疫情影响最小的一门课?线上学习理论课,老师还“贴心”地推出了随堂测试问卷,要是线下学,这些我没听懂的,又和作业没什么关系的知识点可能就被我放过去了。除了和同学交流/对拍的时候需要打字,不能面对面交流,不太方便了
听说研讨课本来是可以邀请业界开发人员来办讲座的,不知道今年没有实行是因为疫情的影响,还是去年的“业界开发人员讲座”口碑并不好,被暂停了。私认为这个方面大有挖掘空间。

总得来说,这学期的作业没有翻过大车(但依旧写了一个由于脑子一热写的事后看能笑死人而且由于某种复杂的原因没被我的自动评测发现的bug(这句话好长),事后发现,自己的测试逻辑和强测简直太像了,都巧妙地避开了逻辑的测试。这么明显的一个bug, 竟然只有一个点炸了,要是数据覆盖的好能直接卡0都不夸张)

最后,祝OO课程越办越好!

你可能感兴趣的:(OO最终总结)