OOPre_博客作业

赵婉彤-24373243 2025-11-17 22:07:05

一、代码架构

img

  1. 控制层
    CmdProcessor    指令实例化与分发(类似于指令工厂)
    Command         指令类
    
  2. 实体层
    Adv             冒险家,是游戏中心类,绝大多数指令解析时的主体(除了最后一次迭代)(备注:雇主、雇员接口)
    Bottle          (备注:消耗品)
    Equip           (备注:武器、护甲、魔法书)
    Spell   
    
  3. 数据层
    Stats           冒险家属性管理(hp、attack、defpower、money)
    ItemType        枚举类型(包括所有有类型的东西的类型)
    Constance       全局常量
    
  4. 业务逻辑层
    FightField      战场
    Store           商店系统
    WorldLibrary    关系/互动记录(战前存档、友军判断)
    
  5. 工具层
    GraphMaker      雇佣关系图构建器
    Lexer           语法分析器
    

二、迭代开发

输入处理:

因为第一次面向对象编程,感觉搭这个冒险家游戏,什么战斗、买东西之类的都好说,让我花最多时间、重构次数最多的,是输入处理的逻辑。反反复复写了好多次,从最开始的 随用随输入(就很离谱),到把输入处理都堆在 Main class 里(被 JUnit hack 了),再到在 AI 建议下造指令工厂,专门弄了一个 Cmd class,还是有点丑,但也够用了。

Command class,把 指令 视作可实例化的对象,指令的属性:

private final String op; // 指令的类型
private final String advId; // 发现每一条指令都有冒险者 id
private final String[] args;

输入解析(把一行输入整理成我的Command类), CommandProcessorClass核心的指令处理器,传入整理成 Command 类型的指令数组,相应指令。冒险家名单自然也是在这里。

处理方法—— Consumer 函数式接口

观察发现,每个方法都需要

  1. 查找涉事冒险者(主动方/第一个)
  2. 检查冒险者是否存在且存活(死亡则打印死亡提示词)
  3. 执行具体操作

设计 withAdv 方法来处理公共部分:

private void withAdv(String id, Consumer<Adv> action) {
    Adv adv = getAdv(id);
    if (adv != null) {
        action.accept(adv);
    }
}

Consumer 把一段代码当参数传递,在需要的时候执行, 描述 “找到冒险家之后该对他做什么”,把里面的方法 accept(Adv adv) 作为参数传给 addBottle。把变化的操作逻辑从固定的查找逻辑中分离出来,从而实现重复逻辑的合并。

三、JUnit

  1. 我的 CmdProccessoradv 设成了静态的,给测试造成了很大麻烦,因为它们互相影响。
    CmdProcessor.getAdvs().clear();
    

四、面向对象

  1. 封装:与简单的函数封装不同,面向对象编程的封装是将属性和方法封装在一起,实现了对外隐藏或不隐藏,可以实例化成对象。
  2. 继承+多态:想起来学数据结构的时候手动 copy 一个和子节点有微妙不同的父节点。

五、OOPre

非常有趣且令人愉快的课程,虽然我猜下学期就是有趣但不愉快了。
建议:

  1. 增加开始迭代作业前的练习数目,一无所知地开始迭代会导致重构,重构不是很愉快 : (。
...全文
36 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

270

社区成员

发帖
与我相关
我的任务
社区描述
2026年北航面向对象设计与构造
java 高校
社区管理员
  • 孙琦航
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧