270
社区成员
发帖
与我相关
我的任务
分享1. 项目架构设计与实现
我的最终项目由 src 中的十大类组成。除了顶层的 main,用于第七次作业的表达式解析的 lexer 和 Parser,以及 SearchResult 与容量受限的 LimitedDeque 外,真正承担主要功能的核心类可以概括为四大类:Adventurer、Bottle、Spell、Equipment。
在此基础上,我进一步通过继承进行了细化:
Bottle → HpBottle、AtkBottle、DefBottle、ManaBottle
Equipment → Armour、Weapon
Spell → AtkSpell、HealSpell
此外,我设计了一个 Use 接口,让不同类型的物品都能以自己的方式实现“use”指令,行为更统一、扩展更自然。
main 中采用了一个较大的 switch-case 结构用于识别指令。核心逻辑大多集中在 Adventurer 类中:除了基础属性,我还为其加入了多个容器,包括“仓库”(存放装备与药水)、“背包”(携带消耗品)、“装备栏”(护甲与武器)、“上下级关系”(用容器存储上下级对象实现)等。绝大多数方法均在Adventurer类中实现。其他类主要负责存储自身属性,Bottle 和 Spell 会额外实现拓展后的 use 行为。
在迭代过程中,架构最明显的变化是将 Bottle、Spell、Equipment 等抽象为父类,再逐步细化为不同子类,让结构更清晰、可拓展性更强,其余部分变化不大。
⸻
2. 使用 JUnit 的体会
JUnit 帮我真正体验到了“单元测试”的价值。它能让我把每个方法单独测试,定位问题的效率相比 C 语言时代大大提升。以前找 bug 常常是“牵一发而动全身”,为了一个小问题要沿着流程把所有中间步骤重新检查一遍。但 JUnit 能在 bug 还没深入代码结构、变得难以定位之前就把问题暴露出来。
不过,它的作用依赖于代码本身是否够“可测试”。由于我转向面向对象的思维还不够彻底,依然把不少关键逻辑写在 main 里而没有封装到类方法中,这部分就没法通过 JUnit 做单元化验证。即便我写出了覆盖率很高的测试集,仍有相当多的问题被“漏掉”。所以想充分发挥单元测试的威力,必须把逻辑拆分为清晰、可测试的函数,而不是堆在主逻辑里。
⸻
3. 从 C 到 Java 的 OOP 思维转变
从 C 语言转到 Java,我感受到面向对象更贴近人的自然思维。在 C 语言写双关键字排序时,我就习惯把多种属性(ID,不同的关键字)“捆成一个整体”放进结构体中,再对结构体排序。虽然形式上还是面向过程,但我觉得这种把相关属性封装进一个“对象”的做法其实已经接近 OOP 的思考方式。
到了 Java 和 OOP 的语境中,这种倾向被工具化、体系化了:类、继承、接口、设计模式……
我觉得最明显的变化是:
写程序不再只是设计流程,而是在“搭建一个世界”。
过去写代码像是在写一串为了完成功能的流程步骤;现在写代码更像在搭建一套结构清晰、功能分布明确的系统。开始写功能之前,往往先构造若干“轮子”(类与方法),然后让这些轮子之间协作实现功能。继承和接口的存在也让新功能的加入变得简单——添加一个子类即可,无须改变整体逻辑。写代码时也不必再时刻担心全局变量与逻辑耦合,只要专注于当下这个“轮子”是否足够“健壮”即可。
如上所说,这种结构化、模块化的模式,也让测试与调试变得更加容易。
⸻
4. 对课程的建议
我认为在每次迭代之后,如果能展示几种不同的实现思路、给出部分架构示例、并简单比较优劣,会对我这种 OOP 思维尚未成熟的同学非常有帮助。期中若能展示几份优秀代码,也能让我及时调整思路、形成正确的方向感。
否则如果从一开始思路就走偏了,迭代中很难纠正,最终会在后期出现“越写越重、越改越乱”的情况,积重难返,只能强行往下写,也会难以达到理想的效果。