面向对象先导课程博客作业

面向对象先导课程博客作业

不知不觉间,面向对象先导课程(OOpre)已经迎来了尾声。在过去的半个学期里,我们在课上学习了 Java 开发的基本知识,在课下完成了大作业的 5 次迭代和 2 个小作业。这些都为下个学期的面向对象课程(OO)打下了基础。

以下是我的总结反思:

架构设计

大作业的架构设计如下:

  • Main 类负责输入输出;
  • GenshinImpact 类负责管理全局,对冒险者、战斗日志与商店统筹调度,并处理输入输出;
  • Adventurer 类负责管理冒险者;
  • RegularBottle 类、ReinforcedBottle 类和 RecoverBottle 类负责管理各种药水瓶,后两个类继承了 RegularBottle 类;
  • RegularEquipment 类、CritEquipment 类和 EpicEquipment 类负责管理各种装备,后两个类继承了 RegularEquipment 类;
  • Food 类负责管理食物;
  • FightLog 类负责管理单条战斗日志;
  • Commodity 接口负责实现价值体;
  • Store 类负责实现商店。

其中的大部分类都是在迭代过程中根据需求添加的。另外,药水瓶和装备对应的类名原先为 BottleEquipment,在它们的种类增多后改为了现在的名字。

JUnit 使用心得

JUnit 是一款著名的单元测试工具。单元测试对于减少代码漏洞有着重要作用。

OOpre 在大作业发布之初就要求使用 JUnit,并对覆盖率提出了较高标准:方法覆盖率达到 90%,行覆盖率达到 60%,分支覆盖率达到 60%。

可惜的是,我的后几次作业都没能达到 JUnit 要求。一方面是因为要求过高:单元测试要求对每个类的各个函数分别展开测试,需要自己构造测试数据。并且在迭代的过程中,随着函数功能的变化,测试数据与测试方法也需要不断更新。另一方面则是因为我在 OOpre 上花费的时间不够多。

另外我还注意到,有些同学直接使用中测中的测试数据进行测试。这样做可以轻易满足覆盖率要求,但是违背了单元测试的初衷——算是一种无奈之举吧。

OOpre 学习心得

OOpre 这门课程是 OO 正课的先导课程,它的出现显著减轻了 OO 正课的压力。

在学习这门课程之前,大一的“程序设计基础”和“数据结构与程序设计”讲授的都是 C 语言及面向过程编程。而 OOpre 让我们第一次接触到了 Java 语言和面向对象编程,这是一个巨大的转变。幸运的是,我克服了途中遇到的各种困难,在挑战中基本取得了成功。可惜的是,某些同学依然停留在面向过程的思维模式,在迭代开发中遇到了较大困难。

但是,我在 OOpre 中花费的时间还不够多,这导致我赶 ddl 现象较为严重,而且没有完成后几次迭代的 JUnit 要求。

另外在课程结束的时候,我问了老师两个问题,老师进行了耐心解答,使我对 OOpre 有了更深入的理解:

  1. 我在进行大作业的初次开发时,使用了指导书中提供的输入解析代码,它可以将输入存储为字符串数组。但是我不确定解析输入数据与处理输出数据这项繁杂的任务应该交给 Main 类还是 GenshinImpact 类来完成。

    如果交给 Main 类,那么可以将解析好的输入数据作为参数传给 GenshinImpact 类的各个函数,有效分离输入输出功能;但是函数只能返回一个值,当有多个值需要输出时,需要构造数组进行传递,带来性能上的损失。而如果交给 GenshinImpact 类,可以将输入字符串作为参数,输出字符串作为返回值,由于 GenshinImpact 类掌握着大量数据,对字符串进行解析、组装将会得心应手;但是这样做会向 GenshinImpact 类中加入大量无关代码,不利于输入输出功能的分离。

    老师听完我的解释以后说,面向对象程序设计没有固定的答案,各种设计都有其优劣。针对你提出的问题,不妨换一种思路,构造专门的输入输出处理类:Main 类将输入的字符串写入输入处理类,GenshinImpact 类再从中读取各种类型的数据;而 GenshinImpact 类可以向输出处理类中写入各种类型的数据,输出处理类将其转换为字符串,再交给 Main 类输出。

    这使我认识到,当一个类的功能过于繁杂时,可以将其中一些功能提取封装成另一个类,让各个类的职责更加清晰分明。

  2. Checkstyle 规定,一个函数不能超过 60 行。这样的规定虽然可以阻止同学们写出过长的函数,鼓励大家由面向过程编程转向面向对象编程,但也带来了一些不必要的麻烦。例如,Main 类的 main 函数在读入一条操作之后,要对操作类型进行判断。项目开发初期,只有不到十种操作,如果写 switch 语句,每个操作占 3 行(第一行 case、第二行调用功能函数、第三行 break),空间绰绰有余。但随着项目迭代,操作种类不断增多,最终竟然达到了 23 种!此时使用之前的方法一定会超出行数限制。如果压缩到每个操作 2 行(前两行合并为一行,不会引发 Checkstyle 错误),或者改用 if 语句,虽然不会超出限制,但是剩余的可用行数十分有限。对此,许多同学为分支语句创建了单独的函数,甚至有人将其拆分为多个函数,破坏了代码的连贯性。虽然老师在课上提出了一些建议(如设计 CommandUtil 类),并提供了参考链接,但是这些方法过于繁琐。许多同学认为这种要求过于死板。

    老师解释说,Checkstyle 的严格规定是为了培养大家的适应能力。在航空领域,要求更为严格,一个函数不能超过 30 行。如果现在作出严格的规定,那么大家就会努力去适应规定。将来遇到更宽松的规定,甚至没有规定时,大家也能做到灵活应变,随心所欲不逾矩。

课程建议

虽然 OOpre 的出现是为了缓解 OO 正课的压力,但是 OOpre 的负担仍然很重。几乎每周都要进行迭代开发,另外还有 Checkstyle 和 JUnit 的强制性要求。强测与 bug 修复也是一个较大的挑战,有时需要通过对拍的方式来定位 bug。希望课程组可以适当放宽要求,减轻同学们的负担。

另外,OOpre 的指导书质量有待提升,指导书中排版问题、表述问题较多,多次出现数据限制含糊不清的问题,此时同学们会询问助教进行确认。考虑到指导书只使用一次,无法充分吸收同学们的意见建议,以及助教的压力也很大,在设计题目时难免出现差错,这也是没有办法的事情。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值