架构设计
Main类
作为程序入口,基本没有进行任何操作
Handle类
Handle类进行控制台输入的读取和分析。我在这里采用的是边读边处理的方式。主要是因为战斗日志带来了n之外的输入,为了简化输入逻辑(但是好像并没有怎么简化)。
Commodity接口
是Adventurer和Food和Bottle和Equipment的接口,技算它们的价值和类型
Store
单例模式。
Adventurer类
Adventurer类包含了冒险者的所有属性和他拥有的Bottle、equipment、food和战斗日志,几乎所有的操作都是从冒险者这个类作为起点。
Bottle类
药水的基本操作、
Equipment类
装备的基本操作、
Food类
Food的基本操作。
FightNote类
处理战斗日志相关。
Knapsack类
管理冒险者的背包
Observe类
采用观察者模式,冒险者观察冒险者血量。
我采用有什么属性办什么事的基本思路设计各个类的方法,这样虽然功能划分比较简单,但是会牺牲代码的可拓展性,往往会牵一发而动全身。
迭代过程
第一次迭代增加背包要求;第二次迭代引入战斗日志概念;第三次迭代增加雇佣,价值和类型概念;第四次迭代引入商店和援助概念。
在这几次迭代过程最让我头痛的是第三次迭代,即第六次作业。由于加入了新属性,我几乎重写了所有构造方法,这次迭代体现我构造方式的不足,不能适应新属性加入。
其次引入新模式后就必然会有对之前操作的重新应对,我之前是复制以前代码,稍作修改再增加一个类,这产生了很多重复代码。
有一处重大失误,在设计时吧药水瓶容量和药水的含量当成一种东西。在没有用到容量的时候没有任何问题,但是商店计算容量时就出现了“稀释”现象。在设计时没有仔细考虑。
而且,我在计算药水或武器的恢复/伤害时,采用返回武器属性的方法,但添加新类型时处理就很麻烦,最终选择把冒险者对应属性传到Equipment类计算伤害量,这样新类型可以直接覆写。
Store生产商品的时候,一定会有对类型的判断,所以我在Store写了对应的构造方法,不同判断结果选择不同方法。
junit心得体会
junit在确定每方面代码的正确性起了很大的作用。这种正确性是以测试样例的全面完整为基础。在我代码开发过程中,junit单元测试并没有产生很大的作用,原因在于一个人手写各种可能发生的情况是一件非常耗费时间和精力的事情,处于这种考虑,我只写了课程组覆盖率的最低要求。(这让我最后一次作业遭受了重大失败
)
单元测试:保证每个方法或分支的正确性对维护代码整体正确性和稳定性有至关重要的作用。
oopre心得体会
第一点:高内聚和低耦合。我在实际编程体验中初步理解了它的重要意义。一个类需要的功能尽量放在它自己身上完成,降低对外界的依赖,这样修改时就可以只在一个类内修改。就比如,我最开始添加装备等物品时,是把对应属性一个一个传到Adventurer内,这其实隐含了类型的判断,增强了对外界依赖。
错误示范:
adv.addBottle(Integer.parseInt(copy.get(2)), copy.get(3), capacity);
更好的做法是把整个copy数组传过去,再进行想要操作。
在举个例子是:计算武器伤害量:
this.hitPoint -= star * level;
它先获取Equipment的star属性,再在Adventurer类里面计算,但是如果Equipment属性和计算伤害的方法增多,就很难适应和处理。应该直接在Equipment类内算出伤害量。
当代码耦合度过高,对其他类依赖过强时(这个类处理一点,那个类处理一点)就会使代码增量开发困难度增加,会导致多个类且不止一处的修改,很容易修改遗漏,产生难以发现的bug。
第二点:模块化编程。这种编程方法使代码分块,逻辑清晰。很容易知道一个模块、一个分支在做什么,这对代码的理解和之后的增量开发起了很大的作用。
for (int j = 0; j < k; j++) {
String oneNote = inputInfo.get(j);
Matcher mt1 = pt1.matcher(oneNote);
Matcher mt2 = pt2.matcher(oneNote);
Matcher mt3 = pt3.matcher(oneNote);
if (mt1.find()) {
this.operate(fightName, team, mt1);
} else if (mt2.find()) {
this.operateTwo(fightName, team, mt2);
} else if (mt3.find()) {
this.operateThree(fightName, team, mt3);
}
}
这是对战斗日志的操作,不断细分的模块即方便了代码开发(思路更加清晰),也容易理解。在模块化开发中,面向对象的风格检查功能在很大程度上帮助了我。
oopre课程建议
建议课程组加强代码风格的要求,加强这方面分值占比。
加强junit覆盖率的要求,鼓励同学们做好单元测试。