面向对象课程第三单元总结
设计策略
总结分析自己实现规格所采取的设计策略
本单元作业中我实现规格大致按照以下流程:
-
查看给出类之间的关系和主要方法,总体上大概明白要做的事情
-
按照作业要求指导书实现异常类
-
逐个类查看方法(简单浏览规格+根据方法名推断),决定使用的容器,并实现逻辑较简单的方法
-
对于较复杂的类,仔细查看规格,理清规格逻辑,将规格长句分步转换成代码
-
对于可能会超时的方法进行更改优化(可能需要更换或者增加容器)
-
再次对照规格,检查所有代码的正确性
测试方法
结合课程内容,整理基于JML规格来设计测试的方法和策略
根据课上内容,基于规格的测试的框架如下:
Test Trigger:
使用测试数据构造被测对象、调用被测对象方法、获取执行结果
以对象状态为目标,构造状态迁移操作,在具体状态中执行观察操作和进行判断
Test Checker:
使用测试数据和被测对象的查询方法检查执行结果
设计方法检查不变式和修改约束涉及的数据
Test Data Manager:
提供数据访问更新接口,针对方法、数据规格设计针对性数据
根据前置条件设置数据、方法输入参数,动态调整后置条件涉及的数据
其中Test Checker可以使用JUnit进行测试
JUnit的Assert类中的断言用来程序执行结果是否与预期一致,如判断是否相等、是否为空等
JUnit还有一些注解,@Test规定测试案例,例如@Test(timeout=1000)
可以测试是否超时,@Before等注解可以规定执行顺序、创造释放对象
容器选择
总结分析容器选择和使用的经验
本单元作业我使用的容器包括HashMap
,ArrayList
,HashSet
需要快速根据Id
获取对象,且不要求存储顺序的我都使用了HashMap<Integer, ClassName>
,包括MyPerson
中的value
和acquaintance
,MyNetWork
中的people
、groups
、messages
、emojiHeated
,MyGroup
中的people
由于每个人对应的信息在getReceivedMessages
需要按照顺序输出,MyPerson
类中使用ArrayList<Message> messages
存储信息
为了降低计算queryBlockSum
的计算时间,我使用ArrayList
存储不同连通块,每个块是一个HashSet
,添加两个互不连通的人之间的关系时就将两个HashSet
合并,即在MyNetwork
中通过ArrayList<HashSet<Integer>> blocks
作为连通块的容器
性能问题
针对本单元容易出现的性能问题,总结分析原因;如果没有出现,分析自己的设计为何可以避免
比较容易超时的方法:
queryBlockSum
:统计联通块的个数
/***MyNetwork.java***/
//将所有连通块存储在blocks中
private ArrayList<HashSet<Integer>> blocks = new ArrayList<>();
//addPerson增加连通块
HashSet<Integer> newBlock = new HashSet<>();
newBlock.add(id);
blocks.add(newBlock);
//addRelation可能会合并连通块
HashSet<Integer> block1 = getPersonBlock(id1);
if (!block1.contains(id2)) {
HashSet<Integer> block2 = getPersonBlock(id2);
blocks.remove(block2);
block1.addAll(block2);
}
//getPersonBlock获取某个人所在的连通块
private HashSet<Integer> getPersonBlock(int id) {
for (HashSet<Integer> block : blocks) {
if (block.contains(id)) {
return block;
}
}
return null;
}
//queryBlockSum获取联通块个数
return blocks.size();
sendIndirectMessage
:
Dijkstra算法:选择起点,将同一连通块中其他点设置为点集s,初始化s中所有点距起点最短距离minLength为\(∞\),更新与起点相连的点的minLength为边的权重。循环每次选择s中距离最小的点p,遍历所有与p相连的点根据边的权重更新minLength,重复上述操作直到选到终点为止。
堆优化:通过小根堆维护当前未标记过且离起点最近的点。
架构设计
梳理自己的作业架构设计,特别是图模型构建与维护策略
本单元中Person
为图的结点,关系Relation
为图的边,通过blocks
存储连通块;groups
为点集,将具有某些关联的点放在一起,统计一些群体性质(年龄均值、方差,社交活跃度);信息message
为某结点传向单个结点或者点集,涉及到最短路的问题
构建:通过addPerson
添加结点和连通块,addRelation
增加边和合并连通块,addGroup
增加点集、addToGroup
向点集中增加点,addMessage
增加未发送的信息
维护:delFromGroup
从点集中删人,sendMessage
将信息分配给对应的人并从未发送信息序列中删除(sendIndirectMessage
选择最短路进行传递),deleteColdEmoji
删除使用频率低的表情
(图模型建构维护是指的这个吗QAQ,感觉自己写了一堆废话)