OO第四单元总结博客

OO第四单元总结博客

一、架构设计

1.第13次作业

第13次作业给出的任务是对类图进行一些查询操作。首先,关于UML的各个元素,官方包内都建好了相应的类,因此,我做的事情是建立我自己的MyUmlClass, MyInterface等类,分别对应官方包里的那一些类,并且在自己建的新类里面,加入邻接表,用以表示元素之间的连接关系。

本次作业的UML类图如下:

首先分析每一个小类的各部分字段的意义:

  • MyUmlClass:类
    • father:父类
    • attributeHashMap:每一个类所具有的属性
    • operationHashMap:每一个类所具有的方法
    • interfaceHashMap:每一个类实现的接口
    • associatedClasses:每一个类关联的其他类
    • umlClass:所包含的官方给的uml元素
  • MyOperation:方法
    • parameterArraylist:每一种方法对应的传入参数(后面作业改成了用HashMap存储)
    • returnValue:返回值
    • operation:所包含的官方给的uml元素
  • MyInterface:接口
    • fathers:继承的父接口
    • umlInterface:所包含的官方给的uml元素
  • MyParameter:参数
    • type:种类名称,要么是某一个类名或接口名,要么是基本属性,要么为null表示不合法
    • parameter:所包含的官方给的uml元素
  • MyAttribute:属性
    • type:种类名称,要么是某一个类名或接口名,要么是基本属性,要么为null表示不合法
    • attribute:所包含的官方给的uml元素

在总的大类MyUmlInteraction中,我用各种Hashmap容器来存储各种各样的元素,具体代码如图所示:

private final HashMap<String, MyUmlClass> classHashMap = new HashMap<>();
private final HashMap<String, MyInterface> interfaceHashMap = new HashMap<>();
private final HashMap<String, MyAttribute> attributeHashMap = new HashMap<>();
private final HashMap<String, MyOperation> operationHashMap = new HashMap<>();
private final HashMap<String, MyParameter> parameterHashMap = new HashMap<>();
private final HashMap<String, UmlAssociation> associationHashMap = new HashMap<>();
private final HashMap<String, UmlAssociationEnd> associationEndHashMap = new HashMap<>();
private final HashMap<String, UmlGeneralization> generalizationHashMap = new HashMap<>();
private final HashMap<String, UmlInterfaceRealization> interfaceRealizationHashMap = new HashMap<>();

在构造方法中,我首先遍历一遍传进来的elements,并且根据不同的Elementype来确定不同的元素,并且将不同的UMLElement用我自己的新类包装起来。之后进行一些后续处理,这些处理包括:

  • 遍历attributeHashMap,确定其属性,并且将其插入到MyUmlClass中的用于存储attribute的容器当中。
  • 遍历parameterHashMap,确定其属性、方向,并且将其插入到MyOperation中的用于存储parameter的容器当中,或者设置相应MyOperationreturnValue字段。
  • 遍历generalizationHashMap,确定其属于类的继承还是接口继承,在Hashmap中查找相应的sourcetarget对应的子、父元素,并且将子元素其插入到父元素MyInterface中的用于存储parameter的容器fathers当中(这个容器用以表示父接口),或者设置相应父元素MyUmlClassfather字段。
  • 遍历interfaceRealizationHashMap,在Hashmap中查找相应的sourcetarget对应的类,接口。并且将接口元素其插入到MyUmlClass中的用于存储MyInterface的容器interfaceHashmap当中(这个容器用以表示该类实现的接口)。
  • 遍历operationHashMap,并且将其插入到MyUmlClass中的用于存储operation的容器当中。
  • 遍历associationHashMap,通过两端在classHashMap中找相应的两端元素,如果两端都能找到的话,分别将两端对应的元素插入到对面端的associatedClasses当中。

构造完之后,就可以对各种指令进行求解,在类图已经解析好的情况下,就是一些算法题了。

2.第14次作业

本次作业新增了关于顺序图和时序图的查询,其类图如下:

可以看到关于此次的架构,关于要实现的类MyUmlGeneralInteraction,分成了基本不耦合的三个部分:MyUmlClassInteraction, MyUmlStateChartInteraction, MyUmlCollaborationInteraction。这三部分分别来执行类图、状态图、顺序图的查询,而MyUmlGeneralInteraction分别保存三个类的一个实例,要执行某一个指令的话,就直接通过该指令跳转到相应类中进行查询。而关于这三个类,我们分别有如下架构:

MyUmlClassInteraction

与第13次作业完全一致,不再赘述。

MyUmlStateChartInteraction

同样构建了一些自己的类用以包住相应的官方给的元素,并且新加入邻接表等用以展示图论,这些小类的具体说明如下:

  • State:状态
    • id:所包含元素的id
    • parentId:所包含元素的parentId
    • name:状态名字
    • transitionHashmap:用以存储以该类为出发端的transition的容器
    • 这个类有三个子类,分别为:起始状态MyPseudoState,中间状态MyState,末状态MyFinalState,这三个子类的相应字段表示包住的官方给的uml元素
  • MyStateMachine:状态机
    • stateMachine:所包含的uml元素
    • regionId:状态机所包含region的id,用以帮助找到属于该状态机的状态
    • stateHashMap:用以存储每一个状态机中相应的状态
    • transitionHashMap:用以存储每一个状态机中相应的状态转移transition
  • MyTransition:状态转移
    • from:转移前状态的id
    • to:转移后状态的id
    • eventHashMap:用以存储相应的触发该转移状态的事件
    • transition:包住的官方给的uml元素

在总的大类MyUmlStateChartInteraction中,我用各种Hashmap容器来存储各种各样的元素,具体代码如下所示:

private final HashMap<String, MyStateMachine> stateMachineHashMap = new HashMap<>();
private final HashMap<String, UmlRegion> regionHashMap = new HashMap<>();
private final HashMap<String, State> stateHashMap = new HashMap<>();
private final HashMap<String, UmlEvent> eventHashMap = new HashMap<>();
private final HashMap<String, MyTransition> transitionHashMap = new HashMap<>();

在构造方法中,我首先遍历一遍传进来的elements,并且根据不同的Elementype来确定不同的元素,并且将不同的UMLElement用我自己的新类包装起来。之后进行一些后续处理,这些处理包括:

  • 遍历regionHashMap,通过parentId找到其对应的stateMachine,并且设置stateMachine的regionId字段。
  • 遍历stateHashMap,确定其所属stateMachine,并且将其插入到MyStateMachine中的用于存储state的容器当中。
  • 遍历eventHashMap,确定其所属transition,并且将其插入到MyTransition中的用于存储event的容器当中。
  • 遍历transitionHashMap,确定其所属stateMachine,并且将其插入到MyStateMachine中的用于存储transition的容器当中,并且根据其source找到转移前状态state,将其插入到state用来存储transition的容器当中。

处理完之后,状态图解析完成,之后就是各种查询指令的编写,一些算法题。

MyUmlCollaborationInteraction

这个类表示顺序图,同样,用一些自己设立的新类来包住官方给的umlElement类,这些新类包括:

  • MyLifeLine:生命线
    • incomingMessageMap:用以存储生命线收到的message的容器
    • sentMessageMap:用以存储生命线发出的message的容器
    • lifeline:用来包住官方给的uml元素
  • MyInteraction:交互图
    • lifeLineHashMap:用以存储该交互中参与的生命线lifeline
    • umlInteraction:用来包住官方给的uml元素

在总的大类MyUmlCollaborationInteraction中,我用各种Hashmap容器来存储各种各样的元素,具体代码如下所示:

private final HashMap<String, MyInteraction> interactionHashMap = new HashMap<>();
private final HashMap<String, UmlMessage> messageHashMap = new HashMap<>();
private final HashMap<String, MyLifeLine> lifeLineHashMap = new HashMap<>();

在构造方法中,我首先遍历一遍传进来的elements,并且根据不同的Elementype来确定不同的元素,并且将不同的UMLElement用我自己的新类包装起来。之后进行一些后续处理,这些处理包括:

  • 遍历lifeLineHashMap,通过parentId找到其对应的Interaction,并且将其插入到MyInteraction中的用于存储lifeline的容器当中。
  • 遍历messageHashMap,通过source和target分别找到发出消息和接收消息的生命线,并且将其分别插入到两条生命线的sentMessageMapincomingMessageMap中。

处理完毕后,顺序图解析完成,之后就是各种查询指令的编写,一些算法题。

3.第15次作业

第15次作业架构相对第14次作业架构基本没区别,就是在三大uml解析类中新添相应的方法。只是,我在类图解析器中加入了6的检测合法性方法之后,发现该类代码行数超过500行,因此新建一个类ClassModelCheck,并且向其传入类图解析器中的必要的HashMap。在这个ClassModelCheck中,我实现了六个检测合法性方法。

在uml图已经解析好的情况下,几个有效性检查的编写是一些算法题,因此没有太大改动架构。

二、四个单元架构设计及OO方法理解演进

1.第一单元

多项式求导。这一单元我的架构是在一个表达式中,用一个存储容器来存储Term,这么干是因为Term之间为加减关系,同种关系。而在Term中,我使用了容器来存储Factor,这么干是因为因子之间为乘法关系。而关于Factor,有很多子类,分别代表常数因子、幂因子、三角因子、表达式因子。这一单元主要学习的东西是类的继承、多态等关于面向对象的初步理解,对类的继承、接口使用、工厂模式等有了初步认识。

2.第二单元

电梯运行。这一单元我的架构是设立一个电梯类,一个调度器,一个用来处理输入的生产者。这几个线程共享的变量为等待区请求队列和待执行请求队列。处理输入的线程负责将标准输入变成请求,加入到等待区请求队列中。调度器负责将等待区请求队列搬运到若干个电梯的待执行请求队列中。每一个电梯负责一个待执行请求队列,负责将待执行请求队列中的请求完成,如果不能完成,根据现有进度,生成新的请求,放入到等待区请求队列当中。这一单元的OO方法是多线程,多线程的线程安全需要良好的架构来保证。这一单元,我改了很多次,试图使自己的线程安全。我个人认为自己有一定的面向对象的思想,不过在这一单元还是在保证线程安全的过程中受到不小考验。

3.第三单元

JML。JML的一大作用就是架构设计,设计好架构,定义好每一个方法的前置条件、后置条件。而不关心具体的实现过程。助教的JML代码给我们展示了漂亮的面向对象架构。同时,我关于OO的认识就是规格很重要,在实现代码前,把每一个方法的规格想好,再去实现。

4.第四单元

UML。这一个单元主要做的事情是对UML图进行解析。这一单元所做的事情是关于架构设计的思想提高到整体层面。我们需要通过类图来观察每一个类图之间的关联、依赖、继承等等。这一单元的架构比第三单元要复杂一些,没有前两个单元复杂,需要做好层次管理,不要使某一个类过于复杂。

三、测试理解和实践演进

1.第一单元

构造评测机,随机生成表达式进行黑箱测试。还有就是手动生成边边角角的表达式来进行测试。正确性检查是根据python的sympy这个库来进行检查。这一单元的测试主要是关于程序的整体性测试,通过构造样例来看看有没有出问题,至于问题出现在哪不能立刻发现。同时,由于随机测试并没有覆盖性,导致有很多问题没有查出来。

2.第二单元

跟上一单元一样,都是关于程序的整体性测试,写完进行测试,无法立刻发现问题在哪。我关于测试的理解相较于第一单元并没有特别大的进步。而关于正确性检查方面,我倒是手动根据标准输出,构建电梯类,按照出人进人,手动模拟了一下,看看有没有出现问题。这次的正确性检查倒是更加进一步加深了我面向对象的模块化思想。

3.第三单元

第三单元介绍了单元测试,我也理解到了针对每一个方法做单元测试的必要性。这样,层层推进,每一步完成后都能通过测试看看自己刚写过的方法有没有什么问题。这样能够保证正确率更高,而且在调试过程中也不会太痛苦。关于我进行的具体实践,我的方法是根据每一个方法的规模都构造一些测试样例,并且看一看会不会出现异常。单元测试之后是整体测试,我找了另一个同学进行对拍,来看看有没有出现问题。

4.第四单元

第四单元跟第三单元一样,关于测试方法的理解没有更大深入,实践来看是构造样例来针对具体某一个方法做测试,之后找一些数据来和同学进行对拍。由于本次作业的构造样例的方法比较复杂且关于UML的理解不算透彻,导致我并没有做太多的测试,而且测试的覆盖性不强,强测中也出现了一些问题。

四、课程收获

关于本学期的OO课程,我也有一些收获:

  • 面向对象思想的建立,模块化思想,工厂模式、单例模式、观察者模式等都有了一些泛泛的认识,而关于程序设计的几个原则,比如里氏替换原则,也在研讨课中听同学讲到了,有了一些收获。
  • 关于测试方法的熟练度提升,我已经基本能够对一个程序搭建评测机来进行测试,正确性检查效率更高。
  • 学会了使用git来进行代码的版本管理,使用git对于代码量较大的工程是不可少的东西。我也尝试了进行版本回退等进行代码修改,有一些效果。
  • 熟悉了JAVA语言,并且用这种语言写了不少代码。
  • 认识到了时间管理的重要性别老卡ddl交作业了

五、改进建议

  • 实验课建议能够在提交完代码之后看一看自己能不能通过测试,要不然如果真的放着问题却不知道似乎也不是一件太好的事情。此外,关于非代码的提交,建议可以在实验课结束后公布参考答案。
  • 希望改进第二单元的测试方法,比如可以一个测试点进行多次测试,如果都没有出现问题才算通过此测试点(如果确实这么做就当我没说吧)。因为多线程的线程安全被测出问题并不是一个每次都会发生的事情。这样会有很多同学因为自己通过了强测和互测而认为自己程序没有问题(比如说我)。
  • 希望能够在实验课后公开每一次实验的指导书,这样课上没有搞懂的事情也可以课下尝试理解一下。
posted @ 2021-06-26 19:25  徐睿霄  阅读(54)  评论(0)    收藏  举报