OOpre 课程学习总结

刘彦希-24371147 2025-11-06 17:36:04

作业架构与迭代调整

最终架构:

该项目的核心操作均围绕冒险者(Adventure)进行,包括但不限于冒险者属性维护、装备维护、技能维护以及战斗系统。所以我们大可将Adventure作为主要类,围绕该类进行操作。

首先,我们需要先行读入并解析指令。随着整体指令需求数的增长,最终我选择将指令读入和读入解析分开,指令读入集中于MainClsss,指令解析集中于Inputmanage。并在指令解析模块根据该条指令的类型引用存在于Adventure中的方法。

Adventure类的功能众多,核心在于管理角色的基础属性(生命值、攻击力、防御力、魔法值、金钱)、物品/技能持有、战斗行为、人际关系(上下级/盟友)等。所以在Adventure类中,我们对以上信息分别实例化,以方便面向冒险者对象进行维护操作。

但显然,并非所有的信息都可以直接用单一变量进行描述,例如魔法,一个魔法具有名字,类型,魔力消耗和效果四个数据。于是我们考虑对这类信息分别建立类,并通过保存类的方式在Adventure类中保存各冒险者的信息。

值得注意的是,魔法,药水,装备这三种信息非常特殊。魔法分为攻击魔法和治疗魔法,药水分为体力,攻击,防御,魔力四个类型,装备有武器和防具,武器又分为剑和魔法书。他们虽然有不同的作用效果,但是其使用模式大体相同,我们在魔法,药水和武器三个抽象类下,通过继承的方式实例化不同的魔法,药水和装备,使得其便于维护。

  • Equipment(抽象类)
    • Armour
    • Weapon(抽象类)
      • Sword
      • Magicbook
  • Bottle(抽象类)
    • AtkBottle
    • DefBottle
    • HpBottle
    • ManaBottle
  • Spell(抽象类)
    • AtkSpell
    • HealSpell

然后是针对指令的实现,我们总共建立了四个类以实现大部分对应的功能:

  • 行为接口Usable - 定义use方法,实现多态使用机制。
  • 工厂类MonoFactory - 统一创建各种物品,封装实例化逻辑。
  • 关系管理类HireGraph - 管理冒险者间的雇佣关系,支持上下级查询。
  • 语法解析类Lexer - 词法分析器,分词处理,Parser - 语法解析器,构建雇佣关系树。(为批量添加关系服务)

最后是fight逻辑,这一指令可以直接在Adventure中实现,this对应的便是攻击的发起者,这样可以方便直接更新参与战斗的冒险者的属性。

架构调整

很显然,我们并没法在项目开始时直接构建出这样的一个架构。事实上经历多次重构是必要的。

1.重构指令指引系统。

最初,我选择将指令读入与指向指令对应模块的功能均集成在MainClass中。这样有很多好处,最显著的就是可以读一条指令进行一条指令,不需要一次性读完所有指令后再执行。但是随着指令的增多,这样的方式必然会导致行数超过checkstyle的要求,于是最终选择将读入指令和指向指令功能模块分开,单独建立一个类以实现指向指令功能模块,这使得后续添加指令不会影响到指令读入,也减少了行数,满足了checkstyle需求。

2.行为接口use单独建类

在P3时,我选择将use操作存放于Adventure类中。但是随着魔法的加入,use的长度逐渐不可控。于是最终选择将use操作单独建类,并根据use的类型(魔法or药水)划分为二。这在P6得到了回报,由于援助机制在攻击魔法发动时仍可能生效,将use分为魔法和药水可以极大的减少中间判断,简化了流程。

JUnit的心得


体会

JUNit是我们debug和面对强测最有力的工具,总体来说,我们可以使用两种方法来使用JUNit进行测试。

1.分模块测试

随着迭代开发的进行,我们最终面对的必然是一个数千行,非常巨大的代码群,这使得我们传统的debug方式很难以进行。于是我们应该利用JUnit可以针对一个特定的部分进行测试。通过建立一定的情景使用某一模块(可以是一个指令,抑或是一个接口),从而检测该部分功能的正确性。

2.构造样例

但是我们很快发现,我们的错误不仅存在于模块的功能实现错误,还有可能出现一些类似于冒险者生命为0,援助进行等逻辑上的错误,这时我们需要考虑整体测试。于是我们可以自行构建样例,通过测试InputMange部分,直接带入指令。我们可以非常容易的找出逻辑问题。

学习OOPre的心得体会

建立面向对象编程的思想是艰难的,其与C语言程序设计有巨大的区别。结合我自己的思维链路,我觉得有一点是非常值得借鉴的,即:面向逻辑->功能模块化->面向对象

我们可能很难在一开始就进行面向对象的设计,但是我们大可在一开始让自己的代码模块化,就好如在C语言中大量使用函数让自己的main函数精简。这虽然离真正的面向对象仍有距离,但是这易于实现,而且很容易重构,从而让我们的项目逐渐面向对象起来。

然后是设计的原则,我总结下来如下。

  • 一个类只实现一个功能
  • 每个类保留尽可能多的接口
  • 学会使用抽象类,这能够保证你的各个类能够直接逻辑相连

上述原则最终的成果便是工厂模式和策略模式,这能保证最大程度的复用与可扩展性。

对OOpre课程的建议

  1. 增加真实面向对象编程项目的展示。很悲伤的是,经过学习,我能够粗浅的实现一个面向对象项目,却看不懂隔壁CO工具Mars的底层代码。
  2. 增加重构训练。用Checkstyle驱动同学们去重构固然好,但是说实在,到最后2P虽然经过了多次重构,但是我仍然对自己的架构不是很满意。
  3. 在课程早期提供往届学长的架构图。我觉得我真正认识到面向对象的思想是在水群中看到了一个往期学长的超级完美的架构图,这一下子就让我理解了工厂模式等当时还没有讲解的概念,而且真正刻意的去面向对象,这让我后期的扩展非常轻松,而且确实得到了很高的收益。

通过这门课程的学习,我不仅掌握了Java编程和面向对象的基本概念,更重要的是培养了抽象思维系统设计的能力。这些能力将在未来的软件开发生涯中发挥重要作用。感谢课程的精心设计和老师的悉心指导!

...全文
39 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

270

社区成员

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

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