1、架构设计
<1>最终架构(Class)
<2>架构调整过程
在这几次作业中,代码的结构经历了多次迭代,迭代主要以增加为主,下面介绍几次主要的增加工作:
- 增加
Bag
类。物品有了两种状态,拥有和携带,为每个Adventurer配备一个Bag
,携带的物品都放入Bag
中; - 增加
FightLog
类。新增了战斗模式,需要记录战斗模式中的操作日志; - 物品出现分类。通过继承将
Bottle
和Equipment
各自分成了三个不同种类; - 增加
Shop
类。该类采用单例模式; - 增加
Operation
类。将处理输入这一工作整合至Operation
类,从而解放main
类;
<3>架构调整过程的一些思考
- 在作业设计之初,我并未完全get到
main
应该承担的功能,并将读取输入以及处理输入这两个在逻辑上可区分的操作都写在了main
中,最终导致在后续迭代过程中出现了main
过于臃肿,无法通过代码风格检查,因此导致了本次作业的唯一一次大改———封装处理输入到Operation
; - 在第三次作业中,物品多了携带这一状态,我在最开始沿用C语言中的思路,为物品都增加了isCarried属性来记录物品是否携带,这样导致后面迭代中使用物品(携带的物品才能使用)这一操作不方便进行,因此下一次迭代中我又新增了
Bag
类;
2、Junit使用的心得体会
非常惭愧但不得不承认,Junit在我的作业中起到的作用十分有限,只有在第二次作业中Junit帮助我发现了一个Bug,后续的迭代中也是为了达到作业要求而去编写Junit。但是,这并非否认Junit的重要性,相反,在经历了这么多次的迭代、遇到了各种奇奇怪怪的Bug后,我更加意识到了Junit的重要性:
- 与常规Debug不同,Junit可以针对方法来进行测试。无需对完整的代码进行测试,通过Junit我们可以对组成类的基础——方法进行测试,这样大大简化了Debug逻辑,我们可以更精准地定位到可能存在问题的地方,同时再一些大型项目中,因为整个项目代码被分成了一个个不同的方法,所以可以多人协作同时进行Debug过程,每个人可以负责一部分方法的测试;
- Junit中有许多中assert断言测试,无需人为的去对拍比对,Junit会自动为我们监控不同属性的值变化,并精准记录存在问题的地方;
3、OOPre学习体会
- Java语言。在OOPre中,最直接的收获就是学习了Java语言的基本用法,在此之前我一直在学习的都是C语言,必须得感慨一句Java语言在应用层面的确比C语言要方便,很多基础的功能例如字符与数字间的转化、读取输入、输出等都有可以直接调用的包,同时还有容器等特点;
- 代码风格。在OOPre之前,我在编写代码时并不会过多注意到代码风格的规范问题,同时我接触到的编程作业体量都较小且不存在后续的迭代,因此代码可读性较差并未对我造成较大影响。而在OOPre中,作业的体量相较之前有了非常大的增加,同时还存在多次迭代,一旦代码可读性较差将直接影响后续迭代,我开始严格规范自己的变量命名、方法命名、代码格式等,并且增加了许多注释,极大地提高了代码的可读性,我在后续的迭代以及Debug过程也深刻体会到了这样做的好处,我能在看到某个变量或方法时立马了解其功能;
- 设计思想。在OOPre中我最大的收获就是学习到了面向对象的一些设计思想,在数据结构和程序设计课程中我并不是很喜欢使用函数,每次代码所有内容都在main里面,而在OOPre中,我第一个接触到的思想就是封装,将在逻辑上有某种关联的内容封装到一个类中,同时将各种不同的操作提取成方法,通过调用各种不同的方法来实现对类中属性的修改,这样做将不同的操作按照逻辑区分开并封装,提升了代码的复用性,同时大大地降低了代码之间的耦合度,在后续的迭代中只需针对某一个逻辑部分的内容进行增加或修改,而无需对全局进行修改;
- 严格按照逻辑进行设计。在本次作业中,有一个Bug让我感慨和收益良多,我们知道
Bottle
有容量属性和是否为空属性,在作业中我并没有将容量和是否为空这两个在逻辑上不相关的属性区分开,而是通过在Bottle
使用后将容量置为0来记录为空,但是从实际逻辑出发,Bottle
的容量应该是一个固有属性,不会随着使用而变化,这样做导致第七次作业出现Bug。这个Bug让我深刻意识到在类的设计时应该严格按照实际逻辑来定义其拥有的属性,不能从因为实际效果相同而将逻辑上不关联的属性合并;
4、课程建议
- 课程的GuideBook顺序太混乱,可以给出阅读顺序,这样方便同学们进行学习;
- Java语言和C语言还是存在一些差异,课程初可以给出一些Java语言的基础教程,方便同学们入门;