2024 BUAA OO Unit4 总结

一、正向建模与开发

正向建模与开发(Forward Engineering)是一种从系统需求和设计模型到系统实现的开发方法,在本单元中我按照正向建模与开发的方法完成作业的步骤是:

  1. 需求分析:根据指导书提取出图书馆的主要业务和业务流程
  2. 系统设计:提取出需求中的实体类、控制类和边界类,分析这些类之间的关系,使用 starUML 绘制类图,确定大概架构
  3. 详细设计与编码:根据 UML 图进行编码,在编码过程中细化并修改每个类向上层提供的接口,如果必要的话可能对类的属性进行修改,进一步完善 UML 图
  4. 测试:完成代码后进行测试,在图书馆系统中主要是对预约、续借的各种情况、边界进行测试

由于是第一次先进行完整的设计再编码,在实现过程中我对类提供的接口做出了很多修改,与最初的设计有较大变化。通过这个单元的训练,我对正向设计有了一定的感受,在第三次作业里我对各个类新增的接口做出了比较详细的设计,由于迭代度不大,比较顺利地根据设计完成了编码,没有对设计的接口做出修改。对于一个比较复杂的系统,先整理需求再进行设计,可以大大减小编码后重复修改的频率,好的设计可以提高开发效率,但是面对需求变化很大的项目可能效果并不好。

二、第四单元设计架构

第一次作业

本次作业需要模拟一个图书馆中借书,预约,还书,查询的业务流程,最重要的一个对象是书,它可以被用户拥有,也可以在图书馆中的书架、借还处和预约处,为了方便管理这些书,我设计了一个类 BookManager 用于存放书的集合,支持基本的增删改查功能。

书籍在用户和图书馆中的移动情况有:

  • 用户 ↔ \leftrightarrow 借还处
  • 书架 → \rightarrow 用户
  • 书架 ↔ \leftrightarrow 借还处
  • 书架 ↔ \leftrightarrow 预约处

每次的移动操作,就是从一个 BookManager 中按照特定把某些书移动到另一个 BookManager 里,由于不同 BookManager 的行为存在一些不同,因此我选择了将 BookShelf, BorrowReturnOffice, AppointmentOffice 继承自 BookManager,向外界提供与实际业务场景符合的接口。

图书馆具体的运作逻辑由控制器提供,我在 Library 类中实现了对图书馆的控制功能,对外接口为 run 方法,根据输入执行对应行为。

public void run(LibraryCommand<?> input) {
    LocalDate date = input.getDate();
    if (input.getCmd() instanceof LibraryRequest) {
        LibraryRequest request = (LibraryRequest) input.getCmd();
        if (!users.containsKey(request.getStudentId())) {
            users.put(request.getStudentId(), new User(request.getStudentId()));
        }
        behaviors.get(request.getType())
                 .apply(request.getBookId(), users.get(request.getStudentId()));
        
    } else if (input.getCmd().equals("OPEN")) {
        this.date = date;
        organize();
    } else {
        Output.print(date, null);
    }
}

下面是第一次作业的 UML 类图,Library控制类User, Book, BookManager, BookShelf, BorrowReturnOffice, AppointmentOffice实体类Output 类中封装了输出方法为边界类

在这里插入图片描述

第二次作业

第二次需要做出较大改动的需求是续借和图书漂流功能,图书在图书馆中出现位置和移动路径出现了变化,新增的非正式图书和正式图书之间的转化可以通过 Book 类的属性 LibraryBookId 来区分。

需要新增一个继承自 BookManager 的类 BookDriftCenter 作为图书馆中的图书漂流角,管理了图书馆中的非正式图书,新出现的图书转移路径为:

  • 图书漂流角 → \rightarrow 用户
  • 图书漂流角 ↔ \leftrightarrow 借还处

下面是第二次作业的 UML 类图,与第一次作业相比新增的类为 BookDriftCenter,出现了比较大的变化的类有 Book, Library

在这里插入图片描述

第三次作业

第三次出现的新需求是为图书馆用户增加信用积分,并且用户的借书,还书,预约,续借行为需要根据当前的信用积分做出更改,不需要出现类的新增和对之前接口的更改。下面是第三次作业的 UML 类图,与第二次作业相比只有 Book, User, Library 新增了方法或对之前的方法进行了改动。

在这里插入图片描述

三、设计架构体会

第一单元的挑战在于将数学问题抽象为一个个对象,并将数学上的运算转化为类的属性变化。在实现上,需要利用层次化设计将复杂的表达式展开和化简问题逐层拆解,首先解析成基本单元,然后利用递归下降的方式进行转化,最后经过处理输出。

第二单元的挑战在于多线程和复杂系统的控制,比如电梯该如何运行,怎样合理地分派请求,这些逻辑应该采用集中式还是分布式的分布,都需要仔细考量。

第三单元是根据提供的设计和规格进行建模,需要读懂规格需求并设计合理的数据结构和算法高效地实现接口,作业在设计上的难度不大,重点在于帮助我们理解规契约式设计给代码实现带来的帮助。

第四单元的涉及在于正向建模,不同于前三个单元边设计边写代码挑战,需要在编码前根据需求形成大致的设计并初步绘制 UML 图,在刚开始时,由于不太适应这种设计方式,最后的实现跟设计有很大的差别,经过三次作业训练,在最后一次作业中的实现和设计已经可以比较好的匹配,也感受到了好的设计可以提高编码效率,减少推倒重来的次数。

四、测试体会

在第一单元中,我进行了两类测试,一是对那些核心的计算类用 JUnit 进行进行单元,二是使用脚本进行自动化测试,通过大量的随机数据找到问题。

在第二单元中,涉及到多线程,每个类的功能都并不复杂,重要的是各个类之间在多线程下的通信协作是否正确,因此我没有进行单元测试。我做的测试主要是高并发情况下和边界条件下对线程安全的测试。

在第三单元中,JML 为单元测试提供了很好的范例,我在代码中那些涉及到算法和动态维护的数据和方法进行了单元测试,在确保 Network 类的各个接口正确后,通常代码整体运行起来就不会出现问题。在第三单元,我开始使用覆盖率分析工具来判断测试的强度,代码中的每个分支、方法都应该在数据中被覆盖到。除此之外,我开始对自己的代码进行压力测试,通过手工构造特殊的数据,来检查代码的运行效率。

在第四单元中,整体业务流程比较简单,在确定设计后实现难度不大,每个类方法不涉及算法大多是对容器简单的增删改查,主要逻辑在于控制类对各个类之间的交互,因此只需要对控制类进行单元测试。在本单元我同样进行了自动化测试,与前三个单元不同的是,在第四单元我基于官方包的输入输出接口完成了输入数据生成投喂、输出捕获和正确性判断,对于自动化测试的实现方案有了全新的理解。

通过四个单元的学习,我掌握了自动化测试的脚本编写能力以及单元测试编写能力。所有的测试代码在下面的仓库中:评测机 git 仓库

五、课程收获

  • 面向对象设计思维:在上学期的 pre 课程中,我对面向对象的理解还局限于类的封装和继承的使用,在本学期的课程里,第一单元让我对层次化建模和多态有了更深的理解,第二单元让我对复杂系统中的层次化设计有了新的理解,第三单元和第四单元主要聚焦于编码前的设计和编码后的测试。
  • Java 编程能力:在完成作业的过程中,为了优化代码可读性和鲁棒性,我学习了 Java 中提供的 Stream, Optional 等工具类,Stream 类通过链式编程和函数式编程极大地提高了集合元素操作的可读性,Optional 类提供了一种优雅的方式来处理可能为空的值。
  • 多线程编程能力:第二单元中的电梯问题让我开始接触到多线程问题,对于线程之间的协作,安全等问题有了初步的了解,提高了多线程 bug 定位和调试能力。在学习过程中,我了解了 Java 中提供的读写锁、线程池等处理多线程问题的常用工具,结合操作系统所学知识,逐渐对多线程有了更深的理解。理论课上老师提出了高并发下性能问题,底层指令重排带来的线程安全等挑战,激发了我进一步了解多线程编程的兴趣。
  • 测试能力:在每个单元中,我都进行了自动化测试,掌握了 Python 脚本编写,数据构造能力。另一个方面是对单元测试在开发过程中的作用有了新的理解,比如在第一次作业中,对于涉及到计算、化简、展开的核心类可以进行单元测试,通过单元测试验证核心类的正确性,可以在出现 bug 时更快地定位,提高开发效率。

一个学期的 oo 课程转眼就结束了,4个单元、9次迭代作业让我的代码能力得到了前所未有的提高,还记得大一专业宣讲时听到 oo 一周的代码量有千行,之前的我不只一次怀疑自己能不能完成这门课的任务,现在我终于可以自信地和当初的自己说你可以了。现在想想,每天静下心坐在教室里写作业、搭评测机,从定位一个 bug 到最终解决,也是一段有趣而难忘的经历。

在这里插入图片描述
在这里插入图片描述

  • 13
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ChenxuanRao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值