第四单元作业总结

第四单元作业总结

本单元,我们自学了UML图及其json层次化表示方法。在此基础上,我们完成了对类图、顺序图、状态图的解析以及查询方法,并根据UML规则对输入的数据进行了正确性检验。总体来说,第四单元是对前三单元的综合,既有第三单元式的“类规格”要求,也有一、二单元自主设计程序构架的要求,并让我真正有些明白了什么样的程序才是好的面向对象的程序。

第四单元框架总结

本单元1/3时间理解UML,1/3时间写框架,1/3时间实现功能。本单元让我充分认识到了构架的重要性,构架就像是一个小的操作系统,系统写的好、服务到位,就能轻松实现复杂的功能。得益于第1次作业的构架设计,我在本单元并没有重构,而且在第3次作业时,也没有像其他同学一样遇到各种各样的问题。

U4H1

由于注意到了UML中Class和Interface作为Node的地位十分相似,因此在设计之初我就让MyClass和MyInterface继承自MyNodeElement,由此实现了灵活的UmlGeneralization和UmlRealization。除此之外,我一开便考虑到了多继承的情况,因此在MyNodeElement中设立Map<String, MyNodeElement>用于分别储存继承和实现的父节点,这也为我第3次作业打下了良好的基础。


图片名称

U4H2

第2次作业中,加入了对顺序图和状态图的解析。因为在作业要求中,三种图相互独立,因此在本次作业中,我也使用了模块化设计,三种图之间相互不可见。这样的设计虽然实现了模块间解耦,但是却会在三种图需要进行交互的时候引入额外的麻烦。不过,幸运的是,本单元中并没有出现这个问题。


图片名称

U4H3

本次作业中加入了8条规则,其中R003、R004、R005放入MyNodeElement中,作为节点的方法,由MyClassInteraction调用,其余放在Interacation类中实现。程序的构架延续自第2次作业。


图片名称


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

OO实则为一种编程思想,其根本在于将属性、方法等元素按照对象分类,并挨个“打包”,以此实现封装(说白了就是我写完就懒得管了,只要确保这个包是正确的,打好包扔一边),并且实现“高内聚、低耦合”的模块,让程序更加具有灵活性、适应性、鲁棒性。

大一时

现在回想,其实我在很早以前就已经开始无意识地使用OO思想进行编程。下图为大一下学期数据结构课程中的“北京地铁最短路径”。当时的我习惯将程序拆成一个个模块(如读入、处理、输出),一个个完成。在确保每个模块能够正确行使功能后,就放在一边不再管。现在看来,当时图方便的做法恰恰是面向对象中对方法的封装。


图片名称

第一单元

第一单元刚开始时,我对面向对象的理解仍然停留在大一的水平,认为面向对象仅仅是对部分代码的封装,并没有按照对象抽象出不同的层次,这就使得我在写第一单元第三次作业时遇到了极大的阻力。

第二、第三单元

在学习这两个单元时,我对面向对象的理解进一步加深。相比于第一单元对代码过程式的封装,我能够根据具体需求抽象出具体对象了。例如在第二单元中,我抽象出了电梯轿厢、电梯控制器、分配器、乘客等对象,这种对象式的封装是我能加顺畅的完成了原本十分复杂的任务。

在第二单元结束时,我阅读了《重构——改善既有代码的设计》,并对电梯的代码进行了局部的重构。在灵活使用了继承特性后,增强了代码的可扩展性,能够适配未来出现的货物、特殊策略、多类型电梯。至此,我终于明白了面向对象和面向过程的区别,以及什么样的代码是可扩展的。

第四单元

第四单元使我明白了构架的重要性。在学习第四单元时,我用了1/3时间理解UML,1/3时间写框架,1/3时间实现功能,并且在第1次、第2次作业中分别尝试了两种构架设计,并且深切体会到了构架好坏对程序的影响。

第1次作业中,我采用的“宏内核”的设计,所有的功能实现丢给底层类递归实现,而Interacrion这一“用户”程序则十分简单,只需要1行代码调用对应操作即可。这种实现方式虽然让“用户程序”显得十分简洁,但是不够灵活、难以移植。后来为了修改1个bug,我不得已往dfs算法中传入一个idiot类,只为记录当前节点是否已经访问过。

第2次作业中,我借鉴了Linux的设计,底层类只提供简单的、最基本的操作,具体功能的实现需要“用户”自己把这些功能拼在一起。(Linux提供了管道、grep、重定向等一系列十分简单的工具,用户可以按照自己的需要进行拼装,从而灵活地实现复杂的功能。在第2次作业中,我的底层类只提供找父节点、检查规则、查询id等十分简单的服务,需要“用户”在Interaction中自行组装)采用了更优构架的2、3次作业并没有出现bug,且能够实现更加复杂多变的图算法。

实践证明,第2次作业所采用的构架更为成功,具有更强的灵活性、可移植性。通过这个单元,我深切地明白了一个道理,越简单、底层的服务越灵活,越复杂、封装完善的服务更加强大、但不够灵活。我认为这也是我相比功能强大的Python,更喜欢指针满天飞的C语言的原因。

四个单元中测试理解与实践的演进

第一单元时,结合sympy手捏数据进行测试,十分低效,并且不是自动化的。

第二单元时,我使用了对拍的方式进行测试,这样改善了测试的效率(不用等着sympy完成化简),但是数据依然是手捏的。虽然这样做虽然覆盖面不够广,但是却能够根据程序的逻辑,造出更容易造成逻辑混乱的数据,从而暴露程序的问题。(de出了楼层换乘的bug,但是电梯的人数上限被我忽略了,其实当时就是犯懒了,数据都捏好了,但是没仔细看。。。。。)

第三单元时,由于输入具有固定的格式,因此使用了自动生成数据 + 对拍的方式。事实证明,在理解彻底的基础上,自动化测试方式能够有效的检测bug是否出现(2、3次作业没bug,实际上也没写出bug)

第四单元时,采用了半自动化 + 半手捏的方式。自动化测试用于数据轰炸,先找出大的问题。手捏数据实在mdj文件的基础上进行修改,造出特别刁钻的数据来测试程序的鲁棒性。第四单元,除了指导书没说清楚的UmlParticipant之外,没有其他bug。

课程收获

一学期下来,OO课程是我学会了面向对方的编程思想,并且着实感到了OO的优势(省心)。前面所述可能是老师、助教们设计好的教学目标,但是OO真正教会我的是:即使面对一团乱麻一样的代码也不样轻言放弃;在关键时刻一定要懂得取舍,不能因小失大;不能只看局部,只有从整体审视才能写出成功的构架。

三个具体改进建议

1.第一单元放在开头真的有点难了,希望课程组能够调整一下难度,或者微调教学的顺序。

2.在第一单元时,以代码实例让我们明白什么是面向过程,什么是面向对象。

3.第四单元的指导书可能需要完善,第2次作业的指导书有些地方说的不够清楚。例如,第2次作业的指导书只说了统计UmlParticipant的数量,并没有界定UmlParticipant的范围,并且官方认证的讨论帖中写了Participant包含EndPoint和LifeLine。结果在强测中EndPoint不被认为是UmlParticipant,随后课程组在第3次作业中修改了指导书。

线上学习oo课程的体会

线上学习对我们的毅力提出了更高的挑战,在家看视频很有可能看着看着就走神了,如果想学好OO还是要靠自制力。

原文地址:https://www.cnblogs.com/EricYan2000/p/13129866.html