2024-BUAA-OO第四单元作业心得

22060106-朱李浩 2024-06-16 16:32:50

第四单元总结

经过了一学期的紧张,也算是迎来了OO课程的尾声。这一学期也不可谓不难,繁重的压力,还有不熟悉OO这种迭代开发与大规模开发、修复的节奏,还有大规模的程序设计,都导致OO课程开始的情况不甚理想。但是后面随着学习的推进,也慢慢学会了一些东西,能够在风浪中站稳脚跟了。本次博客作为最后一次博客作业,也就根据要求,以及个人体会,进行一个OO课程的总结了。

一、正向建模与开发实践总结

第四单元主要讲究的UML语言与程序开发中的实际关系,以及怎么使用UML语言辅助程序的规范化,迭代等。

在以往的作业完成中,我们习惯于直接进行简单的思索以后就立刻开始上手写代码了,本单元则是相反的,提倡我们先进行充分的架构思考与验证,再进行代码的编写。其实按理来说到了这一步应该就可以结束了,剩下的就是代码编写完成后,进行错误检查呵功能一致性检查的问题了。但是可能是因为我水平太菜,经验还是不太足够。后期我还是需要更改uml的设计,比如新增类,新增属性,新增关系,或者更改一些类的功能等。因此整个流程变成了,设计uml,编写代码,扩充uml,编写代码,然后在后面两个步骤中循环,最后知道完成相应的作业。

总结下来,也是因为太过缺乏相应的建模与设计经验,以及足够完备与长远的设计思考能力,所以可能更多需要走一步看一步,进行相互的验证与扩充。

在第一次作业的过程中,需要设计类图,需要描绘每个类的属性、方法等,这个虽说较为简单,但是对于基础不太好的我来说仍十分艰难。基本是想好了类的种类,但是无法预见每个类需要进行什么操作,设置什么属性等。因此在实际程序构造中反复补充类的属性与方法,对于部分方法的参数也进行了一定数量的修改。

第二次作业的状态图则相对来说简单不少,因为在第一次作业中也基本使用属性的描述来确定了每个图书的状态转移,因此相对来说任务轻松了一些。同时,有了第一次作业的基础,对于每个类功能的划分也有了较为清晰的定义,后面在定义类图、写代码、扩充类图、扩充代码之间的操作也相对来说少了不少。

第三次作业的uml设计其实个人觉得是最困难的,因为当顺序图加入了以后,你会发现其跟类图、状态图都产生了一定的关联与限制,比如“任何一个 message 的 source 和 target 所对应的两个类如果不同,两个类之间应有关联关系”这些,这些对于三者同时产生了一定的控制。同时,因为前两次已经形成了比较大的代码量,所以在编写顺序图的时候,也有较大的需要补充的消息,而不仅仅是的只有第三次的消息内容。顺序图复杂的生命周期、协作、以及消息的传递与返回的机制,也使得顺序图相比于类图和状态图更加复杂了。

总的来说,这一单元作业对于个人建模能力的要求还是十分高的,你需要拥有足够的整体思维以及前瞻性,才能够在最开始的构造时候“一步到位”,不然基本上就会出现需要对uml图和代码进行反复迭代的情况,互相扩充。但是经过这一单元的学习,确实也认识到了uml对于设计和代码编写的协助。uml图使得代码关系脱离了传统的文本语言的范畴,能够更加具象化地体现代码块之间的关系。同时,也能够对代码的合理性进行验证。以及个人感觉最明显的一点,在拥有了一个和程序相匹配的uml图之后,在你每次迭代、修改的时候,能够更加清楚地知道每个模块的作用以及情况,对于自己如果长时间没有回顾这一块的代码,确实能够明显提升开发效率,我觉得如果放在团队开发以及工作的交界的时候,形式化的语言与展现,也能够大幅减少自然语言可能带来的理解偏差,以及提高工作效率。

二、本单元架构设计及代码实现对应关系

本单元作业的最终设计如下:

类图:

Main.png

状态图:

StatechartDiagram1.png

顺序图:

SequenceDiagram1.png

本次作业整个结构个人还是比较自豪的,可以感觉应该是这学期对于抽象与聚合程度最高的一次设计了。整个过程只出现了四个类,所有的内容都抽象为这四个类进行表述,每个类各司其职进行各自的数据维护与管理。

可以看出来,程序的主体是Library类,Main主要负责输入与输出的处理与输出更新的触发等。没错,我没有使用官方包提供的输入与输出内容,同时为了方便处理,我还在Main中维护了一个debug变量,可以方便进行处理过程的显示。

Library则是整个“图书馆”的建模,里面维护了图书信息与用户信息。用户可以“拥有”图书,因此在用户内容内会维护自己的借阅、预约等信息。但是图书这个时候是不会记录自己的“被拥有”的信息的,因此不应该和用户出现双向引用的关系,因为这样数据结构会出现混乱,不利于维护。因此,图书馆的属性也是比较复杂的,大规模的Hashmap与ArrayList的数据结构,方便查询与管理。

个人感觉这一次作业的设计程度确实很好,所以迭代代码甚至都没有太多,每次新增一部分代码就可以实现功能。这还是得感谢同学对于设计上提供的建议以及对于抽象设计的概述。

状态图对于这块,因为每个功能设计集成的不错,所以也并没有出现一些极为复杂的状态图情况,比如存在两个状态之间多个转移方法与路线。在之前的作业中,个人觉得这是因该极力避免的,因为你极难进行dbug分析,以及边界情况的界定与判断,万一两个转移情况出现了重合,就可能出现一些不可预知的错误。

顺序图,其实个人还不是太会画,同时可能因为没有使用官方包的原因,所以导致并没有办法使用要求的开始与结束信息方法,也就只能写了两个空方法以通过实际的测试。这次放的为这次作业实际的顺序图。可以看见还是比较复杂了,基本传递了2~3层的消息。但是也并没有出现极度复杂的循环传递消息与交叉情况。

三、本学期架构设计思维的演进

本学期架构思维的变化,个人还是感觉比较明显的。从“散打高手”变成了可以抓到着重处理。

第一单元,确实还在使用面向过程的编程方式,虽说个人当时觉得设计的很好,毕竟根据编译器得设计方式,设计了前端后端和实际的运算执行部分,但是一遇到迭代就卡死了。不是因为前端设计和中间代码生成的迭代问题,这两块其实进行的还算顺利。但是当遇到互相包含与重叠的数据结构时候,就裂开了。因为没有抽象的思想,或者说,有,但不多,导致在第二次的时候就得开始重构,构造一个比较合理的数据存储结构。这也导致第二三次作业直接出现很大的问题。

第二单元,多线程,这一单元确实烧脑子,因为太过魔幻了。这个时候,我还基本上是“能过就行”。代码写出来了以后,也会出现各种问题,然后上锁设计也趋近保守,尽量给会出现冲突地进行上锁。同时程序设计方面,也有了一定的面向对象的思想,比如,使用了Settings作为电梯与中控传递信息的途径,同时也在中控层面,把每个电梯抽象为了一串“控制数据”,通过对这串数据的查询,修改,加载等操作,知晓运行状态,控制电梯运行等,而不需要直接关心电梯的情况,相当于它只需要关注这个“盘子”。但是可能因为个人能力不足的情况,设计的电梯还是会在修改了死循环bug之后,出现运行超时的情况,同时个人也尝试了更小粒度的读写锁等,以便提高并行程度。但是并没有出现足够的改善,可能是因为电梯策略本身的就有一定的不足吧。而且因为测试的不够完善,导致强测分数也不甚理想。

第三单元,jml,算是能够在思想上进行一定的实践的内容了。但是因为个人对于算法与数据结构的不熟悉,还是花费了大部分时间在算法的学习上,以便能够成功完成作业。但是对于算法的不熟悉,也导致了在三次作业中,超时的点越来越多,而且没有太多时间能够进行解决。不过对于jml的内容中间,也是花费了一定时间投入进行研究,并且认真完成了每次junit test的内容。

第四单元,才是个人感觉设计的最好的一个单元,虽然临近期末,时间真的很紧,但是因为有朋友学长等的帮助,一开始就进行了一个较好的设计,一改之前打乱仗东拼西凑的模式,在一开始就拥有了一个较为完善的架构,虽说后面还是因为思虑不全导致反复迭代uml图与代码,但是先期思想已经完善太多了,所以写代码的时间花费反而少了不少,以及迭代的工作量也有所减少。成绩也提高了不少。

四、测试思维的演进

整个课程下来,可以看出来“测试”这个东西贯穿了OO的全部,但是可惜的是,我明白测试的重要性,以及进行完备的测试的时间较晚,所以也导致前半段十分困难。

在第一单元的测试中,还在使用很原始的输入的方式,完成了功能a的支持,测试一下a,完成了功能b,测试一下b,OK过了,没有了。但是随着功能复合的增多,abc三者的复合功能是指数级增加的,并没有进行覆盖测试。导致中测弱测可以通过,但是强测基本碎碎。

第二单元就更神奇了,因为你完全不知道什么时候会出错。即使你大概预测到了边缘情况,但是在多线程的环境下,边缘情况不是所有,因为异步中间,什么都有可能发生,而你的人脑对“异步”进行揣测,是很难进行全部覆盖的,你只能通过大规模的测试来尝试着“覆盖”出可能的情况。而且就像老师上课说的“只要这个bug的情况出现过1次,在剩下的100次中间没有出现,但是他就是存在的”。你只能分析,或者测试以求复现。而且相同的输入,在不同环境下可能情况也不同,有时候真的在手动编制的情况下很难复现。

第三单元中,也是提供了一种验证方法,同时也引入了白箱、黑箱测试,jml也类似地提供了一种代码编写想法,以及单元或者模块的测试思想,虽说这个jml提供的代码“特性”或者是想法,并不可能是最好的设计思想。比如几层for循环的遍历肯定效率很差,还是得要点算法的。同时也是在这个单元中,我使用了自动化评测,首次展开了“黑箱测试”,同时也尝试了使用单元测试与白箱测试的方法,对部分关键代码进行了测试。但是可惜因为时间有限,并没有能够对每一个代码块或者单元进行全覆盖测试。

第四单元中,因为没有神奇的多线程,以及对于算法极强的要求,所以也就直接全部使用了黑箱整体测试的方法。但是因为随着迭代更新,各种事件的发生关系也是指数级增加,所以还是出现了单纯的整体黑箱测试不能够完全覆盖的情况,因此依旧出现了部分测试点在测试中没有被覆盖,但是在强测中被测出来了的情况。

其实对于测试,个人感觉在整个课程的进程中,没有能够将其发展到极致,比如更早地认识到测试的作用,更早地进行测试,不然效果应该能够理想不少。同时,也在此感谢那些能够花费自己课余时间编写自动化测试程序以及对拍等测试工具的同学,能够让我沾点光,同时也能够更加便捷地进行测试。

五、课程收获

一学期的OO课程,真的很苦很累,代码量大,时间紧凑,同时对于没有基础或者基础薄弱的情况真的举步维艰。但是也算是熬过来了。

在没有学习这门课之前,感觉自己面对一些需求,用面向过程等最基础的编程思维,磨也能够磨出来,无非就是花费多一点时间。但是在OO课中间,有限的时间,庞大的任务量,以及迭代开发的需求,使得我发现纯粹的靠时间磨,或者靠已有经验去硬着头皮蛮干有时候也是难以行得通的,面对迭代需求,重构,终究只是无路可走或者必要需求时的可选路径,这也是前期摆烂或者试图“少事”的代价。

同时,在前期还是比较缺少迭代开发的经验,即使写过网站,但是其集成程度与迭代的需求与密集程度,还是无法与课程中间的强度相比拟的。在课程中,你可能需要思考可能需要在什么方向进行迭代,从而提供一定的支持,以及怎么在迭代的时候,能够方便地回忆起之前的构造方式,从哪能够快速下手等,这也是UML图以及代码注释能够提供的帮助。在第四单元,因为有了这样一个类似于总概的东西,即使你已经忙到记不太清楚上次写到哪了,怎么构造的,也能够很快回忆起来,进行进一步的开发。

最后,大概也是测试的部分,确实了解到测试方法,与开始使用测试方法太晚了,因此也导致整体错误率真的很高很高。而且很多经过事后复盘,发现只是很呆的设计失误等,比如加值加错了等,但是就这么简单的错误,自己手搓测试过程中却没能够发现,导致了大规模错误的出现。

整个过程中,个人觉得最大的帮助还是对于编程思想的帮助,确实课程以一种形象且便于理解的方式,使我对面向对象的程序设计思想有了一个显式的认知,这是我以往看各种博客,教学视频中间未曾有过的体验。经过各种作业的训练,也确实感受到了相应的优势与运用。设计软件时的思维不再是面向过程那样,而是试图通过对象之间的联系来完成不同的功能,尽可能地降低代码的耦合度,实现“高内聚,低耦合”的设计原则。我觉得面向对象的思想对于我其他方面的学习也有着很大的作用,能够让我在完成工作的时候摆脱一些细节的限制,从宏观出发去考虑完成方案。

代码编写方面,也有了一定的经验,相比于以往纠结、不敢写的状态也有了一定的改善,敢于行动与尝试了,随着自身的设计和实现能力不断增强,程序的正确性与编写效率也有所提高。

至于与同学的交流,研讨课以及博客,还有助教的设计帮助与志愿者的帮助,也确实给予了我不少思想上的改进与设计上的帮助,使我能够快速进步。

再次感谢所有同学,助教,志愿者,以及老师的辛勤付出。

...全文
67 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

301

社区成员

发帖
与我相关
我的任务
社区描述
2023年北航面向对象设计与构造
学习 高校
社区管理员
  • YannaZhang
  • CajZella
  • C_ecelia
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧