BUAA_OO 第四单元总结和课程总结博客

BUAA_OO 第四单元总结和课程总结博客

本单元的架构设计

第一次作业

作业分析

本次作业需要实现对uml类图的解析,要求能够实现类中的属性和方法的数量统计、类的属性可见性查询和类的关联以及实现接口等等。

架构设计

要完成本次作业,首先要对类图中各个层次结构进行分析,了解类图中各个元素的关联关系,如图所示:

除图中uml元素之外,还应该由association连接两个umlClass,每个association含有两个associationend元素:

在本单元中我自己构造了MyUmlClassMyUmlInterfce类用于存储类、接口以及其所含有的相应元素,并使用HashMap来存储各个UmlElement元素,首先进行对所有element元素进行三次循环将所有元素加入当相应Map中。在第一次循环时,我先处理了UMLClassUMLInterface元素,并根据这些元素构造了自己的Classinterface类;在第二轮循环时,我处理了UMLAttributeUMLOperationparentId为相应类与接口的UML元素以及UMLGeneralization、UMLAssociationUMLInterfaceRealization等直接关联类和接口的UML元素;在最后一轮循环中,我处理了UMLParameter元素。

这个架构结构较为简单,但在进行部分查询操作时可能需要时间复杂度较高(但因为本次作业时间限制不是很严格就没有进行太多优化了*_*

在所有方法中,需要注意的是接口的相关查询,由于在接口查询时可能会遇到接口的重复实现,因此,需要使用一个list来存储已经查询过的interface,避免因重复实现而造成的死循环。

类图

bug分析

本次作业由于有一个异常抛出错误(即本该抛这个异常的时候抛出了另一个异常),造成了强测某个点的损失,在改变了抛出了异常之后bug被顺利修复。


第二次作业

作业分析

本次作业要求在上一次作业的基础上实现对顺序图和状态图的解析,并实现状态机的状态数量,某个状态的所有可达状态,顺序图中的参与对象和顺序图中的消息等等元素的查询。

架构设计

本次作业在UML类图的基础上添加了UML顺序图和UML状态图,为了对UML图的层次关系进行合理解析,首先需要了解UML顺序图和UML状态图的结构关系:

在本次作业中,我添加了MyUmlStateMachineMyTransitionMyInteration类。初始化过程依然和第一次作业中相同,只不过加入了顺序图和状态图的初始化步骤。在实现顺序图时,我将所有的生命线和消息存储到了MyInteraction中等待查询,比较简单。在实现状态图时,我在MyUmlStateMachine中存储了该状态图中的所有状态和状态转移关系。除了正常的状态以外,还有final和init状态,为此,我在MyUmlStatemachine中设计了两个布尔变量用于标示该状态图中是否含有起始状态和终点状态。为了便于状态转移关系中触发事件的查询,我设计了MyUmlTransition类存储与该状态转移相关的触发事件从而进行查询。

类图


第三次作业

作业分析

本次作业需要在前两次作业的基础上对模型进行有效性检查,主要包括循环继承、重复实现、属性同名等情况的判别。

架构设计

在第三次作业中,我设计了一个类FormatCheck进行有效性检查。在这些规则中,比较容易出现问题的是R003和R004两个关于重复继承和重复实现的判断问题。由于在数据中可能出现重名的类和接口以及循环继承的情况,我改变了前面搜索接口时只用name进行判断的设计,将其改成了用id判断是否重复,如果前面已经出现过这个id,则说明出现了重复继承或重复实现等问题,抛出异常即可。这次作业虽然难度不大,但很容易出现考虑不全面等等问题,幸运的是,由于本单元作业需求改动是渐进性的,没有出现新的奇怪需求的情况,所以本单元我没有进行重构,每次作业改动也较少。


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


第一单元

在完成OO课程所有作业后再回首,我感觉第一单元才是难度最大的一个单元。在第一单元的作业中,由于对面向对象的思维不够了解,我进行了多次重构以达到三次作业的渐进性需求,最终设计架构的类图如下所示:

在进行第一单元作业的时候,不管从思路上还是在实现上都遇到了很大的困难,在前两次作业时,我出现了循环依赖的状况,代码复杂度极高,嵌套层数也很深,也因此造成了许多难以处理的bug,在进行重构后,我重新考虑了多项式应有的结构,将其分为了不同的层次进行处理,这样有效减少了循环复用的情况,有效避免了大量bug的发生。

在这一单元我可以说从零开始理解面向对象的思维方法,从第一次作业中面向过程分析整个多项式解析求导的流程到第三次作业将多项式分解为各个层次进行处理,逐渐走向面向对象,我大概了解了面向对象的一部分思路——将整个问题拆分成不同部分,每个部分负责自己有关的事情,外部只需要调用该部分暴露在外的接口而不会对该部分本身造成改动。虽然第一单元给我造成了非常非常大的压力,但最终程序的完成给我带来了很多成就感,也提升了我面向对象编程的能力。


第二单元

第二单元的主要目的是为了让我们接触多线程的相关内容,了解多线程的死锁和安全等等问题。比起看到第一单元任务时的不知所措,在这一单元的作业实现中,我很快就找到了思路。在本单元作业中,我采用集中式调度,将整体结构分成了电梯单元和输入处理单元,每个电梯拥有自己的电梯队列,当电梯队列为空时,电梯会从输入处理单元中的等待处理需求队列中取得request并放入自己的电梯队列中进行处理,总体架构如下:

在这三次作业中,我均采用了集中式调度,可拓展性较差,但好处是结构简单,不容易出现问题。在这一单元作业中,我线程安全方面出现了很多问题,作业中经常有死锁的发生,其中最令我头疼的是线程相互唤醒导致无法进入wait状态的问题。(线程安全问题真的是难发现难解决TAT)经过本单元的学习,我更深入了解了线程运行机制所带来的结果——任何两条语句都有可能连续执行,也就是说,我们必须要保证在任何一种顺序下都能够得到正确的结构,这也是多线程编程的难点所在。


第三单元

比起前两单元来说,第三单元真的十分友好,根据课程组给出的JML语言来填充相应函数并作出适当优化即可。在本单元作业中,我将其看成了一个图模型,person即是图中的节点,relation是图中的边,增加person相当于向图中增加节点,使用HashMap容器进行存取为了确保一定的时间复杂度避免TLE,我在实现isCircle函数和queryBlockSum时使用了并查集机制,为每一个person设置了一个祖先,当两个person祖先相同时即可说明两个点联通,同时在两个person中添加relation时需要维护并查集的关系;在实现sendIndirectMessage函数时,我采用堆优化的迪杰斯特拉算法查询两个点之间的最短路径。


第四单元

第四单元需要实现对UML图的解析,经过前面三个单元的训练和学习,在完成这一单元的作业时我对于模块的拆分和梳理已经比较得心应手了,也能快速梳理不同UML元素之间的从属关系。可以说到了这个单元,我已经能够较为熟练地应用面向对象的思维方式将整个问题分成不同层次不同部分进行处理了。


总而言之,从第一单元到第四单元,作业难度呈现不断下降趋势,我对于面向对象思维方法的理解也不断增强。从开始时努力从面向过程的思维转向面向对象的思维到最后一个单元直接以面向对象的思维方式开始思考,将问题拆分为相应部分进行处理,OO这门课让我收获许多。


对测试理解与实践演进

由于对评测机的搭建不够熟练以及作业已经造成的巨大压力,我在评测机方面并没有花费太多的精力,只在某几次作业中进行了尝试。在第一单元作业中我尝试使用python中的sympy库搭建了对拍程序对互测屋中的程序进行测试;在第二单元中我使用正则表达式生成了部分随机化数据进行测试;在第三单元中我使用了课程组推荐了JUnit测试方法进行了单元化的测试并使用python程序对一些构造出的边界数据进行了验证。在最后一单元中由于直接测试难度较大,我在大佬的帮助下进行了程序的对拍并找到了许多考虑不周全而导致的bug。(此处感谢大佬的帮助)

总而言之,我在测试方面所作出的努力不够,一方面是因为自身能力不足,另一方面则是因为对测试并不重视,(测试其实真的很重要TAT)我以后会在这一方面多多努力,希望在以后的课程中努力做到完备的测试叭。


课程收获

  • 对面向对象的思维更加了解,将程序看成由一个一个独立部分组成的个体,由各个个体之间的接口进行协同作用完成程序功能,各个部分之间没有相互影响,不必知道对方的实现细节。

  • 层次化设计能力有所提高,在设计一个规模较大的程序时,可以先进行架构上的设计,并考虑在程序功能需要扩展时架构该如何调整。在架构设计完成后可以先将代码的框架搭建出来,写出需要使用的函数和类等待之后填充。

  • 数据结构方面的收获。在每个单元的设计中,我选取了不同的数据结构来适应不同的需求,保证数据存取较为容易。在第三单元作业中,为了保证时间复杂度,我查找并选用了并查集算法和堆优化的迪杰斯特拉算法,对于数据结构方面的知识由了更加深刻的实践体会。

  • 多线程方面的知识。在第二单元的学习中,我对于多线程运行机制和线程安全有了更加深刻的体会,在线程运行过程中,任何两条语句都可能顺序执行,需要使用锁的机制保证临界区代码的安全。

  • 测试方面的收获。python中subprocess的使用、jar的运行等等。

  • 写代码要多做测试,精益求精。在前面几次作业中,我基本以过中测为目的,在中测完成后就不在进行测试,但在互测和强测的时候往往会暴露出代码中的很多问题,在后面的作业中,我往往会更加注重程序本身的质量,多进行测试发现bug,不仅仅是以完成作业为目的了。

总之,OO这门课可以说是我本学期编程学习方面收获最大的一门课了!!!


课程建议

  • 建议在寒假预习课程的时候增加一些内容以便更好地和第一单元接轨。(第一单元实在是难度太大了-_-)

  • 建议后面两个单元的题目说明更加完善。在这学期的作业中这JML单元的规格描述和UML单元的叙述存在不清楚的地方,导致同学们需要关注讨论区中问题并大量翻阅才能得到明确的说明,甚至在代码完成后还需要根据讨论区进行改动。(或许可以整理今年有争议的地方在以后的指导书中明确一下)

  • 建议实验课程的答案能够公布。在每次进行实验课程时,虽然很有收获,但往往不知道自己的结果是否正确,公布答案也更有利于同学们课后的学习。

posted @ 2021-06-26 18:03  ZIMUQIN  阅读(51)  评论(0编辑  收藏  举报