OO第四单元总结

OO第四单元总结

第四单元架构设计

类图模型

主要采用HashMap容器表示类包含的属性方法,以及继承、关联等关系

 private final HashMap<String, Integer> subClass = new HashMap<>();
//classId -> subclass_number
private final HashMap<String, String> classExtend = new HashMap<>();
//classId -> classExtend.id
private final HashMap<String, ClassOperation> classOperation = new HashMap<>();
//classId -> operations
private final HashMap<String, ArrayList<UmlAttribute>> classAttribute = new HashMap<>();
//classId -> attribute
private final HashMap<String, HashSet<String>> classImpleInter = new HashMap<>();
//classId -> interfaceId
private final HashMap<String, HashSet<String>> interExtend = new HashMap<>();
//interfaceId -> interfaceId
private final HashMap<String, UmlAssociationEnd> association2end = new HashMap<>();
//associationId -> AssociationEnd

对类图中的UmlElement进行分层,依次处理,可以保证处理该元素时parent一定存在,最上层是UmlClass和UmlInterface,接下来是UmlGeneralization, UmlInterfaceRelization, UmlAssociation, UmlAttribute和UmlOperation,最后是UmlParameter和UmlAssociationEnd

对于错误检查,R003采用深度优先搜索方法,R004采用广度优先搜索算法。

顺序图模型

顺序图模型分成四层进行处理

for (UmlElement element : elements) {
parserInteraction(element);
}
for (UmlElement element : elements) {
parserAttribute(element);
}
for (UmlElement element : elements) {
parserLifelineAndEndpoint(element);
}
for (UmlElement element : elements) {
parserMessage(element);
}
状态图模型

查询关键状态时,先对原始的图进行广度优先搜索,看是否存在关键状态。然后去掉查询的状态相关的边,再次进行广度优先搜索,看是否能到达Final State

if (!hasKey) {
return false;
} else {
String stateId = stateName2id.get(stateName);
HashSet<String> canGetTo = new HashSet<>(matrix.get(pseudostate));
canGetTo.remove(stateId);
ArrayList<String> queue = new ArrayList<>(matrix.get(pseudostate));
queue.remove(stateId);
while (!queue.isEmpty()) {
String tmp = queue.remove(0);
if (finalStates.contains(tmp)) {
return false;
}
for (String i : matrix.get(tmp)) {
if ((!i.equals(stateId)) && (!canGetTo.contains(i))) {
canGetTo.add(i);
queue.add(i);
}
}
}
return true;
}

架构设计思维

第一单元

在这一单元的作业中,主要学习到了递归下降的思想,面向问题分解与归纳的层次化设计。尤其在第一次作业尝试过正则表达式方法后,我发现递归下降可以将繁杂的任务进行分解,逐一解决。这使代码的架构更加有层次,思路更清晰。迭代开发则需要各类高内聚低耦合,函数功能简单明确。

第二单元

第二单元主要是电梯多线程的问题,还有一些设计模式。最终我发现线程安全不应该建立在对各种情况分类讨论的基础上,而应该优化架构、减少使用共享数据、避免出现线程安全问题的可能。在本质上属于面向并发控制与安全的层次化设计,需要明确共享数据有哪些,各个线程的工作是什么。

第三单元

本单元主要学习了基本的JML规格和基于规格的层次化设计,JML准确地定义了数据和方法的设计要求,从而可以通过逻辑方式来验证代码的正确性。数据的规格与数据的具体实现方式无关,因此仍然需要选择合适的容器存数据。JML在表示某些复杂的情况时,可能会比较繁琐,例如queryLestConnection中求最小生成树,需要花很长时间理解,同时编写这类JML时也需要思路非常清晰。其中为了便于表述,定义了subgroup和connection来描述最小生成树的特征,而非从直观的角度表示最小生成树。queryBlockSum的情况也类似。自然语言中对连通块和最小生成树的定义使用了很多已经定义过的概念,而JML语言中不支持定义,因此自然语言和JML表示有所不同。此时,使用自然语言更加便于理解。

但在写第四单元的作业时,我也认识到了JML的好处。自然语言中对方法的表述可能有歧义,通常也不会覆盖所有情况,可能导致理解有误。这种时候就需要JML对方法的正确性进行准确的定义。

第四单元

第四单元主要学习UML模型,是面向复杂数据管理的层次化设计。处理UML模型时需要分层进行,从而保证处理该元素时parent一定存在,不会出现乱序。此外,存储数据时也需要进行分层。面向对象本质上也是一套抽象语言系统,词汇有对象、属性、操作、活动等,语法有对象间连接、对象与数据间连接、属性与操作间连接等等。

UML语言可以更准确、直观、简单地表达思维。它直接提供有针对性的、分离的结构与行为描述手段,而且可以将描述元素整合起来。

测试

本学期每个单元我都是手动构造数据来测试,测试的覆盖率较低,而且只能测试已经在写代码时想到的情况的正确性,对于没有考虑到的情况无法进行测试。前两个单元都是对所有可能的情况进行分类讨论,对每一种情况构造数据进行测试。第四单元主要的问题是对于题目的理解有误,还有一些没有想到的情况。第三单元有JML规格后可以保障测试数据的覆盖率,但仅用后置条件和约束条件对结果进行判断无法保证结果完全正确,仍需要对拍。此外,对于代码性能的检测也需要额外构造数据。

课程收获

四个单元的学习虽然各有侧重,但主要思想都是层次化设计。分层的处理可以将繁杂的任务进行分解,逐一解决。这使代码的架构更加有层次,思路更清晰。迭代开发也需要代码的架构清晰,尽量与它所描述的对象贴合。同时,每个单元都接触到了不同的内容,递归下降、多线程、JML、UML、图模型都是完全不同的内容,是对知识面的补充和拓展。

此外,在面向对象课上我养成了更好的代码风格,给属性和操作起名字时也尽量更准确。代码量也比以往解除过的更大,有了处理更大规模的代码的经验,为以后的课程打下基础。

改进建议

  • 希望在第二单元开始之前能有更多对线程的讲解

  • 课上有些内容比较抽象,只用文字描述有点难以理解,希望能有更多实例

  • 第一单元虽然采用了面向对象的方法,但递归下降本身有点面向过程的感觉。一开始的时候对面向对象的理解还不够,和递归下降混在一起就更不容易理解什么是面向对象。

posted @ 2022-06-29 10:12  rmfl  阅读(30)  评论(0编辑  收藏  举报