OO第四单元总结暨课程总结

一、第四单元作业架构说明

UmlElement 部分属性说明

公有属性 备注
type 类型
id id 字符串
name 名称
visibility(部分没有) 对外可见性,如private、public

类图

UMLClass 备注
parentId 指向UmlModel或UmlClass(不是继承关系)
UMLOperation 备注
parentId 指向UmlClass或UmlInterface
visibility 对外可见性,如private
UMLInterface 备注
parentId 指向UmlModel
UMLAttribute 备注
parentId 指向UmlClass
type 类型,如int
UMLParameter 备注
parentId 指向UmlOperation
direction IN 为输入参数,RETURN 为返回值
type 类型,如int
UmlAssociation 备注
parentId 指向UmlClass
end1 指向一个AssociationEnd
end2 指向一个AssociationEnd
UmlAssociationEnd 备注
parentId 指向UMLAssociation
reference 指向引用的Class
UmlGeneralization 备注
parentId 指向UmlClass或UmlInterface
source 尾端,指向子类
target 箭头端,指向父类
UmlInterfaceRealization 备注
parentId 指向UmlClass
source 尾端,指向Class
target 箭头端,指向Interface

Association和AssociationEnd关系

UMLClass <- AssociationEnd <- Association -> AssociationEnd -> UMLClass

状态图

UmlStateMachine - 略

UmlRegion 备注
parentId 指向UmlStateMachine
UmlPseudostate(起始状态) 备注
parentId 指向UmlRegion
UMLFinalState(结束状态) 备注
parentId 指向UmlRegion
UmlState 备注
parentId 指向UmlRegion
UmlTransition 备注
parentId 指向UmlRegion
source 尾端,指向迁移前的状态
target 箭头端,指向迁移后的状态
guard 前置条件
UmlEvent(trigger) 备注
parentId 指向UmlTransition
UmlOpaqueBehavior(effect) 备注
parentId 指向UmlTransition

顺序图

UmlInteraction - 略

UmlLifeline 备注
parentId 指向UmlInteraction
represent 指向UmlAttribute
UmlMessage 备注
parentId 指向UmlInteraction
source 尾端,通信的源UmlLifeline
target 箭头端,通信的目标UmlLifeline
messageSort 消息类型
UmlEndpoint 备注
parentId 指向UMLInteraction

总体架构

OO第四单元总结暨课程总结

OO第四单元总结暨课程总结

 

 

第十三次作业

本次作业的主要目标是实现类图的生成以及相应的查询功能。

在 UmlProcessor 生成 MyUmlClass 类的实例时,我将从属于该类实现的接口 Interface、该类的方法 Operation、该类的属性 Attribute、该类关联的类 Association 、类的父类 Parent 都存放在了类中,方便查询。UmlProcessor 存储类的集合保存在,并提供一定的 public 方法以供外部类查询。

MyUmlGeneralInteraction(ps. 第十三次作业的时候叫MyUmlInteraction)中根据需要实现的功能,调用 UmlProcessor 中的函数,再进行一定的判断即可。

第十四次作业

本次作业的主要目标是实现状态图和顺序图的生成以及相应的查询功能。

同样的,在 UmlProcessor 中生成自定义的一些类,根据上面的表格进行生成就可以,不再赘述。

本次作业的难点,个人认为是在接口方法的实现上。getSubsequentStateCount() 中我用到了 dfs 算法,把每个 MyUmlState 当做有向图中的一个节点进行查找,每个节点中存储着指向的节点的 ID。

第十五次作业

本次作业没有大的改动架构,主要是在第十四次作业的基础上增加一些判错功能。

本次作业的难点我认为在于 R002 和 R003,这两个的判断方法中,我都用到了 dfs 算法。

 

二、四个单元中架构设计及面向对象方法理解的演进

第一单元

第一单元的主要任务是表达式求导和化简。

在第一单元的时期,对于面向对象方法的理解还处于似懂非懂的状态,虽然了解了面向对象的概念,但并不真正理解面向对象相比于面向过程式的编程的优势,明明能几行代码写完的内容,为什么要多写那么多 “没必要” 的类呢?并且,我对于面向对象的具体实现方法没有思路,知道父类继承方法但用不好。

在架构方面,我仔细思考了荣老师在课上说的 “1 + 1 = 2” 的例子,然后努力按照这个思想去设计我的表达式系统。由于对面向对象方法的理解不够,以及自身代码能力的问题,我的第一次作业就写的异常繁琐。由于是第一次写面向对象类型的程序,我的架构处于面向对象和面向过程之间,异常混乱繁杂。可谓是写 bug 真是信手拈来,debug 一把辛酸泪。我写了整整两天的程序,又 de 了两天的 bug,在最后几次中测才 ak。相比于纯面向过程,我的架构好在刚好能够应付后两次作业,后面迭代并没有全盘重构。

总的来说,现在回首去看第一单元的架构,发现问题还是挺大的。架构形式的繁杂表现在表达式类求导后输出的是 String 而不是表达式类,所以在化简的时候需要再次将 String 转换成表达式类。并且,迭代开发时需要修改很多以前的代码,而架构的不合理导致类与类之间的耦合度很高,一个类中的方法被多个类反复调用,稍微一修改可能造成多个 bug。作业代码迭代到后面,已经是我几乎不敢修改一行代码的程度了。

第二单元

第二单元的主要任务是多线程电梯。

经历过第一单元的磨砺,我对 java 语言以及面向对象的思想有了进一步的理解,这为第二单元打下了基础。而第二单元的多线程机制是新接触的,在面向对象设计的基础上加入多线程机制着实还是有些难度的。在第二单元,我已经能有意识地较为合理地划分类的功能和规模,控制类之间的耦合度,为迭代开发预留空间,力求不让我的电梯代码变成第一单元那样迭代困难,甚至不得不重构。总的来说,第二单元中我对面向对象方法的理解更加成熟,因此做出的程序架构也相对更加合理,容易维护、迭代开发。

第二单元的难点在于多线程程序的线程安全问题。对于临界区资源的保护与共享,在保证正确性的同时合理兼顾效率是重中之重。

第三单元

第三单元的主要任务是 JML 语言。

这个单元中主要的任务不再是自己设计基于面向对象思想的程序,更多的在于读懂 JML 规格描述。我认为这个单元的难点在于 JML 描述语言的繁杂。另外,这个单元更多注重于图算法的思考,如最短路径的查找。

在这个单元中,我熟悉了 JML 语言,理解了在给出规格的条件下写代码的工作形式。

第四单元

第四单元是我认为理解量和代码量都非常大的一个单元,让我仿佛回到了第一单元的时期。对于 UML 模型源码的理解是一个比较困难的过程,并且对 UML 模型的元素进行处理也是一个代码量非常大的工程。并且在此过程中还需要考虑一定的算法来实现。

这个单元我认为是我面向对象方法应用地最好的一次,我在设计时花了挺长的时间去思考如何架构,最终我的架构是以增强类功能直接的独立性为目标,如我设计了一个 UmlProcessor 类,负责存储和处理各种 Element。这样的架构方式,让我在第二次、第三次迭代开发的时候非常顺利。

 

三、四个单元中测试理解与实践的演进

第一单元的作业要求单一,即表达式的求导,只需要判断输出结果的正确性即可。因此第一单元的测试,主要是随机测试,利用 Python 及其拓展库编写的自动评测机,能较好的覆盖到第一单元的作业要求。

相比于第一单元的作业要求,第二单元的测试要求更加多维。并且由于第二单元是多线程程序,测试结果的不确定性也导致了评测存在困难。此外,多线程程序还需要考虑线程安全问题,对于程序的临界测试也是非常必要的。因此第二单元,随机测试和手动构造数据点相结合,测试耗费精力更多。

第三单元主要是单元测试。由于有规格的明确限制,因此使用单元测试也是十分明确的。单元测试中需要考虑各种可能出现的情况,而随机测试不能保证能覆盖全面,所以仍需要辅以手动构造的临界数据点。

第四单元的测试要求也较为明确。因为随机测试需要编写的评测机的工作量太大,以手动构造测试样例为主,辅以“读代码”验证。

 

四、课程收获

  • 熟悉和掌握了 java 语言,提高了些代码的能力,这是非常实用且重要的技能。

  • 深入了解了面向对象程序设计思想,相比于原先的面向过程思想,我获得了更强的程序设计能力以及更多的程序实现方法。

  • 进一步理解了多线程程序的原理和运行机制。

  • 锻炼了代码风格的控制,相比以往,我现在写的代码更加工整,可读性更高。

  • 进一步理解的测试的重要性,锻炼了程序测试的能力。(一把辛酸泪)

  • 锻炼了心态,对写程序变得习以为常、从容不迫,面对 bug 也能坦然自若。

 

五、课程建议

  • 丰富课前预习的内容。在预习时,我仅仅掌握了一定的 java 语法,对于继承机制还不甚理解。然而第一单元第一次作业就需要动手写那么大量的代码,靠着本就不强的代码能力,难度更是进一步加大。并且,预习课中的指导部分我认为过于简略,我初学时真的难以理解。我认为可以适当增加预习课的内容,更多增加教学内容,而不是一昧让我们通过实践去体会。(预习中我根本没有用到继承机制就写过了...)

  • 给予更多的课下作业时间。周日晚上截止的评测,到周二晚上公布评测结果,这其中的两天我间隔我认为可以适当缩短,如周一晚上截止中测提交,这样我们的课下时间更为充裕。(我认为强测不需要花费那么多时间)

  • 实验课提供反馈结果和 bug 修复环节。这实验课总感觉缺点啥,仔细一想是没有反馈激励导致的。并且,实验课过去之后就再无动静,对于自己的掌握情况的了解并没有大的帮助。

上一篇:实现递归树形结构


下一篇:【Java】树状节点结构的数据