301
社区成员
发帖
与我相关
我的任务
分享目录
本单元的主要任务是以一个图书管理系统为背景,学习UML建模语言及正向建模实践。
在本单元的学习过程中,我逐步体会到了正向建模开发的流程及其意义。
首先,什么是正向建模?在我看来,所谓正向建模,就是在具体写代码之前,设计好整体架构,明确有哪些类及类之间的关系、各业务的大致处理流程、类之间如何进行消息协作。这分别对应UML中的类图、状态图和顺序图,有力地帮我们对工程整体有了一个宏观的把握。
具体而言,UML类图:表达了类的特征(属性、方法)及类间的关系,让我们对各类的职责有了一个明确的认识,使我们设计的类更加分工合理,职责明确,更符合“高内聚,低耦合”的思想。
UML状态图:表达了一个对象乃至一个系统状态转移的路径和条件,本单元中主要是一本图书的状态转移行为。绘制UML状态图,使我们明确各业务的处理流程,即一本书是怎样被来回借阅、移动、预定、归还的?明确了这些,实现具体功能时就能做到有条不紊,胸有成竹。
UML顺序图:表达了各对象的生命线,及各类间是如何交互协作的。本单元中主要是图书管理过程中各单位间的消息传递与处理。绘制UML顺序图,同样是为了使我们处理业务思维更加清晰,流程更加明确。
正向建模软件开发大致包括如下流程:需求分析与理解,模型设计与建立,代码编写与实现,代码验证与测试。在本单元中,我大致遵循了先在脑中设计、构思好,然后在纸上绘制UML模型,依据模型实现代码,最后再正式绘制模型图的过程。个人的感受是比起前几个单元的直接开写,这样的开发流程避免了同时思考“树木”与“森林”的混乱,看似增添了负担,实则是减轻了各个阶段的思维负担。当然,本单元的图书管理系统规模尚小。我相信在将来更大规模的开发过程中,一定能更深切地体会到UML带来的好处与便利。
本单元架构设计的难度并不大,只需按图书馆各部门之间的关系分别设计类。具体而言,我在三次作业中,分别设计了如下类及类间关系:
Hw13

Hw14

Hw15

可以看出,架构设计的主要依据是各部门职责的不同,以及用户的相关操作。最终的代码设计和UML模型间是互相追踪的。首先,具体代码实现以UML为指导,此处代码设计追踪了UML。但代码最终完成后,难免有一些需要对预先设计的UML进行补充与完善的地方,此时就需要UML追踪代码设计。UML与代码是紧密联系,互为表里的。
这四个单元中,我的架构设计思维进步很大,主要表现在以下两个方面:
1.从只追求完成功能到追求架构设计的合理性。在Pre及正课之初的很长一段时间内,尤其是Pre阶段,我一直不重视架构设计,认为只要功能正确即可,架构设计没什么用处。但是,在这个学期更具挑战性的编码实践中,我越来越体会到良好的架构设计的重要性。在Pre阶段,每次的迭代开发其实并不是很复杂,所以“两耳不闻架构事,一心只求功能对”的方法尚可应付。但是,在正式的课程中,每次迭代的功能要求要复杂得多,若不注重架构设计,比如将几个方法实现的功能堆在一个方法里、将几个类实现的功能堆在一个类里,会给后续的开发、维护带来极大不便,所谓的正确性也就难以保证了。我认为这一点主要体现在本学期的第一单元与第四单元,让我们学会如何设计合理的类及类间关系,类间的协作,利用继承、接口等让代码有层次化等等,在实践中感触颇深。
2.从只顾当下功能需求到考虑未来开发场景。最初我每次迭代开发的时候,丝毫没有考虑后续开发的意识,简单地完成本次作业就可以了。但事实上,我们每次迭代与维护时不仅要考虑当下的需求,还要考虑未来可能需要的功能需求,为之留下充足的余地。这样可以避免每次迭代时都大规模重构。这一点我在第二单元中感受最深,例如第一次作业中指出“本次作业指定了接送乘客的电梯”,如果因此就不写分派器的话,就会为后续迭代带来麻烦,所以我还是写了分派器。此外,第四单元第一次作业中,我并没有将用户建立一个单独的类,而是仅用一个HashSet管理每个用户拥有的书,这是我考虑的不周之处。到第二次作业时,我就发现这种方式会巨麻烦无比,遂改进。(事实证明第三次作业中用户增添了信誉积分、已预订书籍等属性后,无User类的架构是更不可行的。)
总得来讲,第一单元层次化架构设计,第二单元多线程架构设计,第三单元涉及架构较少,主要是规格化设计和严谨的思维,第四单元利用UML进行架构设计,四个单元的训练下来,让我们的架构设计思维能力有了显著提升。
测试思维方面我主要是由原来的不测试或者依赖评测机测试,到学会自己构造测试数据,分析需求中的各种情况,以及边界条件,构造测试数据。在原来的Pre中我几乎不做什么测试,每次作业需求和坑点都较少,按部就班写完通过中测也就不会挂强测了,所以一直重视不起来测试。但OO从第一单元起,就让人充分认识到了本地测试的重要性。第一单元的测试主要是加深表达式树的深度,以检验各种情况下计算的正确性。第二单元主要是针对高并发、死锁,以及电梯运行过程中的各种限制(乘客人数限制,reset后移动不得多于两层,双轿厢电梯不得同时位于同一层等)进行测试,构造各种(“诱导”程序出错的)边界情况进行测试。第三单元实现正确性不难,主要是针对性能,进行了各种超过公测数据限制的压力测试,用各种情况极端且量大的自造数据点来衡量实现的时间性能,以保证强测不超时。第四单元测试主要是丰富指令组合的情况,尤其是针对各种出错的情况(有书则不能借、逾期则不能取、负分则不能借)进行测试,测试是否会输出错误的accept;此外还有卡逾期时间,卡升级时机等测试手段,都是容易出bug的点。
在测试这一点上,我感觉自己是有一定运气的,几乎每次都能在本地测试时恰好发现自己的bug,经常会出现“认为这个功能应该没有bug,但还是测试一下,没想到真测出bug了”的情况,每次都感慨要是偷懒少构造了这条测试数据,可能强测就挂了。后来这种情况出现的越多,我对本地测试就越加重视,感觉宁可多造一千,也不可少造一条。最终我很幸运地通过了12次强测,没在强测中被测出来问题,因此我认为我对测试的坚持是很有必要的。
“折磨”了我近半年的OO课程,竟然就结束了。平心而论,这是我目前学过的核心专业课中,我最喜欢的一门。大概对我来说,软件方面的课程就是比硬件方面的课程更有意思,所以就我感兴趣的程度而言,纯软件的面向对象设计与构造 > 软硬件衔接的操作系统 > 纯硬件的计算机组成原理。还记得去年OOPre课程结束的时候,我为自己认识了一种新的编程和思维方式,掌握了一门新的语言的基本知识而感到振奋,对未来的正课充满期待。不曾想,今天连正课也落下了帷幕。在自己期待的这门课中,我收获了很多。
1.面向对象思维的提升,这是毋庸置疑的。记得上课的时候,老师反复说,面向对象不是一种编程方式,而是一种思维方式。确实,现实生活中的万事万物,都可抽象为一个个“对象”。用面向对象的方式分析问题,抽象业务,关注错综复杂的问题中的一个个最小单元,可使问题规模分解,使问题得到简化。用面向对象的方式思考问题,就已经成功了一半(doge).
2.编程能力的提升,这也是毋庸置疑的。无论是架构设计还是编码规范,乃至语言特性,这个学期都有了不少新的收获。
3.细致分析需求的能力。OO正课中的每一次作业需求都较多,有时有很多很细节的需求,都需要我们仔细阅读并考虑到代码实现当中。遗漏需求或者需求理解不透彻,是软件开发中相当严重的错误。
4.面对挑战的勇气。课程中,颇有难度的迭代任务、等待强测的紧张刺激、互测攻防的各显身手,都给我们带来过压力,带来过挫折,带来过打击。但是看到自己最终平稳地走过了终点线,这种激动还是难以言状的。从今往后,面对其它困难时,我们也要相信“没有比脚更长的路,没有比人更高的山”,一步一步地战胜挫折。
这一个学期OO学习的过程,对我来说既有折磨,也有愉悦。现在,这一个学期的惊心动魄都结束了,我真的有些不舍。课上老师曾提起,大三软件工程可以算是OO的一个“后继”课程。那么,我也先小小期待一下——正如OOPre结束时,对OO的期待。
感谢这门课程,让我从设计到实践到测试,面向对象编写软件的能力有了很大提升,感谢所有老师和助教们的辛勤付出。