第四单元总结
第一次作业
第一次作业一开始,我自己把需要的部分元素实现了一遍,例如MyClass,MyInterface等,他们分别存储了相对应的UML
Xxx类在查询时所需的信息,也按照逻辑存储了一些其他的信息,例如MyClass的父类id,参数,操作,关联项等等,这为下面的查询定下了不错的基础。这之后,再用ClassCollection和InterfaceCollection两个单例类来实现相应管理。
大部分的查询方法实现都较为简单,只有关于接口的查询。其实在怎样实现上也没什么好办法,就直接用上个单元的bfs拿来用。另一点是,关于关联数的计算,看到有不少人询问其实助教在讨论区说了,数AssociationEnd就可以了。
这样的架构不算很差,但是若牵扯到同时和Class以及Interface有关的查询,其主要逻辑还是放到了Interaction里,这样对于扩展其实不算有利。
第二次作业
第二次作业的内容其实很简单,我还是依照上次按结构重新实现一遍这些类,如MyStateMachine,MyState,MyLifeline等。同时,上次代码的复用困难和眼看就要超500行了的限制,让我向上又封装了一层,StateManager和InteractionManger,把对于具体对象生成和查询处理的主要内容都放在了这个类里,对外只提供接收UmlElement和返回查询结果的接口,使得MyGeneralInteraction进一步解耦,具体实现也更清晰,更漂亮了。
至于这次要写的查询方法,依旧是只有依靠上次的bfs解决的可达状态一个。
第三次作业
第三次作业的主要内容,就是对于Uml图的检查。这次,我终于忍受不了,把第一次的垃圾遗产移到了新的ClassManger里,并且做好分包,使得整个内容变得能看起来。至于具体实现,理想情况下,我希望可以通过对一张图的一次扫描就完成所有的工作,但实际是线上为了尽量不改变已经正确的部分和实现难度确实有,就没有全部整合进一次扫描。后4个和第一个查询,都可以依靠简单的标记实现。(不过第一个我还是阅读理解失败,错了一个点),故而不谈。至于002,003,004,显而易见地可以发现,主要就是对接口图的遍历问题(类图不算图,错的几率太小了)。
-
002的判断是关于是否有环路,这类判断有各种各样的写法,但我最终还是怕出错,选择了判断每一个是否是环上的点来实现(当然不是全裸)。
-
003实际上意味着到达一个点有两条路,这个也按照上面循环一遍也就好了,但与此同时,也可以得到一个接口实现的所有的接口了,这在004和问询接口时可以省事。
设计总结
第一单元作业,这次由于对于基本架构的设计较差,导致前两次作业还算基本把计算和元素的设计放在了正确的位置上,而第三次基本上就是对于一种叫Item的对象进行求导计算的面向过程代码,这使得那些有的没的的优化就成了平添bug,相当于在设计上给了我一个大教训。也给了我每次重构都能变强顶住的强大抗压心理。
第二单元,由于接触的是全新的多线程,且第一次了解了“设计模式”,为了搞懂这个全新的东西,我在多线程和设计模式两方面,都阅读了不少资料。所以这次基本山就是在第一次的生产者——消费者架构的基础上进行修改,比较成功。每周不用重构,任务量骤减。成熟的设计模式一方面保证了正确性(说实话,我觉得设计模式正确的话,基本不考虑临界区大的效率低下问题的电梯还不太容易出线程问题来的),另一方面也使得扩展更为容易,这是由于职权较为清晰的缘故。
第三单元,基本是照着JML写实现方法,没有什么设计。
第四单元,设计结构比较清晰,就是照着UML天然的所属关系形成的树来完成架构,比较清晰。
测试总结
测试是OO课程的重要一部分,关乎着自己的强测得分和互测的奖励分。找bug的基本方法也就是两条路:手动构造又或者自动化测试。
手动测试更具有针对性,但数据量较小。而自动化测试的数据量大,但针对性较弱。
手动测试最大的问题其实主要不是数据量小的问题,依靠单纯加量就可以解决的问题没有很多,仅有例如线程安全问题(多跑几遍),时间复杂度(事实上,这也和针对构造有关,例如第四单元强测反复出现的卡不vis选手的图),堆栈溢出(其实也得构造个长链)。其它的很多结构性问题,不需要很大的数据量,就可以引发。
而自动化测试,其实有可能在随机过程中出现这些针对性测试,从而找到bug。此外,其实自动化测试也可以生成较为特殊的数据,或者针对不同的规则要求或者数据分类,分类进行较为具有针对性的测试数据。其实,这也是具有一定针对性的。
针对这几次作业,我在第一单元时,没有实现真正能用的评测机,实际上还是基本依靠本地测试。
而在第二单元时,自动测试的逻辑比较复杂,且我对针对第二单元的特殊数据没有很多积累,所以实际上有逻辑的测评也没有起到很大的作用,主要还是对拍和手动。
针对第三,第四单元,由于没有互测,其实不必要搭建一个好的测评机的要求进一步下降,更多的只要依靠手动+比较有针对的随机数据对拍就可以了。另一项就是使用JUnit,但是由于对拍太简单了,且基本上问询语句就代表了测试的模块是谁,所以JUnit的作用被部分代替了。
课程收获
OO是我这学期感觉比较良好的一门课指的是被虐了那也没怨言。
从宏观的层面上来说:大概一学期过去了,我有了一个对于面向对象的初步概念,知道了一些简单的设计方法,也学到了一些新的知识。这些知识不单单止步于写完作业本身,另一方面其实也是如何进一步掌握Java又或面向对象的指导方向:例如第二单元,关于JVM和多线程的相关知识,还有很多可以深入学习的部分,第三单元为了解决时间复杂度的问题,也初步了解了一些Java容器的底层实现,(甚至结合起来,可以去了解线程安全问题的底层实现),还有包括一直以来都在被强调的”设计“的问题,都是将来可以进一步深究学习的部分,而面向课程这门课,让我初步了解了这些知识,也有益于将来的进一步学习。
另一方面,由于强测和互测制度,也强迫我们学习了一些相关的测试知识,这也是十分宝贵的部分。
很感谢OO这门课,看着最后pre+work内四个单元的文件夹,我还是能感到这学期有了一些进步,学到了一些东西,也知道了一些将来想多学一点的东西。
此外,还有一些零散的知识,例如git的使用,命名的规范,以及真诚感谢第三单元,虽然很不OO,但是帮我补上了DS的超级大坑的一部分。
几个建议
- 感觉第一单元的设计难度其实较大,希望在前期多给一些指导资料。
- 第四单元助教搬来的往年优质讨论真香,希望课程组考虑汇总往年较好的讨论和博客给下一届。
- 希望实验有反馈,
我们高中老师告诉我们,没答案的题不值得做。
线上学习收获
感觉线上学习对OO基本没有影响。相反地,因为我个人更倾向于阅读文字资料,所以微信群讨论和可以回看的录播视频对我有很大助益。与此同时,看不到同学也让我能够敢于进行研讨课分享。而且,对于ppt比人重要多了的研讨课,录屏能够更好地看到文字内容,随时截图,这是非常,非常,非常好的行为。