OO 第四单元总结

OO 第四单元总结

本单元架构

本单元是uml图的解析与查询,主要方法是对uml元素进行自己的抽象,保留必要的信息,而由于uml图是乱序的,并且时间比较充分,所以我在设计的时候根据uml元素之间的逻辑关系进行了4轮扫描,将所有需要的元素存入HashMap<String, elment>当中,然后初始化,方便后续的查询。下面分块介绍初始化操作。

类图部分

重要类介绍

  • MyClass

    • 存储umlClass,可以查询基础信息

    • 内部维护一个father变量作为父类,若为空则没有父类

    • 内部维护一个HashSet<MyInter>存储实现的接口,维护一个HashSet<UmlAttribute>存储属性,维护一个ArrayList<MyOperation>存储操作

    • 此部分是第三次作业内容,维护一个HashSet<String>HashSet<AttributeClassInformation>,存入所有的属性名和对端的AssociationEnd名,如果新增加的name字段有重复,直接加入HashSet<AttributeClassInformation>待抛出

  • MyInterface

    • 存储umlInterface,可以查询基础信息

    • 内部维护一个ArrayList<MyInter>变量作为父类接口,使用ArrayList方便迭代

    • 内部维护一个HashSet<UmlAttribute>存储属性

  • MyOperation

    • 存储umlOperation,可以查询基础信息

    • 内部维护一个ArrayList<UmlParameter>,存储所有的变量

    • 内部维护一个ArrayList<NameableType>存储类型,并且用字典序将Type排序,方便查找是否有重复操作

扫描过程

  • 第一轮扫描

    扫描所有的AssociationEnd、类和接口,将所有信息存入HashMap<String,Element>当中,并且分别以nameid作为key,扫描的同时判断是否有重名的类,有重名的类直接放入HashSet<String> 当中,查询的时候直接抛出异常。

  • 第二轮扫描

    扫描所有实现接口、继承关系、属性和操作,存入响应的父类(包括MyClass、MyInterface)当中,在公共的扫描类中也将其存入。

  • 第三轮扫描

    扫描所有的关联关系和参数变量,将参数变量加入操作当中,将关联关系的对端加入响应的类当中,并且在扫描结束之后将操作中的参数按字典序排序,并且检查是否有非法类型。

  • 检查

    • R001

      注意字段为空的定义,可以先判断是否为null然后使用trim方法判断

    • R002

      在添加的时候就直接判断是否重名,重名的话保存键值对

    • R003、R004

      使用dfs判断是否存在重复继承或环

    • R005

      结束扫描之后判断接口属性是否为public

顺序图部分

重要类介绍

  • MyIneraction

    • 存储了基础UmlInteraction,方便查询基础信息

    • 使用HashMap<String, MyLifeline>分别以name和id为键存储生命线,并且将重名的使用HashSet<String>存储

  • MyLifeline

    • 将所有接受到的消息存储进ArrayList<UmlMessage>,方便进行R007的判断

    • 内部维护一个found和lost变量,存储相应的消息

扫描过程

  • 第一轮扫描

    扫描所有顺序图,和类一样存储顺序图,存储在HashMap当中,并且同时判断是否有重名,将重名的顺序图单独存储

  • 第二轮扫描

    扫描所有生命线和终结点,同样使用HashMap存储

  • 第三轮扫描

    扫描所有消息,将消息加入接受信息的生命线,同时维护生命线的found和lost变量

  • 检查

    • R006

      检查生命线和属性的对应关系,注意生命线的父亲的父亲和属性的父亲对应的是一个

    • R007

      检查生命线被摧毁后是否接到新的消息

状态机部分

重要类介绍

  • MyStateMachine

    • 使用start变量作为起点状态,使用HashMap<String,Mystate>,以id为键值,存储其他状态集合

    • 使用HashSet<String>分别存储所有名字和重名的状态名

    • 维护isCircle变量,记录改状态机是否由起点到终点可达

  • MyTransition

    • 存储基础信息,包括guard、source和target

    • 使用ArraList<String>存储触发事件,不使用Set是因为防止重名

  • MyState

    • 分为三个类型,START、END、COMMON,使用type存储状态类型。

    • 使用ArrayList<MyState>存储所有可以达到的状态

    • 使用HashMap<String, ArrayList<MyTransition>>存储到达指定状态的所有迁移,由于迁移可以有许多个,所有使用ArrayList作为value

扫描过程

  • 第一轮扫描

    和顺序图和类图一样,扫描、存入状态机,以及重名的状态机

  • 第二轮扫描

    扫描所有的状态并存入,并且在扫描类里需要保存id信息

  • 第三轮扫描

    扫描所有的状态迁移,存入响应起点和终点状态

  • 第四轮扫描

    扫描所有的状态触发事件存入相应的状态迁移当中

  • 检查

    • R008

      根据type和存储的迁移状态判断是否为空判断

    • R009

      将所有相同状态迁移的所有触发事件整合判断

在扫描完成之后,对所有状态机进行判断,bfs判断是否起点和终点可达

整体架构如下

 

单元思想和方法递进

第一单元

  • OO思想

    第一单元初次接触oo思想,主要的能力提升是将具象的表达式,符号,数字、函数等等抽象的过程,另外在生成因子的时候学习倒了使用了工厂化的设计模式。

  • 整体架构

    主要使用的是递归下降的方法,并且经过三次作业的迭代架构愈发完整,正确性也尚可,主要是第三次作业为了提升性能进行了大规模重构导致出现了bug。

  • 不足之处

    第一单元由于对题目的理解不够,有些闭门造车。前两次作业的架构虽然正确性尚可但是整体有些冗杂,特别是数据结构用的很差,导致优化起来非常困难,第三次作业的时候大规模重构,性能提升了很多,架构也优化了很多,但是由于时间问题导致做优化的时候有一些小bug。

  • 测试

    本单元是我第一次写自动化测试脚本,自动化脚本还有一些不完善的地方,并且接着上个学期计组造数据的经验,完成了较为完善数据生成器,能够自动化生成求和函数和自定义函数,测试时以生成的数据为主,进行覆盖性较强的功能测试,再加上一些手动构造的针对性数据,如:

    sin(sum(i,0,2,sin((i*x))))

    sum(i,123456789123456780,123456789123456789,i)

    sin(x)**2+cos((-x))**2

    ((((((x+1))))))**8

    ((((((x)+1)+1)+1)+1)+1)

第二单元

  • OO思想

    学习、采用了生产者消费者模式,将电梯请求集中,然后再使用调度器分发。

  • 整体架构

    整体架构如下

    img

    本单元整体架构比较简单,最重要的问题是要把握好共享资源的访问条件。前两次作业采用的是Java已经封装好的线程安全类,始终没有出过线程安全问题,第三次作业为了实现电梯的加权分配,加入了调度器和自己封装的安全类,并且采用信号量操作控制电梯的开关。

  • 不足之处

    这单元的不足之处其实不在于oo上,而是在于os上,当时由于os理论课摆烂,导致前期很多课都没听,但是在电梯单元第三次作业又使用了信号量控制电梯开关,对pv操作和信号量知识的缺乏导致电梯单元出了唯一一个bug。

  • 测试

    本单元测试的一大难点是评测机的构造,这个甚至和电梯本身的复杂度也不遑多让。因为第二单元无法使用直接对拍,所以需要构造评测机。评测机的本质上是一个状态机,在内部根据输出模拟电梯运行的过程,包括乘客上下,电梯移动,电梯状态改变时判断是否有超载,楼层瞬移,楼层非法,乘客未到达目的地等问题。数据生成方面以随机生成为主,最主要的是需要一些时间的控制。

第三单元

  • 思想与架构

    到了第三单元的时候OO思想已经比较完善,所以写起来比较轻松已经能够将jml的元素比较好的抽象,整体的架构就是将所有的图元素都使用HashMap维护。但是我感觉这个单元最主要的收获是复习了图算法、并查集算法。

  • 测试

    第三单元的数据大体上可以分为增加信息类型的数据(例如ap、ar、am等),以及发送、查询类型的数据(qv、qbs等),为了能够正确的查询信息,避免异常,所以需要将已经增加的信息存在数据生成器内部的容器当中,然后针对性的生成查询,发送消息的数据。

    本单元测试主要采用对拍,对拍的程序我也尽量完善了,比如加入了日志的功能,使用命令行编译java等等。

第四单元

这个单元是最迷的一个单元,整体架构前文已经分析过,在此就不过多赘述,但是感觉本单元的收获相对较少。

测试上数据构造和对拍和第三单元也大同小异。

课程收获

  • OO思想

    这应该是学习OO这门课的本质,从上个学期开始学习Java,到这个学期使用OO思想完成了四个单元的作业,再回看最开始学习Java的代码,会发现整个的实现方式有了巨大幅度的提升,包括代码风格,OO思想,以及对Java标准库的使用都变得比较得心应手,对于具象事物的抽象能力,以及设计模式的使用也有巨大的提升。

  • 测试能力

    本学期另一大提升就是构造评测机的能力、生成数据的能力。评测机的典型就是第二单元的评测机,由于多线程的不确定性,所以第二单元的评测机只能通过使用状态机判断状态是否合法完成,完成了评测机是对我能力的一个巨大的提升。另一大提升就是自动化脚本的能力,上个学期的时候,由于还不会python,所以计组的测试困难还比较大,但是这个学期的oo课程下来我对自动话测评已经有了自己的一套思路。

  • 架构能力

    从性格来看,我个人做事比较随意,所以在第一单元的时候架构设计的不是特别好,但是第二单元之后,我完成作业之前都会仔细的思考如何完成本次作业,尽量在写之前就将所有的问题考虑到,并且反复思考程序架构,所以第二单元的作业反而完成起来比较轻松,并且正确率和性能都较好。

课程建议

  • 关于第三、四单元

    个人认为前两个单元是OO课做的比较好的两个板块,虽然难度较大,但对我的能力提升也比较大。但是第三和第四单元我并没有体会到能力的提升,反而是第三单元的复习了很多算法的东西,但是我认为这个有点喧宾夺主了,算法应该不是OO课想强调的东西。

    还有第四单元,可能是我个人理解能力的问题,指导书也给我和一起的几位同学造成了较大的困扰,并且据我的理解,uml图在我们之后的学习当中可能接触的机会也不多,以及本单元对我们其他方面的能力提升是比较有限的。

    所以依我的愚见,第三、四单元可以进行一定程度的改革,甚至直接采用其他主题也未尝不可,例如在OO总结课上提到的MIT的考核方式,即两个较大的工程项目,课程组也可以考虑在同学们已经初步了解OO思想和方法之后完成一个相对较大较完善的工程项目。

  • 电梯单元

    电梯单元可以适当增加电梯运行时间的梯度,例如快速电梯和慢速电梯之间可以适当增加间隔时间,这样一个好的调度算法能够容易获得更好的分数,线程的并发程度也可以适当增加。

当然,我也只是站在我个人的角度提出建议,具体的实施方法和完成难度课程组的了解程度肯定在我之上,我也很尊敬各位老师和助教,希望OO课程能变得越来越好。

最后

在本文的最后,感谢所有和我对拍、给出建议的同学,以及给我帮助的各位助教。

posted @ 2022-06-29 14:21  shliba  阅读(63)  评论(1编辑  收藏  举报