BUAA OO 第四单元总结

吴瑜-22230605 学生 2024-06-10 23:05:49

 

1. 正向建模与开发总结

1.1 UML 图的应用与体会

在本单元的实践中,我通过绘制 UML 图逐步理解并改进系统设计。

类图

  • 初期设计中,Library 类承担了过多职责,造成高耦合,难以扩展和维护。

  • 随着作业的推进,将功能逐步拆分到其他类中,如 Operation 类负责处理命令,Appointment 类记录预约信息,Person 类存储用户信息。

  • 最终的类图较初期设计更为合理,各类职责更加清晰,系统结构更加易于理解和维护。

状态图

  • 状态图主要用于表示 Library 类的状态转移,包括 queriedborrowedorderedreturnedpicked 等状态。

  • 尽管 Library 类过于庞大,但状态转移仍然清晰,帮助理清了图书馆操作的流程。

  • 在反思过程中,认识到状态图在设计初期的重要性,它能够有效地指导系统的状态管理。

顺序图

  • 由于初期设计架构不佳,顺序图中很多操作都集中在 Library 类内部,显得过于简单。

  • 后续作业中逐步将操作分布到其他类中,如 orderNewBookgetOrderedBook 操作不再全部由 Library 类负责,顺序图变得更为复杂和合理。

  • 顺序图的绘制过程暴露了设计中的问题,促使对架构进行改进和优化。

1.2 正向建模的收获与反思

状态图绘制完之后还觉得自己的架构尚可,但顺序图难以下手、羞于提交的时候,才发觉自己的设计远远不够。很遗憾直至homework15,才理解到UML图的意义;更遗憾直至oo要结束了,自己的架构还是很差、类的关联性不强。

只能浅谈一下自己关于UML一致性的一点薄弱理解吧。

一致性的重要性

  • UML 图的一致性确保了系统设计的准确性,各图表应反映同一系统的不同方面,避免设计与实现脱节。

  • 一致的图表有助于理解架构,特别是在开发过程中或工作被打断时,通过 UML 图能够迅速理清系统结构和行为。

架构理解与改进

  • 初期架构设计简单但高耦合,通过绘制和反思 UML 图,逐步识别出系统中的设计缺陷,并进行改进。

  • 学会了逐步优化设计,将操作合理分布到各类中,提高系统的可维护性和扩展性。

正向建模的实践经验

  • 在构建和优化架构的过程中,通过正向建模逐步提高了设计的合理性。

  • UML 图不仅是设计的工具,也是反思和改进的有力手段,通过不断绘制和调整,逐步形成了较为合理的系统架构。

2. 本单元作业的架构设计及其演进

2.1 homework13

本次作业主要为构建图书馆基本模型。

架构设计:

除官方包中的类以外,我只设计了五个类:

  • Main类:处理输入,构建图书馆、完成图书馆中图书的初始化,逐条读入输入,交由Operation类中的handleCommand方法处理。

  • Operation类:接收Main类传递的输入指令,根据指令类型,通知Library类中的对应方法,并接收Library类对应方法的返回值(accept or reject),进行对应输出。同时,用HashMap<String, Person> persons记录来往图书馆的每一个人。

  • Library类:设置

    • HashMap<LibraryBookId, Integer> bookshelf 书架

    • HashMap<LibraryBookId, Integer> borrowReturn 借还处

    • ArrayList<Appointment> appointment 预约处

    • ArrayList<Appointment> wait 等待整理即将送往预约处的书籍队列

    完成queried、borrowed、ordered、returned、picked相应转移操作,并向Operation类返回对应操作是否成功。

  • Appointment类:记录预约信息,包含书籍信息、用户信息、放置日期、放置倒计时。

  • Person类:存储用户id,用户所持有的B类、C类书籍。

 

策略:

  • 整理策略:

    • 闭馆整理:借还处到书架

    • 开馆整理:预约处到书架,书架到预约处

    好处:先将借还处和预约处的书籍收回书架,使等待整理即将放入预约处的预约尽可能得到图书。

  • 预约处理策略:

    先将accept的预约存入等待队列,整理时,如果书架上仍有对应书籍,则将该预约由等待队列转移至预约处;否则继续处于等待队列,等待下次整理。

    好处:保证所有accept的预约能被放到预约处,避免当天整理时由于书籍不足预约信息直接删除。

后续迭代反思:

  • 将所有操作的处理都放在了Library类中完成,耦合度高,架构不清晰。

  • HashMap或者ArrayList形式指代书架、预约处、借还处,后续迭代过程中,预约处、借还处所存储的信息暴增,仅用hw13设置的HashMap或者ArrayList存储不便。

  • 书籍信息只使用了LibraryBookId,没有额外建立Book类,导致后续出现DriftBook,很难办。

2.2 homework14

本次作业新增了漂流处,相应的,要完成图书捐赠、漂流处图书的借阅、漂流图书转正等任务。

架构设计:

  • Main类、Operation类、Appointment类基本同上次作业。

  • 新增Book类,并细分为NormalBook类和DriftBook类,书籍类中记录书籍信息、借阅起始时间(为Person类服务)、借阅倒计时(为预约处服务)、借阅次数(DriftBook特有),同时实现判断书籍借阅/预约是否过期的方法。

  • Library类:

    • 将借还处一分为二,分为borrowReturnborrowReturnU

    • 新增 HashMap<LibraryBookId, DriftBook> driftCorner 图书漂流处

    • 增加renewed、donated操作

  • Person类:新增存放用户持有的BU类、CU类书籍,新增判断某本书籍是否过期的方法。

 

策略:同上次作业

后续迭代反思:

  • 预约信息存储了用户信息,但用户中没有存储预约信息,导致hw15检查用户的对应的预约是否过期时遍历较为复杂,不得不做修改。

2.3 homework15

本次作业新增了用户信用分,是否按期还书、是否逾期取书、捐赠书籍将影响信用分,,并且从书架或图书漂流角借书、预约图书、续借图书等操作要根据信用分进行限制。

架构设计:

没有再新增类,只对类中的方法进行了修改与增加。

  • Operation类:在闭馆、开馆后,对所有用户的所有书籍进行搜查,判断是否借阅逾期并进行相应扣分。

  • NormalBook类和DriftBook类:新增对借阅逾期的判断。

  • Library类:

    • 新添对“从书架或图书漂流角借书、预约图书、续借图书”操作的信用分限制

    • 预约成功后,让用户保存该条预约信息;用户取书后或预约未取逾期后,对应用户删除该条预约信息。(保证用户对自己的预约信息的知情)

    • 逾期取书、捐赠图书,改变信用分。

  • Person类:新增存储用户的预约信息,新增信用分对象和信用分计算方法,新增对持有的书籍借阅逾期搜查。

 

Appointment与person互相知情

策略:

  • 借阅逾期处理策略:

    闭关后、开馆前,检查所有用户所持有的每本书籍是否逾期,逾期则扣除信用分。

  • 整理策略:

    改为全部在开馆后整理:借还处到书架、预约处到书架,书架到预约处。

2.4 代码设计与UML模型设计的追踪关系

  1. 类图和代码设计的一致性

    • 初期设计:类图中的类和方法基本在代码中有所体现,但随着实现的细化, Library 类职责过重的问题逐渐暴露。

    • 最终设计:在类图中新增 Book 类及其子类、调整后 Library 类、新增信用分管理和预约信息管理,代码实现与类图保持一致,但部分细节仍需优化。

  2. 状态图和代码设计的一致性

    • 状态管理:状态图帮助理清了 Library 类的状态转移流程,代码实现基本符合状态图描述。

    • 状态清晰度:代码中的状态转移操作与状态图保持一致。

  3. 顺序图和代码设计的一致性

    • 操作流程:根据代码逻辑和流程画出简单的顺序图。

    • 改进顺序图:顺序图中的状态难以转移,使得高耦合问题暴露无遗,也让我意识到架构的缺陷,因此调整了架构。随着架构改进,顺序图中操作分布更加合理,代码实现与顺序图逐步一致。

通过本单元的作业实践,从初期设计到最终改进,架构逐步优化,类职责分配更加合理。UML图在设计、反思和改进过程中起到了重要作用,帮助理清了系统结构和操作流程。最终代码设计与UML模型设计基本保持一致。

3. 架构设计思维的演进

第一单元:递归下降解析与恒等变形

  • 模块化与分层设计:将表达式解析与计算逻辑分离,通过解析类和计算类的分层设计,确保各模块职责单一,代码结构清晰。

  • 数据结构设计:设计了ExprTermFactor等数据类,采用递归下降解析方法,有效处理表达式的各类操作和优先级。

第二单元:多线程与并发控制

  • 并发控制与线程安全:在多线程环境中,通过同步块wait()notifyAll()等机制,确保线程安全,防止数据竞争和死锁;重视并发控制和线程安全,合理使用同步机制保护共享资源。

  • 层次化设计:将输入处理、请求调度和电梯运行分别封装在不同的类中,形成了层次分明的架构,提升了代码的可读性和维护性。

第三单元:JML规范的代码实现

  • 规格与实现分离:遵循JML规范,实现代码与规格分离,确保代码的正确性和可靠性。

  • 数据结构与算法优化:选择适当的数据结构和算法,优化程序性能:选择HashMap替代数组,提升查询效率;引入并查集优化连通性判断问题……

第四单元:图书馆基本模型的构建

  • 面向对象设计与分类:合理设计了LibraryOperationAppointment等类,体现了良好的面向对象设计原则。

  • 分类与职责划分:本单元差劲的架构设计使我更加深刻地认识到,只有通过清晰的职责划分和类设计,确保系统的可扩展性和灵活性,才为后续迭代和功能扩展提供了坚实的基础。

4. 测试思维的演进

第一单元:递归下降解析与恒等变形

  • 测试依赖:过于依赖同学的测评机,自主性不强。

  • 数据构造不足:未充分考虑构造最简洁、最易错、最麻烦、最大值的数据,导致测试覆盖面不足。

第二单元:多线程与并发控制

  • 搭建测评机进行线程安全测试:针对并发问题难以复现的特点,编写简易测评机,通过多次运行同一组输入,监测超时情况,确保多线程环境下程序的稳定性。

  • 手动构造数据:构造多种复杂场景,如单独一条reset、大量请求、不同时间点的reset操作等,手动检查程序在不同情况下的表现。

第三单元:JML规范的代码实现

  • JUnit测试:编写JUnit测试用例,自动化测试,提高测试效率和覆盖率。

  • 多种数据生成策略:仿照实验的测试数据,随机生成指令,覆盖各种方法调用,并手动构造特殊图(完全图、孤立点图)。

  • 影子图技术验证pure:创建影子图,避免浅克隆问题,通过比较操作前后的对象状态,确保方法实现正确。

  • 多种测试方法:反复调用复杂度高的方法进行性能测试;黑盒测试、白盒测试;全面覆盖:确保所有构造方法和类型都被测试;边界数据和极端数据:测试id的边界值和除法的除数为0等情况。

第四单元:图书馆基本模型的构建

  • 数据构造器:编写数据构造器,自动生成测试数据,提高测试效率。

  • 代码阅读与交流:由于前两次作业难以自动化验证结果,更多依赖于阅读代码、与同学交流、找bug,特别关注书籍到期前后的测试,确保日期处理的正确性

  • 边界测试:第三次作业有credit指标,由于上限设置和实现差异,和整理策略相似的同学对credit指标进行对拍。

总述

  1. 从依赖到自主:从最初依赖同学的测评机,逐渐意识到自主测试的重要性,学会独立构造各种测试数据。

  2. 自动化与多样化:引入JUnit自动化测试,提高测试效率和覆盖率;搭建测评机进行多线程测试,确保并发环境下的稳定性。

  3. 性能与边界测试:关注算法复杂度,进行性能测试;构造边界和极端数据,确保程序在各种极端情况下的正确性。

  4. 数据构造较强、结果正确性验证较弱:注重数据生成策略,通过随机生成、手动构造、影子图技术等方法,全面覆盖各种可能情况,确保测试的完整性和准确性;但对于结果正确性的检验做的不好,对于自由性强、难以对拍的作业,很难想到检验思路,测难以进行评机的搭建。

5. 课程收获

十六周下来,oo不仅提升了我的编程技巧,还培养了我在复杂问题面前的耐心和解决能力。无论是架构设计、并发控制、测试编写,还是应对需求变化,都让我收获颇丰(尤其是和os比起来……)。

简单总结为以下几个点:

  • 架构设计:开始懂得如何从宏观角度审视问题,构建清晰、模块化的软件架构。

  • 多线程和并发控制:面对并发编程的挑战,,我经历了从对锁机制的困惑到逐渐掌握优化策略的过程,虽然一开始迷迷糊糊,理解并不深入,对于并发错误手足无措,但通过不断尝试和优化,逐渐理解了锁机制。

  • 优化策略:电梯调度的优化让我从追求局部最优解的局限中解放出来,转而着眼于全局。我学会了如何在不同的场景下平衡资源利用和性能提升,能够针对具体问题挑选最适合的算法和数据结构,显著提高了程序的运行效率。

  • 软件开发的工具:接触JML,我对代码规格有了全新的认知。UML图的学习让我能够将抽象的设计思想转化为可视化的图形,清晰地描绘出类之间的关系和交互。

  • 测试:代码测试是软件开发中不可或缺的一环。通过实施黑盒测试、白盒测试以及JUnit测试,我学会了从不同维度审视代码的完整性和功能性;通过构造边界数据、极限数据、压力测试,我明白了代码安全性的重要意义,这也鞭策我写代码时多思多想考虑多种情况;通过编写测评机,我的代码能力也得到了提升。

  • 平和的心态坚持不懈的意志

尾记

这学期在oo四个单元的切分下,过得格外的快。一学期以来,我总想着写到这个地方,我会输出很多的,但行文至此,却又不知道说什么了。

也曾为那一点点性能优化而锱铢必较,也曾因一点笔误谬以千里而深夜emo,但总的来说,和oo相伴的一学期很快乐!

感谢幽默风趣的荣老师,感谢每一位辛勤付出的助教,感谢dpo测评,感谢一路相伴的舍友,感谢小丑群里的大家,感谢老朋友smr,祝OO越来越好!

...全文
82 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

301

社区成员

发帖
与我相关
我的任务
社区描述
2023年北航面向对象设计与构造
学习 高校
社区管理员
  • YannaZhang
  • CajZella
  • C_ecelia
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧