OO2021-第四单元作业总结及课程总结

OO2021-第四单元作业总结及课程总结

 

1.总结本单元作业的架构设计

(1)第一次作业

本次作业,需要完成的任务为实现一个UML类图分析器UmlInteraction,学习目标为UML入门级的理解、UML类图的构成要素及其解析方法

本次作业所实现的6个类如图所示:

 

各类的功能如下:

类名作用
Main 主函数
MyAssociation 对UmlAssociation及其对应的UmlAssociationEnd进行封装
MyClass 对UmlClass及其对应的UmlAttribute、MyOperation、MyInterface、对端的UmlAssociationEnd等进行封装
MyInterface 对UmlInterface及其对应的UmlAttribute等进行封装
MyOperation 对UmlOperation及其对应的UmlParameter进行封装
MyUmlInteraction 题目要求

具体实现的思路是通过对UmlElement... elements进行2次遍历,将各种元素处理好之后,调用相关的查询方法即可。应当注意的是元素处理的顺序,第一次处理UmlClassUmlInterfaceUmlOperationUmlAssociation,建立对应的MyClassMyInterfaceMyOperationMyAssociation,第二次处理UmlParameter(加入对应的MyOperation)、UmlInterfaceRealizationUmlGeneralizationUmlAttribute(加入对应的类或接口)、UmlAssociationEnd(加入对应的MyAssociation)。然后再进行最后一次处理(针对对应的HashMap遍历),把MyOperation、对端的UmlAssociationEnd加入对应的类,考虑到查询的时候输入的是类名,又把之前以Id作为key的存储MyClass的HashMap用Name作为key存了一遍,方便针对类名的查询。

(2)第二次作业

本次作业,在上次作业基础上,扩展解析器,使得能够支持对UML顺序图和UML状态图的解析

本次作业所实现的15个类如图所示:

 

各类的功能如下:

类名作用
Main 主函数
MyAssociation 对UmlAssociation及其对应的UmlAssociationEnd进行封装
MyClass 对UmlClass及其对应的UmlAttribute、MyOperation、MyInterface、对端的UmlAssociationEnd等进行封装
MyInteraction 对UmlInteraction及其对应的MyLifeline进行封装
MyInterface 对UmlInterface及其对应的UmlAttribute等进行封装
MyLifeline 对UmlLifeline及其对应的UmlMessage进行封装(UmlMessage分为in、out两类,分开存储)
MyOperation 对UmlOperation及其对应的UmlParameter进行封装
MyRegion 对UmlRegion及其对应的MyState进行封装
MyState 对UmlState/UmlFinalState/UmlPseudostate及其对应的MyTransition等进行封装
MyStateMachine 对UmlStateMachine及其对应的MyRegion进行封装
MyTransition 对UmlTransition及其对应的UmlEvent(trigger)进行封装
MyUmlClassModelInteraction 题目要求
MyUmlCollaborationInteraction 题目要求
MyUmlGeneralInteraction 题目要求
MyUmlStateChartInteraction 题目要求

(由于本单元作业中,UmlStateMachineUmlRegion一一对应,所以也可以改为MyStateMachine直接管辖MyState。我写的时候还是按照UmlStateMachine-UmlRegion-UmlState的等级实现的。)

本次作业中,为了减少针对所有元素进行的遍历,在MyUmlGeneralInteraction里建立属性private HashMap<String, ArrayList<UmlElement>> elementMap,然后在初始化public MyUmlGeneralInteraction(UmlElement... elements)里进行:

elementMap = new HashMap<>();
for (UmlElement element : elements) {
   elementMap.computeIfAbsent(
           element.getClass().getSimpleName(), k -> new ArrayList<>()).add(element);
}

之后对于MyUmlClassModelInteractionMyUmlCollaborationInteractionMyUmlStateChartInteraction的构造,只需传入elementMap,处理所需元素对应的ArrayList即可(应该先判断一下输入数据中有无该类元素),比如:

if (elementMap.containsKey("UmlRegion")) {
   for (UmlElement item : elementMap.get("UmlRegion")) {
       MyRegion newOne = new MyRegion((UmlRegion) item);
       myRegionHashMap.put(item.getId(), newOne);
  }
}

(3)第三次作业

本次作业,在上次作业基础上,对模型进行有效性检查

本次作业所实现的17个类如图所示:

 

各类的功能如下:

类名作用
ClassModelCheck 结构与MyUmlClassModelInteraction相同,实现6个检查方法
Main 主函数
MyAssociation 对UmlAssociation及其对应的UmlAssociationEnd进行封装
MyClass 对UmlClass及其对应的UmlAttribute、MyOperation、MyInterface、对端的UmlAssociationEnd等进行封装
MyInteraction 对UmlInteraction及其对应的MyLifeline进行封装
MyInterface 对UmlInterface及其对应的UmlAttribute等进行封装
MyLifeline 对UmlLifeline及其对应的UmlMessage进行封装(UmlMessage分为in、out两类,分开存储)
MyOperation 对UmlOperation及其对应的UmlParameter进行封装
MyRegion 对UmlRegion及其对应的MyState进行封装
MyState 对UmlState/UmlFinalState/UmlPseudostate及其对应的MyTransition等进行封装
MyStateMachine 对UmlStateMachine及其对应的MyRegion进行封装
MyTransition 对UmlTransition及其对应的UmlEvent(trigger)进行封装
MyUmlClassModelInteraction 题目要求
MyUmlCollaborationInteraction 题目要求,新增1个检查方法
MyUmlGeneralInteraction 题目要求
MyUmlStandardPreCheck 题目要求
MyUmlStateChartInteraction 题目要求,新增1个检查方法

其中,负责类信息查询的MyUmlClassModelInteraction和负责类信息预检查的ClassModelCheck,属性结构与构造方法基本一致,仅仅是分工不同。(为了代码风格检查,每个类不得超过500行)

在构造MyUmlStandardPreCheck时,传入MyUmlGeneralInteraction中构造完毕的ClassModelCheck(R001-R006)、MyUmlCollaborationInteraction(R007)、MyUmlStateChartInteraction(R008),针对不同检查调用不同方法即可。

 

2.总结自己在四个单元中架构设计及OO方法理解的演进

(1)第一单元

第一单元的任务是表达式求导。

在第一单元,我主要采用了根据不同运算符号将整个表达式进行拆分,然后构建表达式树的架构设计。具体而言,构建表达式树的过程为,根据加减号将输入字符串处理为各个项,再通过乘号将各个项处理为各个因子,最后处理各个因子,构造不同的常数、幂函数、三角函数、表达式因子(需要递归处理)。

之前接触的编程任务都是面向过程的,这一单元让我切实感受到了“面向对象”的含义。即,我们考虑的不再是“求导”这一过程本身,而是表达式因子、三角函数、幂函数等等这些“对象”的构建、处理。

(2)第二单元

第二单元的任务是电梯。

这一单元的主要难点在于多线程的实际应用,难点在于debug,我先后尝试了打印输出法和JProfiler两种方法(个人感觉还是使用打印输出法,在关于锁的操作前后加上不同输出,更加简单直白一些)。我的架构设计为,每个电梯都有自己单独的请求队列,调度器接受所有的乘客请求,然后根据乘客需求、电梯功能的不同,将请求发往不同的电梯请求队列,每部电梯只处理自己请求队列中的乘客请求。

本单元主要学习了多线程的实际应用,主要的难点在于确保多线程的安全性。在这一单元中,乘客请求队列、电梯调度器、电梯之间层次分明,分工明确,进一步加深了我对面向对象的理解。第二单元是我得分最高的一个单元。

(3)第三单元

第三单元的任务是JML。

本单元的主要任务是实现JML要求的功能,架构设计没有什么创新之处。

本单元强调的主要是规格二字,以规格为基础,结合自己的算法优化,才能正确高效地完成每一次的作业,绝对不是简单翻译JML规格,算法复杂度、测试等等都是需要格外注意的地方。本单元是动脑需求最低的一个单元,也是我得分最低的一个单元······

(4)第四单元

第四单元的任务是UML。

本单元采用通过自己新建的类封装部分UML元素,完成初始化中对所有元素的处理,之后调用解析器中各个查询方法的架构设计。主要难点在于对UML图各元素之间关系的理解,无论是代码实现还是错误排查,最后都要回归UML自身进行考虑。

在本单元,继承、封装、抽象、层次化设计等等面向对象的实现形式都得到了实际应用。各个层次的Java类职有专司,共同完成题目要求的功能,查询逻辑简单,函数调用清晰,增强了后续的拓展性和可维护性。

 

3.总结自己在四个单元中测试理解与实践的演进

(1)第一单元

数据生成:手动生成刁钻复杂的或者边缘化的数据。

结果验证:简单的直接手算结果,复杂的和同学的结果比对,后来又采用Python的库函数生成正确结果进行结果比对。

(2)第二单元

数据生成:手动生成刁钻复杂的或者边缘化的数据。

结果验证:把结果输出到文本文件,手动查询各乘客是否in、out。

(3)第三单元

数据生成:手动生成(较弱的)数据。

结果验证:与同学的程序对拍。

(4)第四单元

数据生成:手动生成数据。

结果验证:与同学的程序对拍。

事实证明,对程序进行有效的测试是确保正确性的关键。第二单元的多线程给我带来的威胁感最大,所以自己在课下进行的测试最多,提交上去的最终版本也不是很有把握,结果整个单元就错了一个测试点,其他点的用时也很短,反而是我得分最高的一个单元。而第三单元看似简单,所以我疏忽大意,没有注重测试,结果惨不忍睹。

 

4.总结自己的课程收获

  • 在一定程度上掌握了Java编程语言的应用,进一步提高了自己的编程能力。

  • 改变了大一学习的面向过程的刻板思维,学习了面向对象的相关知识,在12次的编程作业中对继承、封装、抽象、层次化设计等有了足够的理论认识与实际应用。

  • 认识到了架构设计的重要性。在OO学习中,提前构思出优秀的架构设计,对于正确性与性能,都能起到事半功倍的效果。当然,有些时候可能写着写着才想到更好的架构,这时候就要舍得花时间重构。

  • 认识到了测试的重要性。有几次作业的强测成绩不太理想,出错的bug都是在我写代码时考虑到了的,结果要么忽视了这些潜在的隐患,要么自信满满地相信自己的代码不会出问题,总之就是没有构造相应的数据去验证一下,导致强测出大问题;这些隐患之前思考过,所以bug修复阶段很快就能改正,这样就更让人后悔了,当时为什么不加强自测、主动发现问题呢?

  • 经历了强测成绩的大起大落、互测攻防的腥风血雨,心理承受能力得到了锻炼。

总之,收获满满!

 

5.立足于自己的体会给课程提三个具体改进建议

  • 实验课,编程题可不可以像公测那样显示测试点通过情况,填空题可不可以课后及时公布答案?如果没有反馈,就没法总结自己实验课的学习情况。

  • 单元训练可以比每单元的第一次作业提前几天开放,便于预习。

  • 最后一单元的作业还是和考期冲突,不利于充分的构思与测试。希望能够调整一下第四单元的作业结构。

 

最后,感谢老师、助教的辛苦付出,感谢同学们的讨论与帮助,感谢OO课程带给我的收获与成长!!!

posted @ 2021-06-26 18:02  BUAA-Panzer  阅读(58)  评论(0)    收藏  举报