2025 BUAA OOPre课程总结

胡诣涵-24371382 2025-11-12 21:27:40

一、架构设计

项目类图大致如下:

img

代码架构大概如下:

解析与控制层

1.入口与控制模块

  • Main:程序入口,仅用于完成输入解析,实例化ScannerInfo对象,调用其ScannerInput方法,将预处理后的的输入指令传进去,实现从启动到业务处理的衔接。\

  • ScannerInfo:通过commandMap实现指令映射机制,用函数式接口实现指令到行为的衔接,替代冗长的switch语句;并封装了handlFIght等处理方法,通过调用Matchadventurer类的接口,实现输入与具体操作之间衔接。

  • Matchadventurer:在本项目中作为关键枢纽,连接着解析层与实体层,管理着各个指令的实现。用ArrayList<Adventurer>记录冒险者,通过hashMap实现冒险者id到实例的快速映射,进而完成对特定冒险者的操作。同时实现了工厂模式创建新实例。

  • lexer:词法分析器,配合Matchadventurer类,通过递归下降解析lr带来的雇佣关系。

实体层

2.人物关系与属性模块

  • Adventurer:为该模块的核心,实现了EmployerEmployee接口,包含冒险者的所有属性和关系以及相关操作。

  • 物品管理:用Arraylist储存相关所有物(技能与装备、药水),同时通过实例化Package类并在其中调用Operateinpackage类进行背包管理和操作

  • 属性管理:通过add,sub等一系列函数管理hitPoint等属性

  • 关系管理:通过Arraylist记录雇佣关系,实现观察者模式进行救援操作

  • Record:实现了单例模式,类似于"石碑",用于实时记录并封装冒险者的生命值并判断是否应进行救援操作。

  • Alliance(接口):盟友接口

  • Employer(接口):继承于Alliance,雇主接口

  • Employee(接口):继承于Alliance,雇员接口

2.物品与技能模块

  • UsableThing:所有法术和物品的顶层接口

  • Item (抽象类) :实现UsableThing接口,是所有物品(不包括法术)的顶层基类。

  • Bottle:继承于Item(也实现了UsableThing接口)。其子类包括HpBottle等具体药水类。

  • Equipment:继承自Item(也实现了UsableThing接口)。包含ArmourWeapon子类。Weapon又包含SwordMagicbook子类。

  • Spell:实现了UsableThing接口,管理法术。

  • Factory:实现工厂模式的类,用于创建对象实例

架构调整及考虑

  • 在最开始的时候,我将ScannerInfo里的输入解析放在Main中,后来发现这样会导致Main中行数较多,本着模块化的原则,我将其单独封装成一个类

  • 在设计中途,由于单个方法不能超过60行的限制(好像是这么多),用switch-case语句似乎显得有些冗长,不太好调整,因此我经过上网搜索资料运用了HashMap并定义了一个函数式接口进行相关处理,从而达到简化代码并使其更清晰的目的

  • 在oopre加油站中讲解了单例模式,后面的作业中也出现了援助指令,因此想到这个时候可以利用单例模式解决冒险者血量封装问题,于是额外创建了Record类。同时根据在其中学到的工厂模式创建了Factory类,也在援助逻辑中应用了观察者模式

二、使用JUnit的心得体会

  1. 作为一个初学者,首先我了解到JUnit单元测试的概念,用自己的理解来说,大概就是针对每个类及其方法编写一套测试程序,保证每个“单元”达到预期效果,从而使整体达到预期效果。

  2. 刚开始写测试时,感觉有点多此一举,反正数据点都是自己构造,而且结果也得自己思考清楚,那直接运行程序手动输入检查不也是一样的吗,这个还更加麻烦。但实际用起来发现,JUnit确实有自己的优势,比如它不仅能对比预期结果与实际输出,还能显示覆盖率等参数,这样方便我们对没有覆盖到的地方额外构造数据进行测试,对比起来,手动测试不仅效率低,还容易漏掉边缘情况。同时,写测试用例的过程也是理清逻辑的过程。为了测试 "fight" 方法,我必须想清楚攻击方死亡、防御值高于攻击力、魔法书魔力不足等各种分支,这个过程反而能让人对整个流程更加熟悉,也有助于发现可能存在的bug。

  3. 同时还有一个小小的便捷的地方,就是虽然写的时候会稍微麻烦一点,但是后续想用之前的数据点时,就不用再进行复制粘贴了,直接运行就行,同时在框架已经搭好的前提下,想要添加样例的话也会比较容易。

三、学习OOPre的心得体会

  • 在OOPre课程的学习过程中,我逐步完成了从C语言到Java语言的转变,也实现了从面向过程到面向对象编程思维的跨越。在语法方面,Java相比C语言有着诸多改进,Java引入了更加安全的引用机制来替代C语言中容易出错的指针操作(以及IDEA会比较智能,比如空指针的时候它会报出具体位置......)。此外,Java丰富的容器库如ArrayList、HashMap等,也让数据管理变得更加高效便捷,不像C语言很多东西都要自己写。

  • 我认为最重要的收获之一是编程思维方式的转变。以往在C语言中,我们更多是在思考"如何实现一个功能"。而在Java的面向对象编程中,我们可能更应该关注"如何组织和管理代码",通过继承、封装、多态等特性来构建程序架构,很多时候在设计一个部分时不会过度去关注更底层的细节,这也是我在这门课上学到的一个重要的东西,也即“自顶向下”的思维,这个思维也可以拓展到很多其他领域。

  • 除了上面这些,在多次迭代开发的实践中,我深刻体会到代码规范性的重要意义。CheckStyle工具的使用让我养成了相比以往更好的编码习惯(起码知道了好的代码风格应该是怎么样的,包括但不限于驼峰命名法等等......),这些看似细微的细节实际上对代码的可读性和可维护性有着显著影响。毕竟当我们回顾之前单元的代码时,清晰的结构和统一的风格能够让我们更快地理解当时的设计思路。

  • 设计模式的学习也让我受益良多,尤其是OOPre加油站的帖子给了我很大的帮助。通过学习单例模式、工厂模式、观察者模式等经典设计模式,我见识到了比较优秀的代码架构,在实际开发中,合理运用这些模式能够有效降低代码耦合度,提升系统的灵活性。

总的来说,OOPre课程不仅教会了我一门新的编程语言,更重要的是培养了我的工程化思维和规范化开发习惯。这些能力将在今后的学习和工作中持续发挥作用。

四、对OOPre课程的简单建议

  1. 对于git的教程能更详细一点(最好每一步都附上图),毕竟新手刚接触真的不太会操作,只要跟着做一下之后的学起来会方便很多。

  2. 第一次作业里顺便教一下怎么看数据点过了没(刚开始以为代码风格分包括了数据点是否过了,没往下翻,结果第三次作业实际上中测没过却以为过了)。

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

271

社区成员

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

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