面向对象第三单元总结
一、规格设计策略
实际上由于是重修已经在第三单元的各种坑点上积累了一定的经验,因此实现规格并不是什么困难的事情。规格叙述比较完备,虽然有些地方为了符合规格的模式需要用过多的语言来描述功能,但是基本按部就班就能比较充分理解规格的意图。规格中的数组基本因为操作时的复杂度的限制被换成了HashMap容器进行实现。
二、基于JML规格来设计测试的方法和策略
实际上规格写的很清楚,但容易出问题的往往是不同方法间的联动,另外由于复用了代码,因此边界测试,针对性测试相对而言较有效果,或者运用升成器升成大量随机测试进行对拍比较容易发现bug。
三、总结分析容器选择和使用的经验
由于有较多的对网络元素的增删查改,因此使用HashMap存储id和元素来代替单纯的元素数组作为主要的用来搭建的容器是合适的选择。在一些方法如获得最小距离是采用了堆优化的迪杰斯特拉算法,因而用到了PriorityQueue容器。此外由于每个人有getReceivedMessages及其相关方法,因此使用了LinkedList来动态存储。
四、性能问题
一方面本单元的时间与去年的要求几乎没有不同,因此服用去年的并查集以及堆优化迪杰斯特拉算法即可完成性能要求。另外有一个不是很好设计的删除冷表情包的方法,其要求不仅删除该表情,还需要删除未发送的消息。因此我构建了从表情包id到Message的id的反向HashMap来即时查询来删除。
if (message instanceof EmojiMessage) {
int emojiId = ((EmojiMessage) message).getEmojiId();
HashSet<Integer> messList = emojiId2MessIdMap.get(emojiId);
if (messList == null) {
messList = new HashSet<>();
messList.add(id);
emojiId2MessIdMap.put(emojiId, messList);
} else {
messList.add(id);
}
}
此外,对于每一组的平均年龄等方法,及时缓存,每加入一个人就增量式计算即可避免性能问题。
五、梳理自己的作业架构设计,特别是图模型构建与维护策略。
图模型方面,由于没有加入顺序的要求,基本元素均通过HashMap进行id为Key,元素对象为Value的方式进行存储。同时群组内进行及时缓存以计算群体数值,对于网络中的人而言构建并查集来实现query_circle的优化。