OO第四单元总结

OO第四单元总结

一、第四单元架构设计

1.1 最终架构UML图

总体解析器架构

类图

顺序图

状态图

1.2 第一次作业总结

第一次作业可以说是三次作业中最困难的一次。由于刚开始接触UML,导致我需要花费大量的时间去理清楚各个元素的含义,以及元素之间的关系,但这只是开始,由于UML本身就很繁琐,同时指导书上所做的规定也非常琐碎,导致我在真正开始编码时,还需要搞清楚各个指令的含义与它所要处理的各种特殊情况。只有在搞清楚这些之后,才能真正的上手编码。

在熟悉了题目之后,第一次作业本身倒是并不复杂。第一次作业要求我们实现一个UML解析器,使其支持对UML类图的分析,可以通过输入相应的指令来进行相关查询。我的思路便是模仿UML本身的结构,将每个UML中的元素包装成一个类,并将这些元素建立成一个类似的层次结构,同时在建立的过程中记录下我所需要的各类信息,从而实现后续的查询操作。

总的来说,第一次作业的难点有以下几个:

  • 如何建立自己的UML模型:我采用了讨论区所说的三重遍历方法,按照层次关系在每一次遍历中提取相关元素,然后进行建模。
  • 如何保存信息方便查询:由于UML中的元素是按照id区分的,但是在查询时传入的参数是name,因此我的做法是针对某个信息,使用两个HashMap来存储,第一个HashMap的键是元素id,值是这个元素本身,第二个HashMap的键是name,值是一个ArrayList,存储同名但不同id的元素。
  • 如何判断重复操作:这里一定要搞清楚参数列表相同的概念,两个操作的参数列表顺序可能不同,但只要两组传入参数之间存在某一一映射使得类型相同,就可以被判定为重复操作。
  • 查找类实现的全部接口:我采用了最朴素的dfs查找的方式,但是当我们对某一个类查找完成后,可以将结果保存起来,这样当另一个类向上查到到了这个类时,就可以直接合并,得到结果。

1.3 第二次作业总结

第二次作业新增了对UML状态图和顺序图的分析与查询。有了第一次作业的基础,这次作业就简单了很多,我们的建模方法和第一次作业一样,还是采取多次遍历提取元素的方式,而在存储信息时,也是按照应存尽存的原则,每种信息都使用了两到三个HashMap来存储。第二次作业的难点有以下几个:

  • 搞清楚状态图模型里的各种状态的定义,以及他们在UML里的表示,这里我们需要将UmlStateUmlPseudostateUmlFinalState分别进行考虑,进行特殊处理。
  • 判断关键状态:关键状态的定义很重要,在判断关键状态时,我采用的方法是使用两遍dfs:首先从起点开始dfs看是否可以到达任意一个终点;然后去掉查询点再dfs查看是否可以到达任意终点。

1.4 第三次作业总结

第三次作业要求我们扩展UML解析器,使其能根据UML规则进行一定的规范性验证。本次作业在架构上和第二次作业基本相同,只需要在第二次作业的基础上增加对UML的检查即可。本次作业的难点有以下几个:

  • 判断循环继承:循环继承要求我们输出在继承环里的所有类或接口,本质上是在求强连通分量,因此我使用了tarjan算法来求大于二的强连通分量,并对自环进行了特判,从而求得结果。
  • 判断重复继承,依旧是采用dfs的方式,对每一个类或接口向上递归查找,如果发现有重复的继承,就加入结果。这里一定要注意,如果开始存储接口的父接口时,采用的是HashMap,就会导致一个接口多次继承另一个接口只被算作一次,即使对这种情况做了特判,之后还需要考虑其子接口的多重继承问题。

二、架构设计思维及OO方法理解的演进

2.1 第一单元

第一单元的任务是要解析表达式,表达式是一个层次非常清晰的结构,自顶向下可以分为表达式、项、因子,而因子又可以划分出特殊的表达式因子,从而形成了一个良好的递归结构。因此将这三层进行封装,并通过递归下降法进行解析,便可以实现解析的功能。

在架构设计方面,第一单元通过引导我们建立一个层次清晰的表达式,锻炼我们架构设计的能力。在这一单元的作业中,我领会到了代码封装的魅力,在具体的每一层中,只需要考虑本层需要实现的任务,而不需要考虑整体实现的复杂细节,便可以将任务简化,最终使得任务难度大大下降,当然这个过程并不是很简单的,我经过了两次作业的摸索,才在第三次作业中实现了一个令人满意的架构。

2.2 第二单元

第二单元的任务是模拟电梯调度,本单元的主题是锻炼我们多线程编程的能力,在理解多线程编程的基础上,引导我们使用多种设计模式,来锻炼我们的架构设计思维。

在这一单元的前两次作业中,我使用了生产者-消费者模式来设计我的电梯架构,将输入作为生产者,分配器作为消费者,从而实现将不同的请求分配给合适的电梯。在第三次作业中,由于换乘请求的出现,我在生产者-消费者模式的基础上,新增了流水线模式,对于需要换乘的请求,我将其分为不同的阶段,每一阶段完成后,将其重新封装为一个请求归还给分配器实现下一阶段的分配,并在最后验收整个请求是否完成。

在这一单元中,如何设计合适的电梯架构是一个重要任务,这就锻炼了我们架构设计和OO方法相结合的能力,既让我们熟悉了生产者-消费者模式、流水线模式等等设计模式,也让我们在实际的编码过程中加以运用。同时本单元也让我们学习了多线程的知识,掌握了多线程编程的能力。

2.3 第三单元

第三单元的任务是按照给定的JML规格编写代码,主题思想是契约式编程。本单元通过对JML规格的阅读以及按照规格撰写代码,训练了我们契约式编程的能力。通过这一单元的学习,我熟悉了JML规格的阅读,并了解到了在今后的学习与开发中,契约式编程的重要性与实际应用。

在这一单元中,我认为最重要的是不能拘泥于JML规格,规格只是告诉了你代码实现最终的效果,而实现的方式则多种多样。如果仅仅是按照规格来撰写代码,那么代码的性能就很难保证。因此,在这三次作业中,我广泛使用了图论的经典算法,例如并查集、最小生成树算法、最短路径算法,来优化代码的性能。

通过本单元的作业,我也了解到了未来学习与工作中可能会用到的契约式编程的思想及其优势:契约式编程具有十分清晰的规则,因此它有助于提升工作的效率,让每个人清楚的知道自己的职责,简化了沟通的困难与可能出现的差错。

2.4 第四单元

第四单元的任务是实现一个UML解析器。本单元很好的锻炼了我们架构设计的能力,要求我们通过对UML元素的解析与层次化建模,实现一个信息详尽,便于查询的层次化结构,并对最终的结构进行信息查询与合法性检验。

在本单元中,我依据UML本身的层次结构,将每一种元素进行了封装,完善了其保存的信息,并建立起层次化的模型,最后分别对类图、顺序图、状态图建立了查询类,并在最顶层建立了合法性检验类,实现了功能明确,高内聚低耦合的架构。这进一步锻炼了我的架构设计能力。

三、测试理解与实践的演进

当完成了一次作业后,我的测试通常分为三层:

  • 首先是代码的静态检查,因为在编码的过程中,我们会在短时间内纠结某个局部,而对整体失去把握。同时,在编码时,笔误是不可避免的。因此在完成了代码后,我通常会大致的检查一遍,观察整体的逻辑是否合乎我的设计,同时检查有没有变量使用错误。
  • 其次是手动构造针对性数据进行测试,在这一部分,我通常会针对作业要求中重点考察的部分,以及各种边界情况构造相应的数据,来检验程序的输出是否合乎预期。这也是我排除掉大部分错误的主要方式。
  • 最后则是自动化测试,通过构建评测机生成大量的数据,并通过正确性检验或是多人对拍来检验程序的正确性。这种测试往往能够使我们发现程序中非常隐蔽的错误。例如在第一单元中,由于输出具有多样性,因此我使用了python编写了数据生成器,并使用了sympy库进行正确性检验;而在第三单元中,由于输出具有确定性,因此主要是通过数据生成+多人对拍的方式进行测试。在这一部分中,我最大的遗憾是很少亲自动手编写一个评测机,往往是搜寻github上往年学长的代码进行改编,或是借用大佬的评测机进行测试。在今后的测试中,我也要试着动手实践,锻炼自己编写评测机的能力。

四、课程收获

  • 在架构设计方面,我认识到,在面对复杂的工程时,一定要认真的理解需求,并有一定的预见性,考虑到未来的迭代与扩展开发,合理的进行架构设计,之后再开始编码。这样能够事半功倍。
  • 在课程中,我学习到了面向对象编程的思想和各种设计模式,认识到了SOLID设计原则的重要性。合理的使用各种设计模式,并遵守各种设计原则,能让我们的架构更加优秀,编码更加合乎规范。
  • 在测试方面,我也了解到了各种测试的方法,认识到了评测机、数据生成、对拍的重要性。相信这些经历能在我今后的学习和代码开发中发挥重要作用。
  • 课程的12次作业,也锻炼了我编写大型项目、迭代开发的能力。

五、课程建议

  1. 我认为寒假的pre时间可以适当的前移,同时适当的增加pre的训练内容,并告知同学们未来的作业中可能会使用的理论知识,让同学们打下更加良好的基础。这样可以让同学们在面对难度陡然上升的第一单元、第二单元时,不至于那么的手足无措。
  2. 希望课程组能在一些测试困难的单元,例如第一单元、第二单元,适当的分享一些搭建评测机进行自动化测试的经验。并引导同学们进行自动化测试。因为在互测中,通读他人代码进行学习借鉴和debug的时间很少,几乎就是在考验大家造数据的能力。与其让同学们漫无目的摸索出刀,不如进行合理的引导,告诉同学们如何进行高效的测试。
  3. 第三单元的难度并不高,我认为可以压缩一部分内容,节省时间,也能够在最后的考期省出一周的时间,不至于在考期还堆积大量的任务影响复习备考。
posted @ 2022-06-28 17:31  Levelower  阅读(11)  评论(0编辑  收藏  举报