一、本单元作业的架构设计
1.1 第十三次作业
第十三次作业实现了基于类图的UML模型解析,首先在构造方法中按照处理好的输入内容解析UML类图,考虑到输入元素的顺序可能颠倒,使用我分三批次处理输入中的不同元素。为此我新建了MyClass、MyInterface和MyOperation三个类,管理类、接口和方法三种UML元素和需要存储的各种信息。然后在进行查询时,如果是第一次查询该类的信息则调用visit方法,找到它的所有父类和从各级父类处继承来的属性、方法、关联、接口继承等并保存,再按接口要求实现对应的方法即可。最后添加主类运行程序。以下是我第十三次作业的UML类图,诚实地说我一些类的属性和方法还是比较臃肿的。
1.2 第十四次作业
第十四作业实现了对UML类图、状态图和顺序图的解析,其中UML类图解析部分我几乎照搬了第十三次作业的内容,没有做太大改动,主要新增了对状态图和顺序图的解析,在第十三次作业的基础上进行迭代开发。关于状态图,我新建了MyStateMachine类,用于管理每个状态机及其涉及的状态和状态间的转移。特别地,Initial State和Final State也作为状态处理。关于顺序图,我新建了MyInteraction类管理每个顺序图模型和其中的参与对象、消息等等。类图、状态图和顺序图各司其职,通过一个总的MyGeneralInteraction类调用类图、状态图和顺序图的所有解析方法,实现官方包接口。以下是我第十四次作业的UML类图,状态图和顺序图的解析要比类图容易一些。
1.3 第十五次作业
第十五次作业在第十三、十四次作业的基础上继续进行迭代开发,但由于第十五次作业增加了对模型有效性的检查,而我之前都是按照正确的模型做的,没有考虑错误的模型,所以我进行了局部的重构(尤其是类和接口之间的继承与实现关系),以便对错误的模型进行识别和检查。总体上的设计框架不变,主要在类图和状态图中增加了一些属性和方法,在所有元素解析完毕后进行全部遍历检查,按序输出对应的报错信息。第十五次作业的UML类图如下,总的代码量增加,达到1200多行。
二、架构设计与OO方法理解
回顾四个单元共十二次代码作业的架构设计,第一单元的前两次作业还是比较机械的沿袭了面向过程编程的陋习,直到第三次作业才开始培养面向对象编程的思想,采用工厂模式,先用正则表达式读取输入的多项式,再用工厂模式解析为不同的对象,按照一定的求导规则求导后输出并化简。第二单元的三次作业都采用了线程安全的设计和生产者消费者模式,并且开始有意识地采用面向对象”编程思想,数据结构和算法分离,各部分的功能较为明确和独立,架构设计详见我第二单元的总结博客。第三、四单元的作业形式都类似于代码填空题,我在课程组提供的设计框架之下,除了实现指定的接口之外,为了尽量地细化功能、便于调试,我自行设计了若干个具体类的职能,简洁、高效地组织代码,既保证了架构设计的完整性,又体现了面向对象的编程思想。此外,我还复习和学习了一些图的算法,再在保证程序正确性的前提下兼顾效率。
四个单元的主题各不相同,作业和实验训练的侧重点也不同,对OO方法的理解自然也各不相同。第一单元是面向对象的入门,初步了解了面向对象的基本概念和设计架构,学习了对象与类的基本性质,尝试围绕类定义数据和设计程序,利用对象间的继承和多态等关系学习和训练层次化设计思想。第二单元重点学习了面向对象的多线程设计与并发控制,进一步了解了JAVA语言下对象的运行机制,尝试采用多线程——现实需求中更常见的形式进行并发行为的分析与设计,编写程序并测试,尤其注意确保线程安全和避免死锁。第三单元以JML为训练内容,学习了规格化的面向对象设计,用规格规范程序设计,基于规格部署JUnit等工具链验证程序的正确性。第四单元主要是UML,学习模型化设计与模型管理,通过对类图、状态图、顺序图等的解析与验证,可以看作是对整个课程的总结与综合。
三、测试理解与实践
在OO课程和工程开发中,测试都是十分重要的环节。第一单元,我尚且停留在手动测试为主的测试方法,手动构造一些符合条件的多项式进行测试,尤其注意测试边界条件和特殊情况,效果不错。
第二单元的输入内容较为复杂,我开始尝试自动生成测试数据,并按指导书的要求逻辑验证输出的正确性。不过无论是自动测试还是手动测试都没有测到bug。。。
第三单元因为输入输出都是经过一摸一样的官方包处理的,所以测试起来十分方便。首先按照一定的规则生成测试数据,然后多找几个同学对拍即可,我通过简简单单的字符串比较发现了许多bug。反而是课程组推荐的JUnit测试,可能是我没有参透其中的奥妙,所以感觉有些鸡肋。
第四单元的测试和第三单元类似,构造对拍器进行字符串比较即可,只是构造数据的难度较大。最后一次作业临近期末,我的测试有些懈怠,强测出了许多bug,在此提出严肃的自我批评。
四、课程收获
计算机学院的专业课大抵分为硬件和软件两条线,硬件有计组、OS、编译、计网等,软件则是程设、数据结构、OO、算法、软工等。由此看来,OO是一门承上启下、十分重要的课程,是我们编写工程化的面向对象代码的入门级课程,也是后续学习软件开发的重要基础。作为一门公认的重课、难课,OO课程展现了它应有的内容和难度,让不同基础的学生都能获得很大的提高。出乎我意料,OO课程几乎没讲JAVA语言,而是放在pre中让我们自学,上来就讲了面向对象的概念等知识,说明这不是一门简单的市面上的那种教你一门编程语言的速成班,而是一门真正的、名副其实的“面向对象设计与构造”,课程中传授的面向对象知识与方法,比如多线程并发、规格化设计、工厂模式、生产者消费者模式等等,都是不局限于某个编程语言的,可以迁移到其它编程语言、其它硬件环境、其它课程甚至非计算机的其它领域去的,我想这种潜移默化的影响和熏陶是我们受用一生的宝贵财富。除此之外,通过OO课程,我进一步深化了工程化思想,学习Git等辅助工具,学习了从表达需求到测试到迭代开发的一整套软件开发的方法论,锻炼了复杂项目、大型软件设计开发经验和能力,互测、研讨、博客等环节锻炼了与他人交流合作的能力,整个课程还锻炼了作为IT从业人员必要的心理素质和抗压能力。不可谓收获不大。
五、三个改进建议
(以下建议按优先级递减)
- 强烈要求课上实验结束后继续公布实验题面并开放实验的测试过程和结果,方便同学课后继续思考研究,学习知识,查漏补缺,没有评测反馈只会让人徒增焦虑,毫无实际收获。此外,严格控制课上实验的题量和难度,有时题量小、难度小,有时题量大、难度大(尤其第六次实验代码量太大了),大多数人两个小时难以做完。
- 无论是课程网站或企业微信都存在有时通知不到位的问题,我非粗心之人,然而修改指导书、修改ddl或是增加实验补测的通知常常错过。和隔壁OS课程组相比,我认为建立OO课程大班群就是一个很好的办法,还可以作为一个答疑讨论的平台。
- 合理安排课程内容和顺序,可以考虑将比较重要的UML放在前面讲授,或者作为pre的一部分内容(可以增加寒假的预习量),或者降低第一单元求导作业的难度(比如提供一个设计好的代码框架供学生填空),减轻同学初来乍到的不适感。另外,本次博客作业进了考期个人感觉也不太友好,可以考虑适当压缩课程安排,减少一次作业。
六、线上学习体会
计算机学院的课程应该算受疫情影响较小的,大部分靠自学,在线上线下都能一样进行,可能课上实验的环节影响稍大一些。从隆冬到盛夏,线上学习的时间更加自由灵活,不用怕上课打瞌睡遗漏了知识。唯一的遗憾是不能见到帅气美丽的老师、助教和同学好友,和优秀的你们当面进行思想碰撞一定会更爽。克服许许多多的困难,完成一学期的OO学习,“曾经沧海”,颇多感慨。千言万语,感谢课程组老师和助教的全心付出,感谢所有为我提供鼓励和帮助的人,感谢努力奔跑的自己,希望OO课程越来越好!
以上。祝好。
庚子仲夏 于金陵