BUAA-OO-2019 第四单元总结

UML作业架构设计

这一单元的作业本质上是对数据之间的联系进行解析,并重新建立数据结构以方便查询的工作,这就要求我们了解各种UmlElement的结构以及他们之间的关系是如何组织的。

第十三次作业

在这次作业的架构上,首先是建立了MyUmlInteraction类,实现UmlInteraction接口,以完成各种查询方法。由于输入数据不保证顺序性,所以不能边读边处理,而是要先将各种元素分类保存在相应的容器中。对于那些后续要通过nameid查询的元素,都使用了HashMap存储以提高查询效率。之后通过一系列build*方法建立继承、实现、关联等关系,再把各种属性、方法、参数加入到相应的类或接口中。

为了方便类和接口管理他们的数据,我为UML中“类”和“接口”的概念又分别开了相应的类。这样一来,一个类(接口)有什么属性、方法、参数,实现了哪些接口,与谁有关联,就都非常清楚了,而且更能体现一种从属关系。更重要的一点在于,每个类(接口)还可以有一个指向父类(父接口)的属性,形成一种树形的结构,方便遍历访问。

第十四次作业

这次作业是上一次作业的扩展,整体的架构思路没有太大的变化。需要调整的地方在于,这次要支持三种UML图的查询,这些方法的实现不可能都放在一个大的类中,所以理想的架构是对于每种图的查询分别在各自的类中实现,然后集中在MyUmlGeneralInteraction中实例化,最终将各种查询操作委托给各自所属的类。

在数据存储和管理方面和上一次作业大同小异,都是有什么元素就建立相应的容器,必要时再开新的类,例如图中的StateStateMachineInteraction

本次作业我耗时最多的部分是实现模型有效性检查,需要考虑关联、实现、继承的直接或间接关系,在遍历时保证不重不漏。其实从难度上来说并不大,只是一些概念不太清晰,需要想清楚各种可能的情况。

OO课程总结

对架构设计及OO方法的理解

OO课程的每个单元作业都分为两到三个阶段,这与实际开发中逐渐增改需求的情况是相近的。如果一开始的架构是好的,那么后续作业的扩展就相对容易。但于我而言,往往后续的作业会让我意识到之前的架构设计并不理想,有时甚至到了不得不重构的地步。在这一次次的推倒重来中,我会渐渐明白什么样的架构是好的,怎样才能写出好的架构。好的架构的特点是简洁、清晰、高内聚、低耦合、易维护、可扩展,这也是OO方法中很重要的一部分。具体来说,每个类或方法都应只有一个明确的职责,只管理自己该管理的数据。对于有泛化关系的类应采用继承来表现共性中的特性,但也要注意对于没有层次关系的类不应滥用继承。要合理设置属性、方法的访问权限,尽可能将数据隐藏起来并提供相应的访问操作。策略与机制分离,将功能模块化封装,降低依赖性和耦合度,使得更改某一功能的实现不必牵连太多其他代码。诸如此类的设计原则还有很多,总之我的狭义的理解是,能在一次次作业的迭代中保持结构清晰稳固、功能愈发健壮的架构就是好的架构。

对测试的理解与实践

OO作业中用到的测试方法基本上就两种:朴素地生成大量数据进行测试,和通过OpenJML、JMLUnitNG等工具进行自动化测试。

第一种方法,按照数据生成的方式可分为人工手造数据和自动化批量生成数据,前者效率较低且一般只能覆盖到一部分情况,后者效率很高而且几乎能覆盖到所有情况,但要求能正确编写数据生成脚本。无论怎样生成数据,为了尽可能的覆盖到所有的情况,我们需要对输入数据的各部分的各种可能进行组合;另一方面,我们要确保测试数据能让代码中的每个分支都被执行到。此外,按照正确性检验的方式,这种方法还可分为标准答案检验和对拍检验。前者的前提是能通过某种方法事先得到输入数据的正确输出结果,这样能确保判定结果的绝对正确性。如果无法得到标答,那么只能采取对拍的方式,即将两人或多人的答案进行比对,对其中有差异的地方分析出是哪一方的问题。当然不排除会有输出同样的错误结果的可能性,只不过发生这种情况的概率很低。

第二种方法,也是OO课程想培养我们学会的测试技能,即通过JML工具链,自动化地生成测试样例。说实话我对这一方面的了解不是很深,更多是一些实验性质的探索,了解了它能做什么及其基本的原理。这种测试方法的好处在于,测试数据的生成全程自动化,且理论上能覆盖到所有的情况。但它的弱势也是显而易见的:学习成本高,需要花更多的时间在代码中编写JML测试相关的语句,这是有一定难度的。

个人认为,可能在工业界,尤其是那些不容许任何程序错误的场景下(如航空航天、军事领域),使用JML相关工具进行严密的测试是必要的。但在OO课程的作业中,甚至是小团队的实际开发过程中,用最短的时间实现最高的效益可能是选择测试方法时更需要考虑的因素。

然而无论如何,JML是一门值得了解和学习的技术。

课程收获

我在这一学期OO课程中的收获是多方面的。

首先,熟练掌握了基本的Java语言。Java是一门跨平台的面向对象编程语言,在学界和工业界都有着广泛的应用。正所谓“工欲善其事,必先利其器”,要学习面向对象思想,首先必须得打好语言的基础。其实课程中对于Java语言本身的教学内容并不多,后期遇到了问题更多是自己上网查找资料,通过各种文档和博客,逐渐强化了使用Java的功底。从这个角度来看,这门课还培养了我自主学习和独立解决问题的能力。

其次,对于多线程编程有了较深的理解。多线程编程是实际开发中常常会用到的一种技术,学习它我们才能解决多模块协作的问题,充分利用CPU的资源。多线程问题需要我们使用合适的设计模式,对各线程间的同步、互斥有深入的理解,全面和仔细地分析协作是如何进行的,这对我们的思维能力也是一种锻炼。

再次,对JML(Java Modeling Language)有了一定的了解。JML是基于“契约式编程”的一种规格描述语言,相比于自然语言注释,JML更加严谨和清晰。我们从两个方面进行了训练:根据需求撰写规格,以及根据规格实现代码。此外,我们还尝试使用JML工具链自动化生成测试样例进行测试。无论体验如何,学习这样一门技术是有必要的,相信将会在未来的实际开发中使我受益。

从次,还学习了UML(Unified Modeling Language)的相关知识。UML通过可视化的图形形式,帮助开发者对大规模、复杂系统进行建模,这对于设计面向对象的架构具有重要的意义。通过对UML文件的解析,得以深入了解各种元素的结构和组织方式,以及检验模型有效性的原则,在这个过程中对面向对象语言的特性也有了更深的理解。

最后,也是最重要的一点,就是对面向对象思想的感悟。它不是某一个具体的知识点,但却是贯穿整个OO课程的灵魂。在每次作业的架构设计中,我对于面向对象的理解都有进一步的加深。具体的内容我已在前文中有过总结,但它的精髓远不止架构设计这么简单。面向对象是一种编程技术,但它更是一种思考问题的方式,一种世界观,一种哲学。世间万物是普遍联系的,它们之间的关系如此复杂,以至于不能孤立地只用过程式的观点来描述事物如何运作。面向对象通过抽象形成类、层次、继承等概念,为我们提供了一个全新的视角……

改进建议

  1. Checkstyle中每行最多80个字符的限制我认为不够合理,编写代码时往往硬生生地把一句逻辑连贯的代码拆成多行,仅仅因为属性或方法名较多、较长。个人认为在阅读代码时,莫名其妙的换行比一行稍长的代码体验更糟。建议将每行的字符数上限改为100~120。
  2. 希望BUG修复可以挽回强测中一定比例的分数。
  3. 希望课程组能合理安排实验课时间,避免再发生上午刚接触的新知识下午就考的情况。
posted @ 2019-06-23 17:57 AdamDing 阅读(...) 评论(...) 编辑 收藏