OO第四次博客作业
第四次博客作业
OO课程的第四单元是完成对UML的解析。本篇博客前半部分对第四单元的架构进行介绍,后半部分对本学期的OO课程进行总结。
一、总结本单元的架构设计
1、架构的选取
刚拿到第一次作业,感觉有点迷茫,一时间不知道采取什么架构来处理问题。在参考学习了往届博客的总结后,发现有如下两种架构“派别”:
HashMap集成派:在一个类中使用十多个HashMap来存储数据,虽然看似方便,但是与面向对象思维相悖;My*****改写派:将UmlClass、UmlInterface等Uml元素改写成自己的MyClass、MyInterface等类,这种方法体现出了层次性,更有利于迭代。
第一单元重构三次的惨痛经历还历历在目,为了之后作业能不用重构,我毫不犹豫加入了第二种“派系”,踏上了一条改写之路。
由于三次作业都是层层迭代的,整体架构都相似,在这里就拿第三次作业来进行具体介绍。
2、元素的解析
毫无疑问,官方包里的十几个Uml元素是有层次关系的,比如只有解析了UmlClass之后,UmlAttribute才能找到parent。因此,我采用在构造函数内直接进行解析,通过多次遍历解析每一层,解析顺序如下:
UmlClass、UmlInterfaceUmlAttribute、UmlOperation、UmlGeneralization、UmlInterfaceRealization、UmlAssociationEnd、UmlInteraction、UmlStateMachineUmlParameter、UmlAssociation、UmlLifeline、UmlRegionUmlMessage、UmlState/UmlPseudostate/UmlFinalStateUmlTransitionUmlEvent
解析依据:根据课上内容和UML基本知识,可得到以下层次图:

注:UmlAssociation和UmlAssociationEnd在实际解析中需要交换顺序
3、数据的存储
主要使用四种容器结构进行元素的储存:
HashMap<String, Object> myElements:储存所有可以成为其他元素父类的元素;HashMap<String, String> associationEnds:储存关联对端HashMap<String, ArrayList<>>:通过名字映射元素,便于myClass、myInteraction、myStateMachine的无名、重名检查ArrayList<>:myClass、MyInterface、myInteraction、myStateMachine的列表,便于第三次作业的合法性检查(其实也可以与第三种类型数据合并,减少存储)
4、类间的交互
限于CheckStyle对于类长度的限制,在MyUmlGeneralInteraction类中,直接调用各改写类的内部方法,最大程度上减少类的体格。同时,对于类似UmlClass、UmlOperation、UmlParameter之类的有多层嵌套的,采用逐层调用的方法获取返回值。
二、总结自己在四个单元中架构设计及OO方法理解的演进
先来看看课程组对四个单元的总体定位:
- 第一单元:面向问题分解与归纳的层次化设计
- 第二单元:面向并发控制与安全的层次化设计
- 第三单元:基于规格的层次化设计
- 第四单元:面向复杂数据管理的层次化设计
四个单元的侧重点各有不同,但是都强调了层次化设计,即层次化的架构。
可以说,第一单元的三次作业是让我在“层次化架构”入了门,老师和助教几乎是手把手教我们如何进行设计。我也在这一单元带来的阵痛中,完成了从第一次作业完全面向过程coding,到之后两次重构将代码逐步层次化。现在想来,第一单元最后自己写的代码也并非那么的层次化,其实可以更多地利用接口进行抽象和优化,这样或许能使架构更加合理,代码的可读性也能提高。
而第二单元的多线程部分,在主流的“消费者-生产者”模式的基础上,我也有了自己的思考,增加了一个类似于CPU的中央类,用于各种资源的协调,这也使得作业中各个类不再只是平级的交互关系,而是听从于更高层次类的“指挥”。
到了第三单元,整体的架构几乎全部由课程组JML代码给出,虽然无法展现自己的“架构想法”,但是,有时候阅读其他人好的架构也能提升很多。这个单元的官方架构以Network类为核心,同时,Message子类使用继承开发,使得整个工程简洁但又层次分明。
最后一个单元的主要架构已在前面给出,很遗憾的是,主要的架构并不是全靠自己想出来的,而是参考了往届的博客。这也让我意识到自己的架构水平真得还只是菜鸟水平,未来还需要更多的锻炼和思考。
在结束了四个单元的学习和coding之后,我对OO方法也有了更充分的认识,自认为OO方法主要是架构设计以及类和数据管理,前者相当于经济学中的“宏观调控”,后者则更像是“微观调控”,两者密不可分,最终构成整个项目。两方面的学习都不是一蹴而就的,更多的是在经验的累积和总结。
三、总结自己在四个单元中测试理解与实践的演进
测试是软件开发极其重要的一环,这学期我也了解和参观了一些互联网公司,发现他们都有专门的软件测试岗位,而我也参加了一些项目的开发,了解到了测试的重要性。
几乎每次的研讨课都有同学分享自己的测试方法,也让我认识了许多测试技巧。在本学期的coding过程中,我主要使用或者尝试了以下几种测试方法:
- 随机数据生成:第一单元的的多项式生成和第三单元图元素的随机生成;
- 构造边界数据:各单元的边界情况;
- 对拍器:第一单元和第三单元的输出结果比对;
- 回归测试:第二单元的三次迭代;
- 利用软件设计并导出数据:第四单元利用
UMLStar生成测试用例; - JUnit:尝试过,但只学习了最基础的使用手法;
- 形式化验证:仅在第一次作业中尝试过。
虽然这学期使用了许多的测试方法,但是自认为在测试层面做得还远远不够,主要在于以下两个方面:
- 自动化水平低:主要以手动构造为主,除了最简单的随机样例生成,很少使用算法自动化生成样例;
- 覆盖性较差:很多边界情况都是拍脑门想到的,没能够构造出覆盖所有情况的数据集合;
- 无法完全做到正确性检查:大多数情况是与正确答案或者同学进行对拍,但无法确保答案的正确定。
对于这些不足,我也会在接下来的学习中不断弥补与改进。希望到大三下学期的软件工程课中,我能使用更完全地测试方法帮助团队找到bug并修复。
四、总结自己的课程收获
技术方面的收获在这几次博客作业中已经说得差不多的,本篇博客的前半部分也主要是以技术总结为主的,那么这里就来说说技术以外的一些收获吧:
- 交流与探讨的重要性:同学之间的交流和探讨肯定要比一个人闷着脑袋想更有效,也更能开拓思路。在这里也要感谢fzc和yrb同学(他们也是大创项目的我的两位队友),平常和他们之间对于作业构思和bug修复的交流也让我收获很多。另外,也感谢研讨课分享的各位同学,让我开拓了视野。
- 时间管理的重要性:OO每周的作业都是无缝衔接,留给每一次作业的时间并不充裕,更何况期间还有其他课程需要顾及,这也就需要我们更好地管理自己的学习投入时间。既不能“太浪”,把ddl拖到最后,也不能一直“爆肝”,影响正常的作息。
- 反思总结的重要性:说实话,我并不是一个擅长总结的人。之前的很多课程,都是“完成即结束”。这学期的OO博客总结也让我明白了总结的重要性,一些想法和构思只有在总结的时候才会被理顺,也只有在总结过后才能被深深地记住。
五、立足于自己的体会给课程提三个具体改进建议
这学期的OO课程体验可以说挺不错的,虽然过程有些“煎熬”,但最后收获还是颇丰。要是说还有哪些改进意见的话,我觉得课程组在这三个方面可以进行改进:
- 理论课ppt的可读性希望能够改进:OO的理论课主要以“世界观”而非“方法论”为主,更多是介绍一些抽象的概念和构思。这时候,我们还没进行实际的coding,很难完全听懂老师课上的内容。但是当打算通过ppt回顾课上知识的时候,却发现ppt过于简单,很难通过ppt联想起老师上课的具体内容。
- 题目难度尽量与往年持平:也看过往年的指导书和博客,发现今年许多作业的难度都高于过往同期的作业。我认为增加太多的需求有时候反而让同学过分关注这些需求的实现,而减少了对作业思想层面的关注。此外,难度的无限提升也会让同学们感到焦虑从而起到反作用。
- 对于CheckStyle的想法:在课程使用的
CheckStyle要求中,对import不能使用.*的限制有些不认同。一方面,许多IDE会自动折叠同一个包中的import,最后还要自己展开很麻烦;另一方面,像第四单元使用大量import而不能折叠,使得整个类的头部显得臃肿,影响美观,这也应该不是CheckStyle想要看到的吧。
浙公网安备 33010602011771号