242
社区成员




我用Main类开始程序,进入OpProcess开始调用在Adventures类中的相关方法;
Adventures类中的所有方法均符合TransString和TransStringSc接口之一,大大简化OpProcess的调用。
Adventurers类会对输入进行预处理,然后选择在此处处理或者交由别的类处理。
下设Adventure类对个人的Bottle、Equipment、Food、Package类进行管理;
LogManger类完成战斗日志的处理,并且生成Log类对象保存在此处;
Store类完成商店相关操作;
Commodity 接口实现对各种价值体的管理。
在学习JUNIT后,为了方便地在JUNIT中写入数据并进行测试,我将main只作为程序入口,创建scanner并传递给OPprocess后就结束了它的使命,尽可能简短:
Scanner scanner = new Scanner(System.in);
int n = Integer.parseInt(scanner.nextLine().trim()); // 读取行数
new OpProcess(scanner,n);
scanner.close();
//这样写的话只需要在OpProcess的JUNIT中创建好一个扫描字符串的scanner,将样例或者别的数据放入字符串,将scanner传给OpProcess即可。
我采用了一种较为巧妙的方法避开了成群的if-else:
由于绝大部分的对指令的处理方法均为传入一个inputInfo的arraylist,我定义一个接口:
public interface TransString {
void passGroup(ArrayList<String> inputInfo);
}
利用这个接口实现类似于C/C++中函数指针的效果:
private final HashMap<Integer, TransString> noScanner = new HashMap<>();
//将各种操作函数的引用加入到这个哈希表即可进行轻松地调用
noScanner.put(1, manager::Adventurer_add);
noScanner.put(2, manager::Bottle_add);
.......
基于这个“函数指针”哈希表,我们可以轻松调用,就像这样:noScanner.get(operation).passGroup(inputInfo);
直接一行搞定所有if-else
由于操作的增加,我逐渐实现了package、store、log、logManager等类,较为细小,不再赘述。
直到后来操作越来越多,bug成堆出现,测试数据越来越不好造,发现直接在junit中创好一些对象要比编测试数据方便太多
对于一些实在简单的方法,我的评价是可以直接摸鱼混过去
在后续一些方法需要前置数据时(比如战斗需要先创好冒险者、装备,还要携带),直接造数据很折磨。不如直接在junit中创对象,然后进行测试,就可以只测这个方法。可以将这些数据准备放在@Before块中,在测试这个类的很多方法时都可以用。
此外,还可以为类专门写一些方便测试的方法,就像后门一样,比如:
public void adv_add_test(Adventurer adventurer) {
adventurers.put(adventurer.getId(), adventurer);
}//这个类可以不需要额外信息直接将对象加入,方便对其他方法的测试
我不怎么用assert,尽管它是今后必须的:可以直接打断点看对象内部状况对不对,差不多的效果。
总之junit是比控制台调试要方便太多了。
在调试bug之余,junit主要还是可以预防bug:比如新写了个方法,可以直接为它做一个测试再合并进git的分支做好存档,而不是写了一堆方法再测出问题了都不知道是谁错了。
以前我们学习的都是对过程的编程,一件事情该怎么办,我们拆多少步,封装到多少个函数。
而现在我们学习的oo,是一种从出发点就有所不同的思想。我们不再是仅仅思考这件事情该怎么做:我们更多的是思考这件事情在哪做,需要哪几个对象做。
一句话总结:如果说过去的对过程编程是一维的(时间维度先后分步处理),那么我们现在的oo就是二维的(空间+时间),在程序规模巨大时,oo处理起来要灵活得多。
除了开启oo这种思维之外,oopre课还能提升统筹管理的设计能力,比如一个好的架构能够大大降低开发难度和升级迭代难度。在设计之初就做好规划,oo最需要的正是这份胸中成竹。这也是我认为收获最大的地方。
建议是把中间bug那节课放到前面来,或者把弱测数据加强点。之前正听着课发现自己上次写的和上面讲的bug一样简直太炸裂了(在遍历时删除),低头一看强测0分,太刺激了。