BUAA-OOpre总结
架构分析
功能分析
InputManage:分析输入指令,传入GameManage
GameManage:管理一个“服务器”,内含所有Adventurer,Equipment等公共资源
Adventurer:执行冒险者行为,包括添加/移除物品(从背包/从仓库),攻击,雇佣,援助,使用药水/魔法
结构图
特点
-
使用
InputManage和GameManage类管理输入以及所有可操作要素,便于进行统一管理,也便于实现要素之间的交互,如冒险者之间的攻击,雇佣,援助。 -
在管理背包物品时采用
Hashmap结构,便于进行背包容量的管理,使物品的放入拿出效率更高。 -
使用
Usable接口管理所有可使用要素,增强了可拓展性,便于管理,且减少了重复代码量。 -
采取工厂模式,添加诸如
BottleFactory,SpellFactory,EquipmentFactory类,有利于代码结构化和简化。
架构变动
共经历了两次较大的变动
-
工厂模式使用:在药水,装备,魔法的种类的区分逐渐变得频繁的过程中,我意识到每次生成时需要多行代码是十分臃肿的,于是我采用了工厂模式,建立若干
Factory,在创建物品时只需用一行调用相应的Factory类,生成方便,且分类清晰。- 同时,
Inputmanage中case量的上升也使CheckStyle不通过方法臃肿,于是在Inputmanage中也采用了工厂模式的思想,使输入分析更清晰。
- 同时,
-
雇佣功能的引入:雇佣功能带来类似有向树的结构,死亡检测变得更加迫切(因为涉及结点的删除),改变血量的手段越来越多……各种原因导致了一次不得已的大调整,
changeHP,isDead,fight等许多代码迎来大变(雾)。相比结构的巨大调整,这次是许多方法运行的优先级细节需要变动。
缺陷
-
关于冒险者的大部分行为都放在
Adventurer类里,导致此类里存了大量方法,代码行数接近500行。- 改进建议:将
fight,assist等实现要素间交互的方法置于单独的类中,既方便GameManage进行管理,也使代码结构更加清晰,便于调试。
- 改进建议:将
-
对多态与继承特性的利用不足,只在
Usable中使用了接口,以及在Bottle,Spell等的分类中使用了继承,实际上导致了一些不必要的代码重复。
Junit使用体会
-
对Junit使用的心得是层层递进的:
第一层:为了交差,对着AI照猫画虎写了一份- 第二层:开始利用Junit对一些单独方法配合
assert语句进行调试,例如使用魔法是否会造成伤害,使用药水是否能增加属性,装装备脱装备是否会改变属性。- 然而,对单独方法的测试并不是Junit的优势,并且无法测试出许多方法间联动的bug
- 第三层:使用
@Before预设好一个“游戏环境”,再从GameManage层面对一些代码进行调试,模拟一个完整的游戏过程。这样既测试到了许多方法本身的正确性,也测试到了方法是否被成功调用。
-
此外,抛出异常也是一种很好的测试方法。
-
Junit的test的文件编辑确实是有些痛苦的,为了测一个类可能要构造很多复杂的数据,重复使用一些繁琐的代码进行环境模拟。但使用Junit的优势也是十分显著的,比起以前学习C语言时通过断点和
printf语句进行调试,assert语句的使用使锁定问题更加准确快捷。
OOpre学习心得
面向对象
相比从前将一个个行为编辑成一个个函数(即面向过程),面向对象的逻辑是为不同主体创建类,并在每个类中单独管理该主题的行为,更通俗的说,我们的任务从编写一个“文件”上升到完成一个“项目”,这样的编程思想将编程视角拉到了更高维,将复杂的功能拆分为多个简单的小方法,有利于全局管理(类似GameManage类)。并且,这样的思想与生活中的思维方式也更接近。
面向对象具有封装,继承,多态三大特征,这三大特征极大的增强的项目的可读性,代码的复用性,易维护和扩展性,也有利于以后多人项目的开发。
结构化
正如上文中我画的结构图,涉及到多个主体的大型项目十分依赖结构化:每一次添加新功能时,先画好结构图以便继承与多态的管理;每一次添加新功能时,预想结构图的可扩展性以增强项目的可扩展性;每一次添加新功能后,根据结构图来调试与锁定bug……最重要的是,一张结构化的流程图真的太酷了。
向下递归
OOpre对向下递归的学习暂时较浅,但一次文法分析的练习也让我体会到了向下递归的独特优势:将复杂的问题逐步拆解成小单元,只要抓住 “拆解逻辑 + 终止条件 + 结果汇总” 三要素,就能轻松应对各类适合递归的问题。
Checkstyle
Checkstyle的使用也是OOpre课程学习的一大收获,纠正了许多不良的编程习惯:
- 变量与方法的命名格式不统一,有时采用驼峰命名法,有时用下划线连接单词,有时甚至用无意义的变量名,使用Checkstyle后,都得到了统一(驼峰命名法确实是最美观的一种命名法)。
- 将一大串逻辑一股脑的塞入一个方法中,然后喜提超过60行的警告(哭),让我进行了多次结构修改。很恼人,但如果没有这个警告,我不敢想我的项目最后是怎样的史山。
- 在一个类中加入过多的方法导致超过500行,这与我上文说的面向对象&结构化相照应,一个类中有近百种方法显然不是一个良好的结构,对扩展,调试,debug都是很大的麻烦。(例如我一开始就在
Adventurer类中加入了过多的方法,光滚鼠标滚轮找方法就看的我要目害了ヽ( ̄д ̄;)ノ)
OOpre课程建议
- 对git的学习不太清晰,只靠外部教程自学有点抓不住重点。
- 感觉bug修复半个小时的提交间隔有点长了,个人觉得和中测一样十五分钟就挺好的。
![[炽吾生平]初雪记](/img/cover_xue.jpg)