2025-BUAA-OOPre-第八次作业-课程总结

一、作业最终的架构设计, 在迭代中的架构调整及考虑

1.最终架构设计:

共20个类,1个接口use,其中 Equipment 和 Bottle 是 abstract类。

PS:继承关系用的黑色箭头,应用接口用的白色箭头,调用用的单线箭头。

2.迭代中架构调整及考虑:

(1)架构调整一:增加 CommandHandler 和 InputProcesser

// 调整前:Main类一不小心就会超过行数限定,过不了CheckStyle
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        HashMap<String,Adventurer> adventurers = new HashMap<>();
        
        int n = Integer.parseInt(scanner.nextLine());
        for (int i = 0; i < n; i++) {
            String line = scanner.nextLine();
            String[] parts = line.split("\\s+");
            // 大量if-else处理各种命令...
        }
    }
}

// 调整后:各司其职,Main只需要使用以下两个类,简洁许多
public class InputProcessor {
    public void processInput() {
        // 只负责输入读取
    }
}

public class CommandHandler {
    public void handleCommand(String[] parts) {
        // 只负责根据指令调用函数
    }
}

调整后,每个类只负责一个特定功能,Main 类不用担心超过规定行数。

(2)架构调整二:创建Use接口

public interface Use {
    void use(Adventurer target);
}

//Bottle和Spell都实现这个接口
public abstract class Bottle extends Item implements Use
public abstract class Spell implements Use

// 调整前
if (item instanceof HpBottle) {
    target.changeHitPoint(effect);
} else if (item instanceof AtkBottle) {
    target.changeAtk(effect);
} // ...更多else if

// 调整后
usableItem.use(target);
  • 原因:Bottle和Spell都有use方法,但代码重复,使用时的类型判断复杂,需要大量instanceof检查。
  • 好处:所有"可使用"的物品有统一接口,新增可使用物品只需实现Use接口,无需修改使用代码。

(3)架构调整三:增加Lexer和Parser

lr命令的输入格式复杂:A(B,C(D,E)) ,需要解析嵌套结构

增加两个类,将解析问题分为词法+语法两个阶段:

  • Lexer:词法分析,将输入字符串分解为token。

  • Parser:语法分析,根据语法规则构建对象关系。

总结:

  1. 发现重复,提取共性抽象:Use接口

  2. 内容过多 ,分解模块:CommandHandler、InputProcessor

  3. 复杂度增加 ,特别的解决方案:Lexer、Parser

二、使用JUnit的心得体会

1.找到隐藏 bug:

在JUnit 中设计边界情况异常情况的测试用例,提前发现了代码中未处理的问题,帮助自己debug。

2.增加重构自信:

在架构调整过程中,如果修改代码较多,难免担心会改变原来已经实现的功能。使用JUnit,可以快速验证原来的功能是否没有改变。

例如在上下级关系的存储设计中,我一开始是每个冒险者管理所有下级,这样会导致存储空间不足;修改成每个冒险者只管理直接下级后,运行JUnit发现原来的方法都全部通过测试,让我确定我在修改过程中没有引入新的bug。

3.培养良好的方法设计习惯:

为了让方法便于测试,我会不自觉地减少方法间的依赖,避免编写过长的复杂方法。这让我在编码时下意识去保证方法的单一性独立性,养成了好习惯。

三、学习OOPre的心得体会

1.从面向过程到面向对象的思维转变

面向过程编程中,我们通过函数的顺序调用实现功能。比如完成一个 “战斗” 指令,可能会先写 “计算攻击力”“扣减生命值”“判断胜负” 等一系列函数,再按顺序执行。

但在面向对象编程中,我们关注的是“谁来做” “做什么”。先识别场景中的对象,再定义对象的属性和行为,最后通过对象间的相互调用实现功能。

这种转变让我意识到,面向对象思维能让代码结构更清晰,尤其是在复杂场景中,对象的独立封装降低了代码的耦合度,让逻辑更加清晰。

2.抽象化思维的深化

抽象化是从具体事物中提炼共性,忽略细节,用更通用的概念描述问题,从而提升代码的复用性扩展性

例如,Item是对 Bottle和Equipment的抽象,它们都有 id、type、效果值,因此被抽象为抽象类 Item,统一定义这些共性属性和方法,而具体的 Bottle 和 Equipment 只需关注自身的特有行为,如 Bottle 的 use 方法。

再如Use接口抽象了“使用”这一行为,无论是 Bottle 还是 Spell,只要实现 use 方法,就可以被 Adventurer 的 useItem 统一调用,无需关心具体是药水还是法术。

四、对OOPre课程的简单建议

  1. 讲解核心知识点时,多搭配简短代码示例,因为新学一门语言刚开始确实是无从下手,只能先模仿,然后再融会贯通。
  2. 讲设计模式时,可以增加一个“无模式实现”与“用模式实现”的优劣对比,因为我看完教程其实没有很明显感受到加上设计模式的优势,加上对比或许能让我更好理解设计模式的作用。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值