309
社区成员
发帖
与我相关
我的任务
分享我的代码采用了分层架构设计,主要包含以下几个核心模块:
类实现层:
Adventurer:核心冒险者类,管理属性、物品、雇佣关系Bottle及其子类:各种药水瓶的实现Equipment及其子类:装备系统的实现 Spell及其子类:法术系统的实现控制层:
Solver:作为总控制器,处理所有指令分发和协调switch (command) {
case "aa": {
addAdventurer();
break;
}
//省略,实现各种指令
}
解析层:
Lexer:词法分析器RelationShip:语法解析器,使用递归下降算法解析lr指令工厂模式:
Factory:统一的对象创建工厂,负责创建各种物品和法术然后类与类之间的关系结构如图所示:

第一次迭代建立了基础的三层结构,实现了Adventurer、Bottle、Equipment等核心类。但此时各模块职责划分不够清晰,并且尚未建立Solver类,MainClass承担了过多职责。
第二次迭代引入了属性系统和背包机制,这是架构的重要扩展:
Adventurer类中新增了hitPoint、atk、def、mana等属性,重新设计了属性的访问和修改等接口Adventurer类中增加了bottlesBag链表来管理携带的药水,实现了容量限制逻辑:public void takeBottle(String id) {
if (bottlesBag.size() == 10) {
bottlesBag.getFirst().setBag();
bottlesBag.removeFirst(); // 容量满时移除最先携带的药水
}
bottlesBag.add((Bottle)items.get(id));
items.get(id).carry();
}
Spell抽象类和AttackSpell、HealSpell具体实现,通过接口Usable统一了药水和法术的使用方式。第三次迭代进一步细化了装备系统并引入了战斗机制,同时随着指令变多,建立了Solver类来统一处理指令:
Equipment细分为Armour和Weapon,Weapon进一步分为Sword和Magicbook,建立了完整的装备继承体系:public abstract class Weapon extends Equipment {
// 武器类
}
public class Sword extends Weapon {
// 物理武器实现
}
public class Magicbook extends Weapon {
// 魔法武器实现
}
Solver的fight方法中实现了战斗逻辑,包括物理攻击和魔法攻击的不同计算方式Adventurer中新增money属性,实现了商店购买功能,通过Factory统一创建购买的物品,就像这样:public static Bottle createBottle(String id, String type, int effect) {
switch (type) {
case "HpBottle":
return new HpBottle(id, type, effect);
case "AtkBottle":
return new AtkBottle(id, type, effect);
case "DefBottle":
return new DefBottle(id, type, effect);
case "ManaBottle":
return new ManaBottle(id, type, effect);
default:
return null;
}
}
第四次迭代引入了雇佣关系系统,这使架构复杂度提升:
public boolean findBoss(Adventurer adventurer) {
if (boss == null || boss.isDead()) {
return false;
} else {
if (boss == adventurer) {
return true;
} else {
return boss.findBoss(adventurer); // 递归查找
}
}
}
cureBoss方法中实现了下级对上级的自动治疗,是一种观察者模式的应用。并且运用递归:public int cureBoss(Adventurer adventurer) {
int c = 0;
for (Adventurer adventurer1 : followers) {
// 这块省略选择最优治疗法术的逻辑
if (/*如果满足条件*/) {
c++;
adventurer1.spendMana(min);
adventurer.addHitPoint(max);
}
c += adventurer1.cureBoss(adventurer); // 递归治疗
}
return c;
}
useItem方法中加入了盟友关系检查,确保正面效果只对盟友生效第五次迭代只加了一个导入树形关系的指令,增加了语法解析功能,实现递归下降算法,Lexer类负责将输入字符串分解为token,RelationShip类使用递归下降算法解析复杂的雇佣关系表达式。
通过本课程的实践,我对单元测试有了更深入的理解。在实现一些复杂逻辑前,我先习惯地编写测试用例。
我还意识到了边界条件的重要性,比如在测试援助机制时,我特别关注了边界情况,多额外增加测试了一些特殊情况下的功能实现,比如下级没有学习治疗法术,下级魔力不足,多个下级同时治疗,死亡冒险者的处理等等。
同时,每次测评对于测试覆盖率的要求也让我认识到了测试覆盖率的价值,通过追求高测试覆盖率,我也发现了不少bug,比如我发现了fight方法中的一个隐蔽bug,当战斗失败时没有正确处理剩余输入,让我重构了输入处理逻辑。
从之前传统的写代码思维到面向对象的转变是一个充满挑战但收获丰富的过程:
在第一次迭代时,我习惯性地将大量逻辑写在一个类中,导致这个类变得臃肿。通过几次迭代重构,我逐渐理解了封装,多态的价值。将不同的功能拆分到专门的类中,并且运用了接口、继承等。通过Bottle和Spell的继承体系,我体会到了多态的强大。
第三四次迭代我也学到了设计模式的实际应用,在第四次迭代中,我自然地应用了观察者模式来实现援助机制。当下级冒险者检测到上级血量过低时,会自动触发治疗行为,这体现了对象间松耦合的设计思想。包括在Factory工厂模式中统一创建对象,在使用时通过统一的接口调用,这让添加新的药水类型或法术类型变得非常容易。
课上学习增加代码重构指导:建议在每次迭代开始前,提供一些重构的思路和实践案例。比如如何识别代码坏味,如何进行安全的重构等。
还可以提供更多设计模式的实际案例:希望在课程中能看到更多在类似项目中应用设计模式的具体例子。