文章目录
本单元所实践的正向建模与开发
正向建模在本教学单元中的实践,主要体现在首先构建UML类图、顺序图和状态图,待整体规划相对成熟后,再进行代码的编写工作。这与我们之前常采取的“边想边写”的方式形成鲜明对比,“边想边写”的方式往往会在编写过程中发现方案不可行,在课程作业这样代码量相对较小的情况下,或许还能勉强应对,但在未来面对大规模代码开发时,正向建模的环节则变得不可或缺。
本单元作业中,先根据课程网站理解要求,再预先设计实现架构(用到哪些类,主要有哪些方法,需要什么属性,以及类之间涉及什么关系),构建类图。再总结系统设计的各个状态(书籍归属或书籍所在位置),以及状态之间的转换线路和条件,构建状态图。最后再根据不同的用户请求绘制各个顺序图,梳理整个处理流程。完成前面的操作后,就可以按照设计好的架构进行编程了,过程中对于之前设计欠缺的地方可以随时进行修改完善UML图(增加必要的属性方法或删掉无用的属性方法等)。
本单元作业的架构设计,并对比分析最终的代码设计和UML模型设计之间的追踪关系
hw_13
- 书架,借还处,预约处均设为单例模式
Handle
类负责分派、处理请求- 学生类自己保存所持有的书,学生发出请求先判断该学生是否已经注册过,若否,要先注册
- 预约处两个队列,分别为待满足队列和已满足队列,可以实现先来先服务。同时还有日期队列,与已满足队列等长且一一对应,保存预约请求满足的日期,方便判断预约是否逾期
- 整理均在白天开门前进行,避免长期休业导致已满足的预约请求全部逾期的情况,即只有开业才满足预约请求。而且如果长期休业,过期的预约请求可能无法在过期当天清理,于是必须在开业当天开门前清理,否则会出错。因此综合考虑实现的难度,决定全部在开门前进行整理
- 整理顺序:借还处(归档)->预约处(逾期)->预约处(给书)
hw_14
- 新增漂流处——单例模式
- 漂流处一个Map记录现有书的在架情况,另一个Map记录已成功借还的次数,转正所需
- 新增还书
overdue
的判断,由学生自己记录借到书的日期,以便判断是否逾期
hw_15
- 学生记录自己的信用积分
- 漂流处新增归属容器,记录非正规书籍由谁捐赠,决定转正给谁加分
- 除了借书逾期实时扣分外,其他的信用积分相关实现较为容易,于是借书逾期我采用置脏位的方法
- 学生类新增一个HashSet容器,记录其持有的还未被判定逾期扣分的书籍
- 一切需要加分的操作或评判信用积分前,均需要遍历“脏”容器,找到逾期的请求,扣分,移出脏容器,最后再加分,防止判断误差以及加分溢出(还书也要遍历,且无条件移出“脏”容器)
- 整理顺序:预约处(逾期)->借还处(归档)->预约处(给书)(先减后加)
四个单元中架构设计思维的演进
第一单元(表达式解析化简)
第一单元这几次作业我体会到了良好架构的重要性,可扩展性。通过作业以及研讨课对SOLID原则有了更深刻的认知。掌握了递归下降法。掌握了当 Map 容器键值是类对象时,如何重写 compareTo() 方法以实现键值比较。
第二单元(多线程电梯调度)
最大的体会就是,理解和掌握线程安全和各种锁的使用非常重要。虽然没有在调度器以及调度策略上费工夫(卷性能),但在设计各种锁,维护我的自由竞争的一大坨线程安全问题的时候,也绞尽脑汁,在这个过程中,我对锁的理解有了进一步的提升。
第三单元(JML)
规格是需求的形式化表述,可以避免自然语言带来的歧义,不涉及如何实现这些功能的具体技术细节。实现时,要在实现规格要求的基础上,运用高级的算法、数据结构等提高性能。接触了规格化设计,这种极其重要的约定手段。实际应用了很多算法知识,以及数据结构,使我对数据结构的理解更深一步。
第四单元(UML)
这个单元我们借助UML图来实现我们的架构设计可视化,以此方便我们进行代码实现和开发。锻炼了我在写代码之前先进行宏观设计的能力,而不是“边想边写”。通过UML建模的一些规则和限制也可以规范我们的架构设计,使其更合理,在设计类图分析类间关系时,就能知道是否需要新的类来进行辅助。状态图和顺序图帮助我们理清了对象状态的转变和类与类之间的交互行为。这个单元使我们进一步感受到UML的"面向对象"本质,进一步加深对面向对象思想的理解。
四个单元中测试思维的演进
U1
构造一些极端情况测试时间性能,比如多个exp()嵌套,以及针对我自己的设计中容易出错的地方具体构造数据,进行单元测试,针对做了化简的部分进行构造数据检测化简是否成功
U2
由于我设计的是自由竞争电梯,每次调度结果不同,再加上多线程本身的bug隐藏性,导致出现的bug很难复现。最终凭借对自己代码的深刻理解,定位到了错误所在处。测试过程较为困难
U3
本单元引导我们编写Junit单元测试,强调了检测assignable条件时,深克隆的必要性。针对本单元容易出现的TLE问题,我首先计算每个要求实现的时间复杂度,针对复杂度较高的实现,构造了大规模的针对性数据进行压力测试
U4
主要采用手动构造数据
课程收获
- 设计一个优秀的架构比实际编写代码要难的多,这四个单元中,我学习了SOLID原则,以及UML模型化语言,后者教我要先架构,再code,前者教我什么是优秀的架构。有一个好的架构对系统的可扩展性,维护都有极大的好处
- 我的综合能力得到了提升,这四个单元的任务中,我一直保持着活跃的思维,思考着更好的实现方式,比如第一单元把
exp()
和幂视作同级,不断扩增表达式树的层数。第二单元首次实现了解决了陪跑问题的自由竞争电梯。第三单元运用之前学过的数据结构的知识降低时间复杂度,学以致用。第四单元由于交互式的评测,使我更加自由的设计自己的图书馆系统 - 面向过程语言向面向对象语言的过渡,体验到面向对象的魅力