第四单元总结
“年年岁岁花相似,岁岁年年人不同”
在纷繁和忙碌之中,一学期的OO课程终于接近了尾声,回顾这一学期的OO学习过程,不可谓不艰难,但是最终的收获也是显而易见的。下面我将对第四单元的作业以及这学期的OO学习进行一个简单的总结。
一、正向建模与开发实践总结
在第四单元中,我们从UML建模的角度出发,一反以往拿到要求就直接上手写代码的习惯,而是先进行架构的设计,模型和类图的绘制等正向建模工作,然后才根据设计好的模型进行代码的实现。
在我看来,这一单元的作业相较于前几单元还是有一定难度的,因为在第一次作业进行建模的时候,由于缺乏建模的经验,也算是下了一番功夫才完成了建模阶段的工作。
在这一过程中,我个人表现出来的问题也比较多。首先是架构设计能力匮乏,即使面对这样一个简单的图书馆管理系统,我也不能很快形成一个清晰完整的架构,反而是在手动模拟了整个图书馆运行过程之后脑海中才有了一个模糊的架构设计。下面是我模拟的过程:
借着这个模拟的流程,我终于理清了图书馆的运行思路,并且开始了类图的绘制。但是在类图的绘制过程中,我又表现得心有余而力不足。我本来是想要尽可能地绘制一个完成的类图,然后给代码提供足够的借鉴,但是我发现自己在绘制类图的过程中无法考虑到很多的实现细节,甚至某些方法的接口都迟迟定不下来。无奈之下,我只好拿着一个半成品的类图去实现代码,当然实现过程中对类图进行修改的规模也可想而知。
总而言之,我觉得这一单元正向建模的过程比较艰辛,主要还是表现在架构能力的缺乏,这也与之前所有的训练的偏向于代码实现能力有关,因此在进行架构时不能擘画全局,左支右绌。当然,完成架构设计之后的收获也比较大,就拿这一次图书馆管理系统的架构来说,尽管第一次作业我的架构设计并不能说很完美,甚至都并不完整,但是因为我进行了架构的设计,所以实现代码时的思路是清晰的,而且之后两次作业的迭代我也都能够在已有架构上进行修改,并没有出现大规模的重构现象,这充分体现了正向建模和架构设计的优势所在。
二、本单元架构设计及代码实现对应关系
本单元作业的最终设计如下:
类图:
状态图:
顺序图:
从类图和顺序图中我们都不难看到,本单元的图书馆管理系统我是将Library
作为核心类,图书馆的其他各个部门都作为其属性,并且在Library
中实现了调度其他各个部门进行具体工作的方法接口。简单地说,每一个请求都会被Library
进行解析,然后根据解析出来的命令类型将其分配给相应的职能部门,如果该部门在完成这一命令的时候需要其他部门的协助,那么它就会将这一要求告知Library
,然后Library
根据对应的要求选择对应部门进行工作。这样一来就实现了以`Library‘为核心的图书馆管理系统模型。
该模型最大的优势就在于Library
具有绝对的核心地位,调用其他部门的方法都需要通过它来进行,所以在实现的过程中思路比较清晰,不容易因为功能太过复杂而乱了手脚。除此之外,这种架构在进行拓展的时候也比较简单,比如在第二次作业进行拓展的时候,只需要增加Manager
和PurchasingDepartment
并且将它们和Library
进行关联即可,在实现功能的时候还是以Library
为核心,通过它去调度其他部门完成相应工作。
但是这种架构也存在不可避免的问题,那就是在完成一项功能的时候需要增加的方法比较多,因为每增加一项新功能,不仅要在对应的职能部门中进行修改,还需要在Library
中增加相应的方法接口,无形中增大了工作量,相应地也提高了出错的概率(也是为什么类图中Library
如此庞杂的原因)。
从本单元作业代码的实现和UML模型的对应关系来看,两者之间的拟合度还是比较高的,可能也是因为我真的先设计了架构然后再实现的代码(bushi)。代码整体的工作流程也是以Library
为核心进行工作,其他各类作为其附属提供具体的工作方法,并且被Library
统筹安排。这一点其实在顺序图中体现的更加明显,能够看到每一个部门进行工作都是收到了Library
发出的消息,并且工作结束后还要给其返回一个消息,使得Library
开始下一步的工作调度。
三、本学期架构设计思维的演进
经过一学期的OO课程学习和训练,我感觉我的架构设计思维和程序设计能力得到了质的飞跃(这就是OO带给我的自信)。感觉很明显的一点就是,在拿到一个需求的时候进行分析的站位更高了。
依稀记得我刚拿到第一单元第一次作业时那狼狈的样子。那个时候我的架构设计思维还停留在之前C程序设计和数据结构的水平,拿到表达式解析的题目时先想到的不是应该采用什么架构,表达式应该如何存储,而是我在遇到各种奇奇怪怪的表达式时应该如何应对,考虑的细节很多很多,这就导致我第一次作业迟迟不能下手,陷入细节的泥潭中无法自拔,也造就了我OO最困难的一段时期。之后在第二单元作业中,我就初步具有了架构设计的思维,在进行电梯设计的时候,我会先思考电梯的调度器和电梯之间应该有的关系,电梯的等待队列应该如何存储,在做好一系列设计工作之后我才开始着手实现,最后实现的效果也比较理想。虽说第二单元难度很高,但是我完成起来还比较顺利,这可能就是我初步具有了架构设计能力的表现。经过第三单元的训练之后,我对架构设计理解得更加透彻,因为第三单元的架构很大一部分是课程组直接给出的,在这样优秀的架构之上我们只需要实现对一些数据的管理和操作,也使得我们的目光能够着眼于一些细节架构的优化处理。所以经过这一单元的训练,我的架构设计能力,尤其是微观的架构设计水平得到了提高。最后一单元就是对架构设计能力的全方位检验了,无论是宏观的架构选择,还是微观的数据处理,都需要我们自己进行设计与实现。尽管经过了一些挣扎,但我还是顺利实现了最后一单元的要求。并且在第二次作业功能极其复杂,细节极其繁琐的情况下,我也能够思路清晰地顺利完成,由此可见我的架构设计思维经过一学期的训练确实得到了很大提升。
四、测试思维的演进
无测试,不OO。
在OO的学习过程中,对代码正确性的测试至关重要,一个良好的测试思维可能让代码的实现达到事半功倍的效果,避免很多不必要的bug。
通过一学期的训练,我觉得自己的测试思维也得到了不错的提升。
第一单元的时候,我的测试思维就跟我的架构设计思维一样古朴,可以说是随便捏一个看着比较复杂的表达式就往控制台上怼,毫无章法。最后的结果就是很多测试点都是类似的,而且完全能够被简单的测试点所取代,导致不但没有测出bug,还在手动计算测试点结果的过程中浪费了时间。
在第二单元中,我就逐渐接触到了黑箱测试和白箱测试的概念。当然,那时的我觉得白箱测试完全可以由黑箱测试取代,毕竟随机的数据,什么测不出来呀!所以,第二单元的测试我就完全交给了评测机,一次作业跑几千上万条数据,直到没有一个bug才肯放心。现在想想觉得那时候心还真大,因为其实随机数据很可能难以覆盖一些边界情况,而这些情况往往又是最容易出错的地方。
第三单元中,我又接触到了JML这个东西,所以测试变得更加严谨起来。在写完代码以后,我在用大量数据进行黑箱测试的基础之上,还通过JML规格中限制的各种条件设计不同的测试数据,尽量提高测试数据的覆盖率,最终也确实收获了不错的成效。
第四单元,正如同他对架构设计的考察一样,对测试的考察也达到了巅峰。因为本单元作业虽然没有JML,但是他的功能繁琐程度和复杂程度依然很高,细节上的各种问题一不留神就会出错。因此,在这一单元的测试中,我也花费了很多时间进行测试数据的构造,要尽可能考虑到更多的细节,同时也要保证功能实现的覆盖程度和正确性。尽管构造数据比较复杂,但经过了前几个单元的高强度训练,这一单元的测试完成得也比较顺利。
总而言之,经过一学期的训练,我的代码测试能力确实在无形之中得到了提高。测试时也变得注重测试覆盖率和有效性,而不再是之前的怎么复杂怎么来,尽可能地降低测试数据的复杂度。
五、课程收获
经过一学期OO“昆仑课程”的学习,虽然经历过很多痛苦的时刻,但是最终的收获还是令我非常满意的。我觉得我的收获主要体现在软件设计和心理素质两个方面。
在软件设计方面,正如前文中提到的,我在架构设计能力和测试能力两个方面都有了较大提升。除此之外,在一学期的课堂以及和同学的研讨过程中,我对软件的一些框架更加熟悉,再也不像之前那样对软件的认识仅仅局限于小小的控制台那样了。
其次,我对面向对象这一思想的理解也更加深刻,设计软件时的思维不再是面向过程那样,而是试图通过对象之间的联系来完成不同的功能,尽可能地降低代码的耦合度,实现“高内聚,低耦合”的设计原则。我觉得面向对象的思想对于我其他方面的学习也有着很大的作用,能够让我在完成工作的时候摆脱一些细节的限制,从宏观出发去考虑完成方案。
在心理素质方面,我觉得自己变得更加自信。完成第一次作业的时候,我由于非常缺乏自信,怀疑自己的能力,从而迟迟不敢于真正下手实现代码。那一周的焦虑令我记忆犹新,但是随着完成作业的数目不断增加,自身的设计和实现能力不断增强,我逐渐变得不再畏惧每一次作业,相应得完成作业的效率和质量也不断提高。
如果说OO课程教会我的知识我在若干年以后都会忘记,但是他对我自信心的提升却一定会伴随着我走完整个人生的旅程,这种提升是无价的,也是我对这一学期OO的学习感到最满意的地方。