2025-BUAA-OOPre课程博客作业

冯京玺-24371531 2025-11-06 23:37:30

2025-BUAA-OOPre课程博客作业

一、架构设计

最终架构

项目采用分层架构:

1. 表现层

  • Main.java
    • 程序的入口,负责按照依赖关系初始化所有核心组件,然后启动命令处理循环。
  • Command.java
    • 命令处理器,从标准输入读取命令,并根据命令关键字调用 Function 类中相应的方法,并接收和向标准输出流输出字符串,涉及 lr 指令的调用 parser 中的方法。
  • parser (package)
    • 解析器模块,利用递归下降法处理 lr 命令的复杂嵌套字符串,包括 Token.java (词法单元), Lexer.java (词法分析器), Parser.java (语法分析器)。

2. 应用层

  • Function.java
    • 该类封装了所有用户命令对应的业务逻辑,连接表现层领域层
  • Context.java
    • 管理所有的 Adventuerer 实例,持有一个 Map 来存储和检索,为整个应用提供了一个统一的数据访问点。

3. 领域层

  • Adventurer.java

    • 核心领域实体,不仅包含数据,还包含了部分业务逻辑,如:
      • 管理自身的物品和装备。
      • 维护雇佣关系并提供关系查询方法。
      • 计算战斗属性。
      • 处理死亡后的状态变化和关系解除。
      • 发起和处理求助事件。
  • AidEvent.java

    • 领域事件对象,当冒险者生命值过低时创建,用于封装一次求助事件,收集盟友的治疗法术并选择最优的进行治疗。
  • domain.items (package)

    • 物品子系统,结构清晰,利用了继承和接口实现多态。

      • Item.java
        • 所有物品的抽象基类。
      • Bottle.java, Equipment.java, Spell.java
        • 分别是药水、装备和法术的抽象基类,它们继承自 Item 并定义了各自的共同属性。
      • 具体物品类
        • 实现了具体的物品行为,可使用的物品通过实现 Usable 接口获得 use() 方法。
  • Usable.java

    • 关键接口,定义了可使用物品的行为 use() ,被药水和法术实现,使得 Function 类可以统一处理不同类型物品的使用逻辑。
  • ItemFactory.java

    • 工厂模式的应用,物品的创建逻辑集中管理,**Function** 类无需知道具体物品类的构造细节,只需提供类型和参数即可创建实例,降低了耦合度。

架构图示

架构图示


(使用PlantUML生成)

架构考虑

从各次迭代的视角看待:

第一次迭代

第一次迭代时,为了避免过度使用静态方法,考虑将架构调整为分层式的架构,在 Main 方法内部构建 Context.java -> Function.java -> Command.java 的依赖关系,通过依赖注入实现了各层组件之间的解耦,增强了可测试性和可扩展性。

第二次迭代

第二次迭代细化了物品种类并且增加了物品功能,考虑将 itembottlesequipmentspells 作为包,实现了模块化管理。在 item 中, Item 作为所有物品的顶级抽象父类;在 bottleequipmentspells 中, BottleEquipmentSpell 又作为各自实现类的中间抽象父类。另外,将 Usable 作为可使用物品共同实现的接口,也使得可使用物品可以共同管理。通过以上架构,基本实践了面向对象编程的继承性和多态性。

第三次迭代

第三次迭代架构方面的变化主要在于,实现了 ItemFactory 作为工厂模式的实践,并将核心类的依赖关系调整为 Context.java / ItemFactory.java -> Function.java -> Command.java ,使职责更加分明。

第四次迭代

第四次迭代主要增加了雇佣关系,其中架构方面的调整在于增加了 AidEvent 类,单独实现一个事件类可以避免在复杂的依赖关系之间来回传递参数,使得逻辑大大简化,同时与 Adventurer 实体解耦。

第五次迭代

第五次迭代主要增加了梯度下降法实现的嵌套关系分析,架构层面的变化主要是增加 parser 包,并在其中实现 Token.java (词法单元), Lexer.java (词法分析器), Parser.java (语法分析器),并在 Command 中调用,避免 Function 功能复杂化,保证了单一职责原则。

二、Junit使用心得体会

  • Junit单元测试主要针对模块进行测试,使用单元测试可以在小范围内进行调试,而不用以整个项目为单位进行调试,并且能够将问题定位到某一个具体的类或者方法,降低了调试难度。
  • 使用Junit测试可以强迫自己进行模块化设计,并且降低类之间的耦合度,否则的话单元测试可能编写起来可能十分困难。

三、OOPre学习心得体会

  • 在OOPre的学习过程中,我初步地体会到了面向对象编程的思想。比如封装,体现在各个类将数据与方法封装在内部,外部只需要考虑调用这些方法;继承,体现在物品类的层级继承,使代码可以复用,并且提高了代码的逻辑性;多态,体现在不同的可使用物品实现 Usable 接口,提高代码扩展性。
  • 在OOPre的迭代作业中,我们不仅需要考虑代码行为的正确性,更要考虑代码的可读性和可扩展性。在每次迭代中,我都尽可能考虑下一次迭代时代码修改的难度,在这个过程中,我不仅学会了面向对象的基本特性,还了解了一些专业术语,比如单一职责原则,开闭原则等设计原则,只需要简单考虑应用这些思想,就可以大大提高项目各部分的可读性、可维护性和可扩展性。
  • 总而言之,在OOPre的各次迭代作业中,我们不仅需要考虑项目能不能跑,更需要考虑架构的合理性、下一次迭代的可扩展性、以及在庞杂的代码中的可读性。经过各次迭代的锻炼,我希望我对编程有了更深入的理解。

四、对OOPre课程的建议

  • 希望课程组可以介绍一些面向对象架构设计方面的知识。
...全文
40 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

270

社区成员

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

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