OO第四单元作业总结
第四单元作业架构梳理
第一次作业的时候一下子拿到官方包的一堆代码比较茫然,所以在设计的之后更偏向于完成任务而没有太重视设计是否符合oo的要求。总体上的思路有点像装饰者模式,因为官方包中每个UmlElement
储存的信息用于查询需要反复沿着储存的树形结构遍历,效率十分低下,所以就想把每个元素相关的信息用My + xxx
的自定义class储存起来,这样查询起来相对方便一些。
这次作业的主要问题还是MyUmlInteraction
实在太过复杂了,代码已经接近500行,几乎储存了大部分的程序逻辑,显然不符合oo的原则。但是因为读官方代码和理解题目花费的时间太多,最后已经来不及进一步优化了,所以这个任务就留到了下一次作业。
发现三种UML图的查询功能是彼此独立的之后,在第二次作业中为了更清楚地管理类图、顺序图和状态图,我引入了ClassModelManager
、CollaborationManager
、StateMachineManager
分别对他们进行管理。
同时吸取了第一次作业的教训,我把所有不需要Manager储存的全局信息的查询方法都一层层封装了起来,交给对应的class和interface自行完成查询,并把结果返回给Manager。这样设计之后每个类的职责就显得清晰很多,编程也因此变得方便了不少。
(比较可惜的是因为错误理解了指导书的意思,忽视了可能有信息来自不在manager中管理的lifeline导致wa了一个点)
架构设计总结与OO方法理解的演进
回顾一个学期的学习,感觉对于oo方法的理解还是有了很大的进步。
- 第一单元
在完成第一个单元作业时我对于面向对象的思想基本上完全没有理解,加上对于java也不是特别熟悉,所以作业完成的时候更多的是希望保证作业的正确性,而没有怎么考虑架构是不是oo。那个时候对于oo的认识基本就是把一些有关的数据和方法封装起来构成一个class,然后如果class之间存在某种共性和相同方法的话,就采用继承和接口的方式提取出来。
现在想来其实第一单元作业怎么能写得更oo其实是很值得研究的一件事。但是就个人而言,我觉得第一单元的作业是对java编程要求最高的一个单元(主要是正则表达式也很难掌握),真的需要花费很多时间才能保证程序的正确性。(第一单元也是我出bug最多的一个单元)实力的不足导致没能够进一步体会oo的思想有点可惜。
- 第二单元
第二单元因为题目的原因,我的架构设计有了明显的改善。电梯问题的结构相对清晰,我在第一次作业的时候就确定了输入-调度器-电梯的三级结构,并且严格控制每个类只处理自己的工作:输入只读取用户请求并给调度器;调度器只负责按照一定的策略把请求分配给电梯;电梯只负责根据请求队列运行。这样的设计延续了三次作业,基本上做到了只在原有作业基础上增加内容以实现新功能,算是一定程度体现了oo的思想。不过这样也导致了潜在的问题,因为调度器并不能知道电梯的确切状态(电梯的信息被封装在电梯内部了),所以不能实现特别复杂和高效地分配策略。就我个人对于oo的理解来说,如果调度器不断请求电梯的信息,调度器和电梯的耦合就太强了,破坏了两个类各司其职的特性,所以为了保证类的独立性我还是选择了这样效率稍微差一些的结构。
- 第三单元
第三单元可能是架构设计最失败的一个单元了。因为jml给的规格很清楚,所以设计的时候除去性能考虑加入的一些储存中间数据的结构,我基本就沿用了jml设计的架构。虽然写作业的时候其实也考虑过,是不是可以采用一些自己的class重新组织数据,但是我感觉都是用点、边的方式储存图,我没想到可能会让查询更便捷的结构。如果让我自己设计class储存的信息和jml规格要求的基本也一样,所以干脆就放弃了做重复工作。
现在想来也挺可惜,感觉如果老师能讲一下用什么样一个不一样的结构可以实现更高效的存储就好了,自己真的想不出来。
- 第四单元
上面也总结过了。就像焦宇才同学在研究课时候分享的,oo其实就是数据和方法的封装,只不过哪些数据和方法封装在一起很有讲究。我觉得这个单元的第二次作业中我做得比之前要好不少,做到了任务一层层分派下去,每个class只处理自己的数据,尽量减少类之间的耦合。
测试理解与实践的演进
oo刚开始的时候因为之前习惯了由课程组提供测评,所以我对于中测很弱、主要要靠自己做测试的安排十分不理解。不过经历了一个学期的学习,我终于意识到了自己原来的认识有多么幼稚。在现实工作中编程的时候怎么可能会有人给我现成的测评机呢?完成领导布置的任务,必然需要交上去一个自己完备测试之后的程序才行。
但虽然理解了测评的重要性,测评本身也不是一件容易的事情,工作量甚至可能比编程本身还要大。
尤其是想要完成自动化评测,相当于需要同时完成随机数据生成程序+正确结果生成程序+结果对比评判程序+自动运行脚本。可能在助教大大们看来这并不是很复杂的工作,但是也许是因为我的编程能力太过薄弱,编写第一单元的自动评测机时,查资料、编写、评测机debug确实要花费我几天时间才能完成。后面对于脚本和python和python熟悉了一些之后会稍微快一些,但如果其他课程的任务比较重的话(比如os实验debug不出来)就没有时间搭建自动评测机了。即使搭建了自动化评测机,因为生成数据的随机性,实际找bug的效果还不如用我一拍脑袋想出来的易错数据效果好。这难免让人感到有些沮丧。
最终课程结束的时候,我只有4次作业中搭建了自己的全自动化评测机,分别是第一单元的第二次作业和第二单元的三次作业。第三单元主要依靠junit测试特殊数据+借用室友写的对拍程序,第四单元主要靠自己画出包含了所有特殊情况的uml图测试。
从强测结果来看,虽然没有出现大翻车(低于75分),但是满分的数量也并不多。出现bug的原因可以分为三种情况:
- 自我测试不够充分
例如第一单元第三次作业写完基本就到截至时间了,测试时间不够;第一单元第二次作业和第二单元的作业虽然有自动化测试,但是出错数据太过特殊没有跑出来。
- 测试出了问题但是不知道怎么改进
这个专指第三单元的第三次作业,因为给hashmap设置了一个比较大初始化值导致时间爆炸tle了。虽然对拍的时候就已经发现了问题,但是debug了整整两天都不知道为什么。到现在也不理解为什么一个初始化会导致时间惊人地翻了几倍,感觉很亏。
- 对于指导书的理解有误
第四单元的第二次作业,没有意识到可以从不存在的lifeline发送信息进来
虽然这样的成绩不能说是特别令人满意的,但是我觉得每次作业我都奋战到了最后,我已经做到了我能力范围里最好的了。
课程收获
提高了java编程能力,学会了简单的自动化评测机的搭建,一定程度上掌握了oo的编程思想。
说来惭愧,老师们在课堂上很用心地教授了很多关于oo的知识,但是我感觉自己始终是一知半解。网课经常要反复看两三遍,最后感觉也没有特别明白老师讲授的内容。现在也不确定自己理解的oo和老师所说的oo到底是不是一回事。
改进建议
- 关于评测
在搭建评测机的时候完全是两眼一抹黑,在网上自己瞎探索。感觉非常浪费时间,并且搭建的评测机效果也不是特别好。既然oo课程组强调自我测试的重要性,希望能够提供一些搭建评测机的学习资料,起码让人不要无从下手。
- 关于实验
每次实验之后都不知道结果影响实验效果。成绩可以不公布,但是正确答案以及快速解决实验中问题的思路感觉应该在实验结束后设计专门的时间讲解。不然没有反馈的实验相当于白做了。
- 关于第一单元
感觉即使有了假期两个预习作业的铺垫,第一单元的作业难度还是有点太高了。我觉得第一单元作业花费的时间超过其他三个单元不完全是因为同学对于java不熟悉,主要是正则表达式的解析太难了。我觉得如果要保持这个难度的话,假期预习需要加入更多相关资料(比如网上讲解正则表达式的视频之类),不然同学纠结于怎么通过中测,对于oo思想和架构设计就完全没有余力去考虑了。
oo线上学习体会
我觉得总体上说oo课程组的线上教学工作是做得非常出色的,甚至可以说是这学期课程中我觉得最认真负责的。上课时老师积极和同学们讨论,课下助教们热心回答同学问题,线上教学井然有序,成果显著。
不过确实有的时候出现了上课老师引导大家讨论,但是没有同学回应的情况,显得有些尴尬。
就我个人而言,我一般都是提前看完了视频内容的。但是每节课的讨论题感觉都不简单,我看完一遍视频之后确实也不知道答案是什么,也就没法回答老师的问题。我觉得也许老师可以给讨论题多一些的提示,帮助同学思考。