OO第四单元与全课程总结

一、作业代码架构设计

1.第一次作业

  • 作业类图如下:

  • 具体架构设计:

    • 第一次作业的全部查询工作都是和类图有关,需要解决的主要问题就是如何解析原有UML类图数据的结构,并形成自己便于查询的结构。所以,可以看到,我在这次作业中的MyUmlInteraction类中,设定了包括UML类、UML亲属关系、UML继承关系、UML关联关系、UML实现关系等共6个HashMap容器,这些容器将原UML类图具有的这些关系分类存储,并且都是以UmlElement的id作为key,这样也能保证对相关关系的查询的唯一性和便捷性。
    • 但是,这样的数据存储设计就导致全部的查询操作的具体实现细节都被MyUmlInteraction类所包括,这就使得这个类的内容过度复杂。以至于我在刚刚写完这个类后,发现checkstyle的文件总行数要求500行都无法满足,只得将部分重复的查询操作修改成一个函数,并多次调用,最终才满足了文件的行数要求。
    • 在具体方法的架构设计方面:在构造方法中通过遍历,将题目需要的数据提取出来,并存进相应的HashMap容器中;而在查询方法中,通过搜索、查找等方法向已经存储好需要的信息的HashMap提出需求,并通过HashMap查询结果进行下一步操作。
  • 作业bug分析:

    • 本次作业强测翻车了,只得了40分,出现了两个bug,主要原因都是因为自己在处理UML类图部分内容的操作上不够仔细,bug内容大概如下。

      • 实现getClassOperationCount方法的过程中,没有注意到抛出的多种异常间的顺序问题,导致我的程序并未按照题目希望的顺序抛出相应的异常。
      • 实现getInfomationNotHidden方法的过程中,没有注意到在相应的AttributeClassInformation中父类属性对应的类应该还是父类,而我却错误的存储为子类。

2.第二次作业

  • 作业类图如下:

  • 由于上面这个类图实在过于复杂,所以提供了以下简化类图:

  • 具体架构设计:

    • 第二次作业相对于第一次作业新添加了UML顺序图和状态图的相关信息查询需求,所以我们仍然只需要在理解UML顺序图和状态图的具体结构和内容后,进行自己的解析与重新存储。但是,由于第一次作业我所选择的数据存储结构过于粗暴,导致了MyUmlGeneralInteraction这个类过于复杂,所以本次作业我对自己的程序的数据存储结构进行了重构。

    • 通过定义有关包括UML关联、UML属性、UML类、UML操作、UML参数、UML实现关系、UML继承关系、UML接口、UML时间线、UML信息、UML画布、UML状态、UML状态机、UML后继关系、UML转移在内的类,可以将原有UML图中所需的各式各样的信息重新存储到这些类中,并且通过这些类提供的统一接口方法,可以很大程度上降低MyUmlGeneralInteraction这个类实现相应查询操作的内容的复杂度,这样也就解决了第一次作业产生的文件行数过多的问题。

    • 以下为部分类对应存储的具体信息

      • 新定义类 原本存储数据类 存储信息结构
        MyUmlAssociation UmlAssociation、UmlAssociationEnd 根据任何一个存在关联关系的对象id存储其对应的全部的关联对象的id
        MyUmlElementAttribute UmlElement 根据某个特定的类和接口的id存储其全部的属性的id
        MyUmlElementOperation UmlElement 根据某个特定的类和接口的id存储其全部的操作的id
        MyUmlElementParameter UmlElement 根据某个特定的类和接口的id存储其全部的参数的id
        MyUmlElementRealization UmlRealization 根据某个特定的类的id存储其所实现的全部的接口的id
        MyUmlGeneralization UmlGeneralization 根据某个特定的类和接口的id存储其所继承的全部类或者接口的id
        MyUmlElementClass UmlElement 根据这个类的id存储其UmlElement部分的内容
        MyUmlLifeline UmlLifeline 根据某个region的id存储其所具有的全部UmlLifeLine的id
        MyUmlState UmlState 根据这个UmlStateMachine的id存储其所具有的全部UmlState的id
    • 在具体方法的架构设计方面:本次作业依然通过构造方法中的循环遍历获取UML图中已经给出的信息,并在重新整合后,形成便于查询的信息结构 ,最终存储到相应的新定义的类中;在查询方法中,通过调用存储所需信息的新定义的类所给定的统一接口方法,并对方法返回的结果进行处理后,即可获得查询最终所需的信息。

  • 作业bug分析:

    • 吸取了第一次作业的教训,在写完本次作业后,我对MyUmlGeneralInteraction类中的方法进行了对拍,排除了一些因为空名字产生空对象的简单bug,最终没有在强测中产生bug。

3.第三次作业

  • 作业类图如下:

  • 同样由于上述类图过于复杂,提供以下简化类图:

  • 具体架构设计:

    • 第三次作业相对于第二次作业新添加了对UML类图、顺序图和状态图的合法性检查,实际上相当于对原有的数据存储结构提出了几个新的查询,并对查询结果进行判断。由于不涉及新的数据存储结构的引入,所以本次作业我是在第二次作业的基础上完成的。
    • 本次作业中,我只添加了UML中AssociationEnd这部分新的信息到原有的数据存储结构中,其余存储的数据已经可以满足各类合法性检查所需。
    • 在具体方法的架构设计方面:本次作业中,我对于相应的合法性检查定义了相应的类,并提供了相应的检查接口,既便于MyUmlGeneralInteraction中存储相应信息的对象的传入,也能够提供统一的合法性检查返回结果。通过调用合法性检查类中的检查方法,并对传入的已经存储好的信息进行现场处理,即可获得最终的合法性检查结果。
  • 作业bug分析:

    • 在完成本次作业后,我依然通过对拍进行程序的正确性检查,最终并没有在强测中出现bug。
    • 这里提供几个检查过程中出现的常见错误:
      • 注意对名称为空的对象的处理。
      • 注意某个对象的parent不存在的情况。

二、作业架构设计及OO方法理解的演进

  • 经过这个学期OO课程的学习,我不仅在知识层面上了解到java对面向对象、多线程、规格化设计以及UML模型等内容,也在思路层面上对作业架构设计和OO相关方法有了深层次的理解。

  • 第一单元

    • 本单元主要内容是多项式求导,但是由于刚刚接触面向对象和java语言,每次作业设计过程也并没有考虑其可扩展性,所以在这一单元的后两次作业中我都进行了重构。在这一单元的前两次作业中,由于不涉及递归项的存在,可以用正则表达式直接读入多项式,然后再将不同类型的项进行抽象。但是最后一次作业中,由于涉及递归项,导致我必须手动处理部分输入数据,这就导致我的架构设计非常混乱并且复杂度较高,而在读入处理后的项的存储架构我也选择的过于复杂,比如将乘除项、幂函数、三角函数都区分开来进行特殊的处理,以至于最后都难以进行化简合并等操作。
  • 第二单元

    • 本单元主要内容是多线程,题目则是电梯的调度。由于本单元恰好学习了生产者和消费者模型,我在这个单元的作业中也采用了这个模型来处理问题。吸取了第一单元反复重构作业代码的教训,我在这个单元的第一次作业中对程序的可扩展性进行了相对深层次的考虑,最后选择了输入线程、调度线程以及电梯线程共同工作的架构,同时将缓存需求队列和全部电梯作为线程间的公共资源。通过输入线程将需求存入缓存队列,调度需求分发缓存队列中的需求到电梯,电梯线程控制电梯的运行和电梯内需求的满足。通过这个可扩展的架构,我成功的完成了这三次作业并且没有重构代码,也算是相对有所进步。此外,本单元线程还有很重要的两点:线程安全问题和电梯效率问题。这两个问题也是我们应当在设计程序架构的过程中要注意考虑的内容。而通过本单元的学习,我也大致掌握了通过synchronized关键字来保障线程运行过程中的安全,以及通过合理调度来提升线程间工作的性能的主要方法。
  • 第三单元

    • 本单元主要内容是JML规格化设计。个人理解,本单元更重要的部分不在于你如何实现最终的程序方法,应当更加注意理解JML在我们对程序进行设计过程中的作用。尽管可能因为JML语言并不完善而在实际工作中难以用到,但是它规格化的思想我们却可以在实际的程序设计过程中使用。通过本单元的学习,我还认识到,程序的设计和实现可以是完全分离的两个过程,不应当让设计部分的内容限制自己实现程序的思路。
  • 第四单元

    • 本单元主要内容是UML模型的解析。通过对原有的UML模型中的数据进行解析,并将有用的UML接口、UML属性、UML方法、UML参数、UML继承关系、UML关联关系、UML实现关系等信息重新组合并存储到新定义的类中,也通过新定义的类提供的统一的查询接口,实现对UML模型中继承、关联、实现等一系列关系的相应对象的快速定位。
  • 总结

    • 通过这四个单元作业的练习,我对面向对象方法中层次化的封装式设计有了更深层次的理解。
    • 通过封装式设计,我们可以实现每个类在程序设计的过程中就是一个独立的个体与层次,而将其相应的属性和功能恰当的分配给特定的类,以避免类功能的冗余,也降低了这些个体间的耦合度。
    • 而通过多层次的继承与实现关系,我们可以让程序具有更强的可扩展性,减少重构代码的次数,这也是面向对象设计中的一个重要方面。

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

  • 第一单元

    • 在本单元的课下测试中,我采用了两个方面的测试内容:一方面使用python生成较大的随机测试数据,同时通过sympy库和自己的程序运行结果进行对拍;另一方面采用手动构造边界数据,实现对程序边界功能正确性的测试。
  • 第二单元

    • 本单元主要内容是线程。由于线程难以进行手动测试,所以本单元我只采用了程序验证电梯运行过程正确性的测试方法。通过python的subprocess库,可以实现随机测试数据的定时输入,然后通过另外一个验证程序分析作业程序的输出,以实现对电梯运行过程正确性的验证。
  • 第三单元

    • 本单元学习了JUnit的测试方法,所以我采用了手动构造复杂数据,并通过JUnit进行程序的单元测试的测试方法。JUnit可以实现对测试覆盖率进行统计,所以我也根据这个覆盖率的反馈不断完善自己手动构造的数据,以实现更高覆盖率的测试。
  • 第四单元

    • 本单元UML类图难以通过自己的程序进行随机数据的生成,所以我的数据还是通过starUML画图并导出而获得。同样采用了JUnit的测试方法,对每个查询和合法性检查进行单元测试,逐步验证每个方法功能上的正确性。
  • 总结

    • 通过这四个单元对测试的不断实践,我在程序的测试层面也有了更加深层次的体会。虽然对拍可以实现对大量自动生成的随机数据的测试,但是边界数据还是需要手动构造。此外,本学期所学习到的JUnit测试,让我认识到单元测试的优越性:它可以实现层次化的测试,能够更加准确定位到程序的错误。所以对于面向程序的测试,我们应当通过多种方法共同验证程序的正确性。

四、课程收获

  • 经过一学期对面向对象课程的学习和实践,我在以下几个方面有所收获:

    • 理解了面向对象的一些简要思想,并体会到对象封装、分担任务以及通过继承、实现等层次方式提高程序的可扩展性的巧妙设计。
    • 理解了多线程程序的相关设计基础知识,并掌握了通过正确使用锁来实现多线程同步和安全的重要方法。
    • 掌握了JML语言的基础知识,能够读懂JML设计,并能够通过JML工具链进行相关正确性验证。
    • 掌握了UML模型的相关概念,能够通过starUML对现有的程序模型进行总结和精简,也同时理解了UML模型的信息架构。
    • 掌握了多种验证程序正确性的测试方法,其中更是新学习到了JUnit的单元测试方法,懂得如何通过测试覆盖率的反馈进行全面的测试和验证。

五、具体改进建议

  • 通过这个学期对本课程的学习,大致有以下三个具体改进建议:

    • 希望能在实验课后得到部分反馈信息。对于部分实验课,需要学生对某些新知识内容有所了解,但是如果完全没有反馈,就让学生很难判断自己对这部分知识的掌握与理解情况。
    • 希望部分课上概念内容能够更加结合实践。在JML和UML这两个单元,课上视频经常涉及一些概念性内容,但是只在课上听一遍往往会难以真正理解这些概念内容,而课下也同样没有对这部分的概念实践的相关指导,以至于难以体现出这些课上概念理论内容的实际重要性。
    • 希望研讨课的内容能够经过更加全面的筛选。个人感觉,部分研讨课的内容并不是具有很高程度的参考价值,只是部分同学对课上理论学习内容的复述。

六、线上OO课程学习体会

  • 由于疫情的缘故,本学期的OO课程完全是依照网络教学展开。但是,由于OO这门课程本身内容就比较完善,包括作业、实验在内的内容都是通过评测网站上来进行,所以个人感觉课程质量依然很高。平常的作业依然给人带来一种压迫感,实验课的限时内容也是让人感到很紧张。比较受影响的就是理论课程和研讨课部分,但由于大部分课程视频以及研讨内容准备充分,所以这两部分对课程学习的影响并不是很大,依旧让我感觉很有收获。
  • 总之,个人感觉,尽管是在线上教学,依然收获颇丰。而OO这门课的老师和助教们也都非常认真负责,为让我们学生有一个更好的理论学习和实践环境而在不断努力,在此也由衷感谢各位老师和助教们对这门课的所有付出与努力。

OO第四单元与全课程总结的更多相关文章

  1. OO第四单元总结及课程总结

    OO第四单元总结及课程总结 一.前言 紧张刺激的OO“昆仑课程”接近尾声,经过一个学期的学习,我的收获和感触颇多,借此博客作业的机会,对自己OO这门课程做一个总结.本博客主要有以下五个方面,一是第UM ...

  2. OO第四单元总结与课程总结

    OO第四单元总结与课程总结 第四单元作业架构设计 总体分析:本单元作业的需求集中于对UML类图进行查询.对于查询操作来说自然的想法是提前预见到需要查询的内容,在一开始就采用适当的数据结构将必要的信息进 ...

  3. OO第四单元——基于UML的UML解析器总结&OO课程总结

    OO第四单元--基于UML的UML解析器总结&OO课程总结 前言:一学期愉快(痛苦)的OO课程学习结束了,OO几个单元作业都各有特色,实验也各有特色,仔细回味起来,不再是单纯的敲代码(但自己还 ...

  4. oo第四单元作业总结暨课程总结

    oo第四单元作业总结暨课程总结 一.本单元作业架构设计 本单元需要构建一个UML解析器,通过对输入的UML类图/顺序图/状态图的相关信息进行解析以供查询,其中课程组已提供输入整体架构及输入解析部分,仅 ...

  5. 「BUAA OO Unit 4 HW16」第四单元总结与课程回顾

    「BUAA OO Unit 4 HW16」第四单元总结与课程回顾 目录 「BUAA OO Unit 4 HW16」第四单元总结与课程回顾 Part 0 第四单元作业架构设计 架构设计概要 AppRun ...

  6. 【OO学习】OO第四单元作业总结及OO课程总结

    [OO学习]OO第四单元作业总结及OO课程总结 第四单元作业架构设计 第十三次作业 第十四次作业 总结 这两次作业架构思路上是一样的. 通过将需要使用的UmlElement,封装成Element的子类 ...

  7. OO第四单元

    OO第四单元总结 第四单元架构设计 第一次作业 uml类图 这次作业我采取的基本思路就是根据指令来建造一个简易的类图,用于查询,其中umlclass中包含了umlAttraibute,umlOpera ...

  8. OO第四单元及学期总结

    OO第四单元及学期总结 第四单元两次作业的架构设计 第一次作业 类图: 树形结构:使用Operation类管理UMLOperation以及parent为该UMLOperation的参数(UMLpara ...

  9. OO第四单元(UML)单元总结

    OO第四单元(UML)单元总结 这是OO课程的第四个单元,也是最后一个单元.这个单元只有两次作业,相比前三个单元少一次作业.而且从内容上讲这个单元的作业目的以了解UML为主,所以相对前三个单元比较简单 ...

随机推荐

  1. Python镜像源集合——镜像源更改方法

    python在线安装库时会较慢,那是因为python的默认镜像源在国外,因此会慢:而国内有很多可以用的python镜像源,将python镜像源更改为国内的,则可以大大加快python库的安装速度. 1 ...

  2. Windows开发常用快捷键

    毕业后一直在从事Windows开发工作,掌握些常用的Windows快捷键可以大大的提升工作效率,同时还能秀一波操作.本文记录在工作中常用的Windows快捷键,以及VS常用快捷键.掌握了这些键盘操作, ...

  3. 手把手教你Spring Boot2.x整合kafka

    首先得自己搭建一个kafka,搭建教程请自行百度,本人是使用docker搭建了一个单机版的zookeeper+kafka作为演示,文末会有完整代码包提供给大家下载参考 废话不多说,教程开始 一.老规矩 ...

  4. Python学习笔记 CH1-4:从入门到列表

    Python CH1 环境准备 因为已经有了C/C++.Java的基础,所以上手很快. 参考书:Eric Matthes -<Python编程 从入门到实践> 环境准备:python3.P ...

  5. [SNOI2019] 通信

    一.题目 点此看题 二.解法 一看就是傻逼补流模型,不会真的有人这个图都建不出来吧 别走啊,我不阴阳怪气了,如果你不知道怎么建这里有图嘛(思路来源是餐巾计划问题): 其中标红的边数量级很大,因为 \( ...

  6. 认清 React 的useState逻辑

    useState运行过程解析 function App() { const [n, setN] = useState(0); //使用 myUseState() return ( <div> ...

  7. 图解双链表(Java实现)

    原创公众号:bigsai 文章已收录在 全网都在关注的数据结构与算法学习仓库 前言 前面有很详细的讲过线性表(顺序表和链表),当时讲的链表以但链表为主,但实际上在实际应用中双链表的应用多一些就比如Li ...

  8. 如何在O(1)时间复杂度获取栈中最大值和最小值

    问题描述: 如何在O(1)时间复杂度获取栈中的最大值和最小值? 问题分析: 普通栈规定的push(入栈).pop(出栈).peek(查看栈顶)等操作都只能在栈顶上操作,如果栈中元素是有序的,那么我们就 ...

  9. 关于在forEach中使用await的问题

    先说需求,根据数组中的ID值,对每个ID发送请求,获取数据进行操作. 首先肯定考虑用forEach 或者 map对数组进行遍历,然后根据值进行操作,但是请求是个异步操作,forEach又是一个同步操作 ...

  10. B. 【例题2】移位包含

    解析 判断是否是子串,可以将这个一个环 #include <bits/stdc++.h> using namespace std; int f = 0; string a, b; int ...