第四单元通过介绍UML语言帮助理解面向对象的层次化设计、线程安全设计和规格化设计。两次作业围绕着UML的内容,使用Java实现了对UML类图、顺序图和状态图的建模。
一、总结本单元两次作业的架构设计
充分利用官方开源库,并根据需求创建了UClass和UInterface两个类分别作为Uml类图中Class和interface的载体。针对大多数任务要求的id和key互查功能,对Class、Interface、Arrtibute和Operation分别设置了一个集合两张表的数据结构。通过邻接表归纳继承和接口实现关系,由于这次作业不存在循环继承,故直接对所有没有父亲的类(或接口)自上而下深搜继承。注意实现顺序:1.接口继承,2.类实现接口,3.类继承。
出现的问题是审题不仔细,孩子继承的属性被标记为孩子的属性,而非父亲的属性。在第14次作业中通过记录每个属性的源头解决了这一问题。
第14次作业UML类图:
将第13次作业中实现的MyUmlInteraction更名为MyUMLClassModelInteraction,继承它以实现MyUmlGeneralInteraction。新增功能中关于顺序图和状态图的查询较简单,分别构建了对应的类以实现需求。类图检查功能中较为困难的是Uml009循环继承问题,由于在第13次作业中已写好深搜部分代码,故直接采用深搜方法查询图中的环。
问题是没有处理空指针,在一些测试点上出现了多余的Uml009报错。
二、四个单元中架构设计及OO方法理解的演进
通过四个单元的学习,我在面向对象程序设计上经历了由陌生到规范再到熟练的过程。
第一单元一开始是通过面向过程的方法来编写,但由于要求实现的功能不断增加,在第二次作业中尝试了以“多项式的项”这个对象为核心的建模方法,尝到了面向对象的甜头。第三次作业进一步深入落实上述模式,初步写出了一个层次化的面向对象程序,具备了处理括号嵌套等复杂内容的能力。
第二单元围绕电梯调度问题探索Java线程。个人认为线程设计是面向对象程序设计中相对独立的一部分,也是相对较难的一部分。在架构设计层面,根据第一单元作业的经验采取了简单的层次化设计,并且根据线程部分所学内容设计了电梯与调度器之间的通讯模式。印象深刻的一点是,第二次作业只有一部电梯,其空闲时可以通过不间断查询获取新乘客信息,但这样会导致cpu超时;课程组通过在测试数据上的巧妙设计引导我们使用和探索线程锁以及由此引出的线程安全通信机制。
第三单元由于是根据JML写程序,有一些命题作文的意味,但我认为这一单元的作业并不简单。在JML的规范下,程序在架构设计上相比于前两个单元少了一些自由度。但第三次作业在时间复杂度上有较高的需求,对算法和数据结构方面的能力是较严格的考察。
第四单元的主题回归面向对象的层次化与规格化设计。经过前三个单元的洗礼,此时我编写出的Java程序已较为清晰可读。在类、接口等对象的基础上实现题目要求的查询功能,第二次作业直接继承第一次作业的大部分代码,是一次较完成的面向对象程序开发和维护体验。一部分也归功于本单元作业围绕UML模型展开,在对UML建模的同时,我也会根据UML规则反思自己实现的代码在设计上的问题。
三、四个单元中测试理解与实践的演进
在前两个单元采用人造测试集测试的感觉和面向过程相似:围绕需求,检查代码实现需求的流程,人为构造特殊数据点。直到第三单元随着JML的学习引入了单元测试方法,除了JUnit自动化测试的好处之外,我认为单元测试的思想也更加适合面向对象程序的架构设计。单元测试为好的架构的实现铺设了道路,更为合作编程、功能迭代扫清了障碍。但前一种测试方法也不应被完全摒弃,如第一单元作业的一些潜在bug就很难只通过单元测试发现。总体来说,架构设计越清晰,单元测试越重要。
另外第二单元需要单独讨论。多线程任务的测试是位于另一个层面上的难题,因为多线程本身就存在一些不确定性。我认为对于多线程程序的设计,时序图是至关重要的;因此测试也应围绕时序图进行。特别地,发生线程间通讯、线程睡眠、开启和关闭的时刻要作为测试的重点。
四、课程收获
这学期的课程收获分多个方面,其中最主要的还是对面向对象架构设计的理解。经过一学期的课程(其中最重要的是11次作业的训练),我在实践中积累了一些架构设计经验,它们独立于数据结构和算法的设计,成为我日后编写程序时重要的参考知识。我认识到,具备面向对象的思维是简单的,如何落实这一思维却是极考验知识和技巧的。面向对象相对于一套复杂的理论科学,更接近大量实践总结出的工程经验。也因此,只有更多地参与面向对象程序设计的实践,才能够做出更好的架构设计。
另一方面是对Java语言的学习。Java是一个门很合适的面向对象入门语言,也是Android应用、数据库等开发任务中的常用语言之一。这学期编写了不少的Java程序,后两个单元更是对Java语言本身做了详细的介绍,仅仅从获得应用Java语言的能力这一角度来看,我也受益匪浅。Java还与C#等传统C-based语言、Kotlin等新兴语言有大量相通之处,即使其本身的前景不甚光明,学好Java也是有广泛而深远的意义的。
还有很多收获是心理上的。不必赘述,总结一下,实践是检验真理的唯一标准。
五、课程改进建议
1. 进一步减小外部条件的影响:即使Eclipse也可以满足课程要求,IntelliJ Idea在完成作业和实验时还是要方便太多。建议课程组直接推荐使用IntelliJ Idea并给出破解教程(社区版不支持UML图),最好是学校可以提供JetBrains License。另外StarUML破解步骤繁琐,实验课上还有下载速度较慢的问题。希望下一届学生不再被这类问题困扰。
2. 作业的考察重点:虽然每次作业中课程组都有耐心引导我们做出合理的架构设计,但一部分作业(和数据点)的难点仍然在算法而非架构设计。希望能够进一步提升架构设计在作业评分中的比重。
3. 实验课内容安排:实验课成为了答题课,尤其是后几节实验课不需要编写任何代码。理论知识固然需要一些习题来巩固,但巩固的这个过程是否应该叫实验课,有待商榷。