302
社区成员




在本单元,我们主要学习了模型化开发的重要工具——UML图。其中,我们在本单元主要掌握的有以下三类:
而关于正向建模,实际上是通过如下流程实现:了解代码需求 -> 构建代码框架 -> 设计代码uml类图 -> 实现代码 -> 补充完善uml类图 -> 根据具体场景和需求设计状态图与顺序图。
具体在本单元的实例中,我们需要开发模拟一个小型图书馆管理系统,接下来按照上面给出的步骤模拟。
- 代码框架:实现一个具有书架(存放书籍),借还处(存放借阅失败书籍和退还的书籍),预约处(存放预约书籍),用户(借阅书籍和预约书籍的对象)的图书管理系统。
- uml类图:根据上述描述,我们可以在uml类图上构建类图框架,声明所需的类和方法。
- 代码实现:根据设计的uml类图实现代码,在实现代码的过程中很可能出现某个uml中的方法无法直接实现,需要我们建立中间方法来实现。
- 补充类图:代码实现的过程中,完善中间方法的uml类图内容
- 实现状态图和顺序图:比如通过代码注解来绘制Book的状态转移图,应当包含
Shelf
,Borrow
,Appointment
,Reader
,等状态;针对图书预约的流程实现预约顺序图等。
以上就是一个比较完善的正向建模设计思路。
首先给出初始类图:
在初始类图中,我们不需要设计非常完善的类图规格,初始设计类图的目的是为了正向帮助我们确定项目框架,比如主要的类有哪些,主要的服务函数是什么等等。在初始设计时,我对能够持有Book的类设计了addBook
和backBook
的方法,同时为Library类提供了各种需要满足的服务,在这样的框架下,正向建模能够为代码编写提供良好的框架指引。在完成hw13后,我的类图发生了如下的变化:
容易发现,初始类图和最终类图的基本框架相似,但是细节上有较大区别。首先,为了方便进行预约,我增加了容器类OrderInfo
,负责提供预约请求;其次,为了同一管理各类请求,新增了方法processRequest
方法,用于同一调用各类请求;对于tidy
方法,在实现时我发现其实质上有三部分,因此将这三部分分开为独立的方法来降低耦合度;最后为一些需要的类增加了重载方法比如Shelf类增加的多种addBook
方法。
关于项目的迭代,正向建模开发有利有弊,具体取决于每次开发的耦合度控制,如果耦合度低,则后续项目迭代只需要在原先基础上进行增加即可,反之则会更加复杂。下面是最终的项目类图:
最终类图中,随着项目迭代增加了如Drift类实现图书漂流角的功能,Reader增加了credit属性来记录信用积分等。总而言之,由于前两次作业的耦合度控制,第三次作业的迭代十分顺利,通过增加新增要求最终满足了设计需求。
在本单元的项目中,状态转移的对象是Book,可能存在许多容器中,因此我们需要通过所处位置定义并追踪其状态:
Book的初始化可能有两种,一种是通过init()
产生的正式图书,直接存放在Shelf中;另一种是通过donateBook()
产生的非正式图书,存放在Drift中。之后图书通过各个方法在不同状态之间转移,而状态转移图提供了一种清晰的方式展现了状态转移过程。需要注意的是状态转移需要在代码中提供注解对应,这一方面是本次课程组的要求,另一方面也是为了提供状态转移的对应,注解示例如下:
OO课程一共有四个单元,第一单元是表达式解析,第二单元是电梯调度,第三单元是社交网络模拟,第四单元是图书管理系统,这四个单元分别对应java项目基本模式,多线程编程,基于JML的格式化要求,UML正向建模。我的架构设计思路经历了如下的变化
- 直接进行项目构建与模块化编程:在表达式求值单元中,我的代码编写风格基本是根据需求直接编写对应的类和方法。在之后遇到需要修改的内容时会导致复杂的代码逻辑重构,而第一单元在了解了接口化和模块化的设计后,通过接口规范类的行为,通过继承实现通用方法帮助我实现了更加简洁的控制项目的方法
- 基于设计模式的编程与线程安全问题:在电梯调度的单元,我学会了生产者消费者模式,单例模式等设计模式,通过模式设计能够帮助我构建行为更加清晰,职责更加明确的类和方法。如在满足reset需求时,通过bufferQueue托盘来缓存生产者的生产资源,延迟提供给消费者使用;另一方面,本单元我了解了多线程编程的原则,熟悉了通过
synchronized
互斥锁,读写锁等方法来安全使用共享资源的方法。- JML规格与算法性能优化:JML语法的学习单元中,我们的任务就是读懂JML规格语言以及编写简单的JML,JML通过对方法的前置条件,后置条件,副作用等的约束来规范方法的功能,通过对类的属性的约束来明确属性的含义,并综合规范了类的作用。这一单元实现的社交网络模拟还对我们的性能有较高要求,我也在学习中了解了并查集算法,脏位设置,维护式查询等性能优化方法,并且实际体验了规格和实现分离的原则。
- UML模型与正向建模设计:最后一个单元我们的设计思路发生了最大的变化,从先写代码再总结架构到先设计架构再编写代码,这个过程刚开始并不适应,因为毫无头绪的设计架构还是很困难,但是在细致的了解了代码的架构需求后,通过分析设计模式能够通过UML类图设计出大体的结构框架,从而指导代码的编写过程;通过对指定情景的顺序图,状态图设计,能够清晰明确的体现对象的生命周期,信息传递和状态转移过程。
OO的全部课程过程中,不可忽视的一部分就是代码的正确性与性能测试。在第一次实验中,我主要通过手搓数据,通过人工构造各种边界条件来测试代码的正确性与性能。第二单元中,通过构建密集时间输入的数据对多线程的安全性进行测试。第三单元我了解了单元测试的方法,通过对JML规格的逐条考察来测试每个方法的正确性。第四单元是UML,我通过UML一致性检测和代码的状态转移是否矛盾来对项目代码进行测试。
OO课程至此告一段落,但是我所收获的知识令我有很大的提升。在一个学期的课程学习中,我从一个对java开发一知半解的小白,到现在能够较为熟练的构建java项目,掌握了多线程编程,设计模式,接口和模块化设计,JML规格语言,UML建模等丰富的能力,让我对项目开发有了更加深刻的认识。