这一单元的做业本质上是对数据之间的联系进行解析,并从新创建数据结构以方便查询的工做,这就要求咱们了解各类UmlElement的结构以及他们之间的关系是如何组织的。编程
在此次做业的架构上,首先是创建了MyUmlInteraction
类,实现UmlInteraction
接口,以完成各类查询方法。因为输入数据不保证顺序性,因此不能边读边处理,而是要先将各类元素分类保存在相应的容器中。对于那些后续要经过name
或id
查询的元素,都使用了HashMap
存储以提升查询效率。以后经过一系列build*
方法创建继承、实现、关联等关系,再把各类属性、方法、参数加入到相应的类或接口中。设计模式
为了方便类和接口管理他们的数据,我为UML中“类”和“接口”的概念又分别开了相应的类。这样一来,一个类(接口)有什么属性、方法、参数,实现了哪些接口,与谁有关联,就都很是清楚了,并且更能体现一种从属关系。更重要的一点在于,每一个类(接口)还能够有一个指向父类(父接口)的属性,造成一种树形的结构,方便遍历访问。数据结构
此次做业是上一次做业的扩展,总体的架构思路没有太大的变化。须要调整的地方在于,此次要支持三种UML图的查询,这些方法的实现不可能都放在一个大的类中,因此理想的架构是对于每种图的查询分别在各自的类中实现,而后集中在MyUmlGeneralInteraction
中实例化,最终将各类查询操做委托给各自所属的类。多线程
在数据存储和管理方面和上一次做业大同小异,都是有什么元素就创建相应的容器,必要时再开新的类,例如图中的State
、StateMachine
、Interaction
。架构
本次做业我耗时最多的部分是实现模型有效性检查,须要考虑关联、实现、继承的直接或间接关系,在遍历时保证不重不漏。其实从难度上来讲并不大,只是一些概念不太清晰,须要想清楚各类可能的状况。编程语言
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课程的灵魂。在每次做业的架构设计中,我对于面向对象的理解都有进一步的加深。具体的内容我已在前文中有过总结,但它的精髓远不止架构设计这么简单。面向对象是一种编程技术,但它更是一种思考问题的方式,一种世界观,一种哲学。世间万物是广泛联系的,它们之间的关系如此复杂,以致于不能孤立地只用过程式的观点来描述事物如何运做。面向对象经过抽象造成类、层次、继承等概念,为咱们提供了一个全新的视角……