BUAA OO 第四单元总结

第四单元结构设计

本单元的主题为UML解析器,要求对UML类图,顺序图和状态图进行基本的查询和合法性检验。由于本单元的作业为迭代开发,故直接展示第三次作业的架构。

首先是总体的架构以及各个板块的类图:
img
img
img
img

  • 整体的架构分为四个部分,分别为类图包,顺序图包,状态图包,以及MyImplementation类。其中,MyImplementation类承担用户接口类的作用,负责调用对应软件包中的方法。而类图包,顺序图包,状态图包则负责相应的UML图的解析和合法性检验。
  • 在具体的软件包中,构造必要的MyElement类,将Umlelement作为其属性,并添加一些必要的属性以实现元素之间的从属关系以及查询等。以StaetDiagram为例,其中的MyRegion的属性有umlRegion以及statespseudostatefinalStates等,解析到UmlState是,便将其添加到states中,查询UmlState的相关信息时,便从states中依据id进行检索。
  • 在容器的选择方面,为了提高效率基本上采用HashMap以及HashSet,对于一些需要进行查重操作的元素采用的为ArrayList
  • 在解析方面,将元素分类并依次遍历解析。
  • 在信息查询方面,有以下几个基本的查询方式:
    • 根据id在HashMap中获取相应的值,也就是元素;
    • 在解析时,将其添加到某个类的属性中或者维护相应的变量,查询时通过get()方法获取元素。
    • 如果需要对元素进行筛查,则直接通过for循环或者λ函数筛查即可。
  • 在异常的检测方面,在类图包中新建了ClassChecker()类,一定程度上实现了检测方法的解耦,其他两个软件包为了方便没有再新建一个检测类。
  • 在算法的选择方面,继承树的建立,重复继承的查询都选择了\(dfs\)算法,查询循环继承则采用的为\(Tarjan\)算法,时间复杂度为\(O(m+n)\)

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

  • 第一单元

    第一单元的主题是解析表达式,并将其展开和化简。其架构设计思维主要是层次化设计,利用面向对象的这一思想能够天然地解决递归的问题。在刚开始接触时,对面向对象编程的思想认识不足,主要是参照Training部分给出了基本的架构。如下图所示:

    img

    第一单元的作业第一次让我感受到了面向对象编程思想的精妙和优雅,对于方法的设计只需要考虑这一层的结构和需求,由于良好的封装性,不需要考虑对其下一层次的实现细节。

  • 第二单元

    第二单元的主题为电梯调度,主要是用的为多线程编程思想。其架构设计思想主要为在生产者-消费者模型上添加层次化设计的思想。以第三次作业为例,设计了控制器以及统一等待队列。整体分为两个层次。在第一层次,输入队列作为生产者,统一等待队列作为共享变量,控制器作为消费者。在第二层次,控制器作为生产者,各个调度器的等待队列作为共享变量,电梯作为消费者。第三次作业原本并没有引入顶层的控制器,而是将乘客请求直接发还给输入线程,但是出现了死锁的问题,因此不得不进行了重构。本单元的主要收获为多线程编程的知识,线程安全问题尤为关键,加锁与否,加什么样的锁,加到哪里都是需要仔细思考的问题,一旦某个细节处理不当,就有可能造成整个系统崩溃。

  • 第三单元

    第三单元的主题为依据JML规格编写代码,初步接触契约式编程。这一单元的整体架构基本上由课程给出,自己只需合理地设计网络以实现更高效率的查询。例如,为了提高对连通分支数的查询效率,新建了并查集类,并基于并查集建立了相应的Block类,用以记录相关的属性。到了第三单元,对于面向对象编程思想的运用已经比较自然了,能够自然地考虑到实现工具方法的解耦等。本单元的主要收获为对JML规格的认识以及契约式编程的相关知识。

  • 第四单元

    第四单元的主题为UML解析器,要求对UML模型进行简单的查询和合法性检验。具体的架构在前文已经论述,由于UML模型本身自带结构,故本单元的架构设计思路主要是实现其结构并尽可能地实现高内聚低耦合的设计,将相关联的属性和功能内聚到一个类或者软件包中,将工具方法解耦或者实现新的工具类等等。本单元的主要收获为加深了对UML模型知识的了解,提高了综合运用前几个单元面向对象编程思想的能力。

测试理解与实践的演进

在OO课程中,测试是必要和关键的。由于测试做的不够充分和工具的选择不够合理而导致的错误往往是难以弥补的。同时,在互测环节,拥有一个数据高覆盖率的评测机能够提高互测的效率。

  • 第一单元

    第一单元主要是通过递归下降生成数据,再用PythonSympy库比对结果是否正确。除此之外还需要手动造一些特殊的数据,对模型进行更完善的检测。实际上,在自测和互测环节,许多BUG都是通过手造数据发现的。

  • 第二单元

    第二单元的测试主要靠舍友的评测机,但是由于对线程安全的不够重视导致了第二次作业的惨状。于是掌握了使用JProfiler进行线程安全检测的方法,使用JProfiler能够了解到多线程中占用CPU时间异常的方法,也能够在死锁时检测出相应的对象,从而能够更好地检测多线程安全问题。

  • 第三单元

    第三单元的测试主要就是数据生成以及直接的对拍程序,并辅以针对一些复杂度较高的方法的自测。数据生成器设计时主要考虑如何提高数据覆盖率,在JML规格的指导下,能够根据不同的前置条件构造不同的数据,设计的难度也就稍稍降低了。

  • 第四单元

    第四单元的测试也是数据生成器以及直接的对拍程序。为了实现数据生成器,我参照官方包解析的样例,采用Python实现了相应的UML类图,顺序图,状态图的模型。第一次作业,由于类图的模型较为简单,通过全面地考虑情况,实现了各条指令测试的全覆盖,第二次作业由于时间不足,仅仅通过随机构造数据的方法,只能通过多次的测试以提高覆盖率。第三次作业在考期中,便只是通过手造数据简单检测。

课程收获

  • 对架构设计的重要性有了更深刻的认识。一个优秀的工程或者项目,需要经过多次的迭代开发。一个良好的架构是一切的基础,在拿到需求后,需要认真进行理解并合理地认识到各个板块的需求和作用,给出了合理的架构设计之后再动手写代码。编写代码的过程中再不断思考如何改善架构。架构的可移植性,可扩展性,性能复杂度等等都是需要考虑的。
  • 学习理解了部分面向对象编程的思想。在编写代码的过程中,层次化设计思想,实例化思想,解耦思想等面向对象编程的思想,都在潜移默化地影响着我编写代码的思路。
  • 学习了许多相关的知识。比如多线程编程的知识,JML规格以及契约式编程,UML模型,函数式编程,以及没有在数据结构中学好的各种算法等。
  • 提高了学习能力和抗压能力。每一次刚进一个单元时,只有不到一周的时间,但是却有崭新的知识,前两天反复地阅读指导书以及上各个论坛查询相关资料的情况每一单元都会重现。我曾不止一次熬夜写代码到两三点,也因为1个BUGde不出来而睡不好觉,还有过临近截止时间发现有难以修复的BUG的经历,这些都让我在面对问题时有了更高的韧性和毅力。
  • 积累了写博客的经验。OO课程的博客也算是我第一次写博客的经历,让我在总结一个单元的学习过程的同时也学习了博客的书写要求和技巧等。

改进建议

  • 第一单元的难度设计可以更加合理一些。个人认为,如果代码架构设计的比较合理,第三次作业所花费的时间甚至不到第一次作业的一半。加之许多同学在刚刚完成pre之后面对表达式的解析还是会手足无措,希望能够稍微降低第一次作业的难度,提高第三次作业的难度。
  • 适当提高中测的强度。以第二单元为例,第二单元的中测强度比较弱,难以检测出线程安全的问题。虽然说是个人的测试没有做到位,但还是希望课程组能提供一定的支持或者指导,也可以在指导书中指出建议使用的调试工具,就像第三单元那样。
  • 研讨课增加老师或者助教的指导环节,可以让同学们针对本单元的设计思路或者方法提出问题,在不影响训练效果的前提下指导部分问题。

OO课程终于完结了,整体来说是一个很不错的体验,课程难度的弹性比较大,不同水平层次的学生都能够在这门课程中收获到很多知识和难忘的经历。最后,祝OO课程越来越好!

posted @ 2022-06-28 15:02  Longxmas  阅读(26)  评论(0编辑  收藏  举报