冒险者的故事已经来到尾声,在这里我将对我这半学期几次迭代作业以及学到的知识进行总结和回顾。
迭代开发作业以冒险者游戏为背景,前后实现了不同种类的药水瓶、不同种类的武器、碎片兑换机制以及背包系统,之后加入了战斗功能、雇佣机制,最后加入秘境工厂副本。
在学习过程中,我对 Java 基础语法有了了解,学习了类的特点和机制,综合运用不同容器,对工厂模式有所体验。
架构设计

图中已有的信息不再赘述,这里说明一些其他的架构信息:
- Adventurers 容器位于 MainClass 类中;迭代作业中所有 12 个操作方法位于 CommandUtil 类中,主类通过传递 Adventurers 容器来实现一系列操作;
- 在 Adventurer 类中,有 bottles 容器、 equipments 容器和 fragments 容器,分别表示冒险者所拥有的物品。背包系统没有使用单独的容器,而是作为各个物品的属性 isCarried 来表示。雇佣关系用 hires 容器表示雇佣者,使用 HashMap 表示援助次数,键值对为雇佣者下标到援助次数的映射;
- TreasureFactory 使用接口管理不同的 Guard 和 Treasure。
在迭代开发的过程中,有几次重大的重构:
- 在学习继承的那次作业中,对于 Bottle 、Equipment 和 Adventurer 类的管理进行了调整:定义一个父类 Unit ,管理 id ,name, ce 三个属性,Adventurer 类直接从属于它,Bottle 和 Equipment 类间接从属于它;定义 Item 类,继承于 Unit 类,Bottle 和 Equipment 类直接从属于它;单独定义三个子类 AtkBottle,DefBottle 和 HpBottle,继承于 Bottle 类;
- 在学习容器的那次作业中,将之前的一些 ArrayList 容器更改为 HashMap 或者 HashSet:不同类型的容器各有优缺点,其中 HashMap 用于明确的映射查找,例如使用 id 直接映射到 Bottle 和 Equipment 等;ArrayList 类用于有序遍历,例如战斗中对潜在被攻击者的临时存储;HashSet 用于不重复的存储,例如 fragments 容器;
- 增加操作数的过程中,主类方法行数过长,增加 CommandUtil 类分别操作(类似于 Solver)。
JUnit 体会
虽说每次编写 JUnit 测试代码都是冲着覆盖率去的(),但也从中体会了一些单元测试的优势。
设置 assert 断言可以很方便地看出方法是否 bug 。但我感觉没有 vscode 直接断点调试看得清晰直白,并且编写 Test 代码也非常麻烦,其实不太理解 JUnit 到底好在哪了(),可能是我没有掌握它的灵魂,希望在接下来的 OO 正课中能有更多体会,
OOPre 体会
在学习 Java 语言之前,我最熟悉的编程语言是 C ,因此从面向过程编程过渡到面向对象编程,我发现了其中的很多不同以及面向对象编程的优势:
- 逻辑的层级关系更加清晰:即便 C 语言中有函数和结构体的方法进行模块化编程,但面对庞大的工程会变得十分困难。在面向对象中,不同的类之间有继承关系,还有接口等不同功能,这一点在 debug 的时候深有体会,看到一个疑似存在 bug 的方法,会去寻找它的类,再去寻找父类(如果有的话),有顺藤摸瓜的感觉;
- 代码的可读性更强:在面向对象中,需要编写更多的方法(函数)来完成相应的模块化功能,而这些方法的命名以及类与方法之间使用“点”的组织方式使得代码非常易懂,相比于 C 语言需要添加大量注释解释对应代码段的企图,Java 更像是在阅读一篇说明书。
- 方便多人合作以及模块化开发:这点在 OOPre 课程的作业形式——迭代得以体会,经过一周时间,再来看之前写的代码居然不会迷失其中(?),并且能精准定位应该在什么地方添加新的需求,这得益于面向对象的逻辑。扩展到多人合作的场景,你可以直接对他人提出“给你一个xxx类,有xxx属性,你来写一个xxx方法”然后将他的代码像拼积木一般与总工程拼接上,非常 amazing 呀。
课程建议
课程组的各位都辛苦了!非常感谢助教们给我们提供的这么有意思的冒险者故事以及详细严谨的指导书,使得学习过程非常有趣(也会因为 bug 抓狂)。在这里提几点建议:
- 上课内容例子不够鲜明:课上非常注重理论,然而实践体会几乎全部放在了课下开发,这会导致课上听得有些云里雾里,以及相对来说枯燥乏味,如果能在课上多展示代码例子会很好;
- 没有更多建议了。
冒险者的故事已经完结,而 OO 的史诗冒险才刚刚开始。
祝我 OO 顺利!祝同学们 OO 顺利!祝课程组越来越好!~o(^_^)o~