其他分享
首页 > 其他分享> > oo期末总结

oo期末总结

作者:互联网

OO 总结

目录

总结本单元作业的架构设计
总结自己在四个单元中架构设计思维及OO方法理解的演进
总结自己在四个单元中测试理解与实践的演进
总结自己的课程收获
立足于自己的体会给课程提三个具体的改进建议

本单元总结

作业要求与实现细节

hw13

查询指令(仅限类图)

作业整体分为了两个部分

层次划分

首先,由于类图中各个元素存在依赖关系,且输入时乱序输入,所以有必要将各个元素划分为不同层级

  1. class、interface
  2. attribute、operation、interfaceRealization、associationEnd
  3. parameter、generalization、association

完整的顺序是:

  1. class、interface、collaboration、statemachine
  2. attribute、operation、interfaceRealization、associationEnd、region、interaction
  3. parameter、generalization、association、lifeline、preudostate、state、finalstate
  4. message、transition
  5. event

每一层级封装为一个while循环的函数,依次处理

Tool工具类——数据结构

之后,完成各个查询指令,为了解决元素间重名的问题,新建了一个工具类Tool并定义了若干查询功能

public class Tool<T>{
    private HashMap<String, T> id2element = new HashMap<>();
    private HashMap<String, ArrayList<T>> name2element = new HashMap<>();
}

这一数据结构被广泛应用于元素的存储,同时可以借助这一数据结构完成相应的查询以及异常的判断

instruction7——查询所实现接口

类实现接口有三种方式:

为此,该指令的实现思路为:

  1. 找到查询类的所有“祖辈”
  2. 获取各祖辈所实现的接口集合(从已有接口获取其祖辈接口)
        HashSet<MyInterface> interfaceSet = new HashSet<>(interfaces.getValue());
        HashSet<MyClass> fatherCollection = new HashSet<>();
        MyClass tmpFather = father;
        while (tmpFather != null) {
            fatherCollection.add(tmpFather);
            tmpFather = tmpFather.getFather();
        }
        //从father集合获取各father直接实现的接口
        for (MyClass f : fatherCollection) {
            interfaceSet.addAll(f.getInterfaces().getValue());
            //interfaceSet.addAll(f.getInterfaces().getNameKeys());
        }
        //接下来要找interface的父亲块

        HashSet<MyInterface> interfaceFatherBlock = new HashSet<>();
        for (MyInterface i : interfaceSet) {
            HashSet<MyInterface> ifatherBlock = i.getAllFather();
            interfaceFatherBlock.addAll(ifatherBlock);
        }
        //从已有接口获取其父类接口
        interfaceSet.addAll(interfaceFatherBlock);
        ArrayList<String> interfaceNames = new ArrayList<>();
        for (MyInterface realization : interfaceSet) {
            interfaceNames.add(realization.getName());
        }
        implementsName = interfaceNames;
        return interfaceNames;

hw14

查询指令(新增顺序图和状态图)

状态图

顺序图

指令分析

实现较为复杂的指令有

关键状态判断

首先,对于关键状态的判断,其最后发生在region中(即state的parent),判断逻辑为:

判断是否可到达:(由于本次作业的时间要求较宽松,所以采用了最朴素的方法)

    public boolean reachable(MyState s1, MyState s2, MyState except) {
        HashSet<MyState> level = new HashSet<>(s1.getLinked());
        HashSet<MyState> visited = new HashSet<>(s1.getLinked());
        visited.add(s1);
        level.remove(except);
        while (!level.isEmpty()) {
            if (level.contains(s2)) {
                return true;
            }
            HashSet<MyState> tmp = new HashSet<>();
            for (MyState levelX : level) {
                HashSet<MyState> tmpX = new HashSet<>(levelX.getLinked());
                for (MyState next : tmpX) {
                    if (!visited.contains(next) && next != except) {
                        tmp.add(next);
                    }
                }
            }
            level = tmp;
            visited.addAll(level);
        }
        return false;
    }

message查询

关于lifeline/endpoint收到或发出的message,建立了如下数据结构

    private HashMap<MessageSort, Tool<MyMessage>> asSource = new HashMap<>();
    private HashMap<MessageSort, Tool<MyMessage>> asTarget = new HashMap<>();

使用了二重索引,便于根据message的种类索引相应的message。

同时,在初始化时,将lifeline和endpoint归为一类,但为endpoint特别加上isEnd的属性判别,在interaction中也专门设置一个容器存放endpoint,这样可以在查找lost和found消息时更快速,统一管理可以接受消息的对象,同时不至于混淆lifeline与endpoint。

hw15

模型有效性检查

hw15集中在模型有效性检查,其顺序执行,发生在查询指令之前,若检测到违反规则,立刻抛出异常并退出

字段为空的判断

(weak1就寄在这里)
最初采用正则表达式,但是无奈学艺不精出现了bug,最终采用朴素的方式解决

R002-重名成员判断

(这一段指导书写的很绕,所以理解这一条有效性判断花了一部分时间)
关于关联的另一端,结合mdj文件理解为一个类所管理的元素有

R002要检查的就是在一个类里面若干个associationend attribute 互相之间不能有重名,如果有重名输出成员名字和当前类的名字。
另外,如果有两个end的name都为空不记为重名,如果attribute和end重名且为空或者多个为空的attri记为异常

//在群里看到有位同学的图,感觉这个理解非常恰当!
public class foo{
    private sometype attri1;
    private sometype attri2;
    private class2 end1;
}
R003/R004 类的继承

类的循环继承:

类的重复继承:

(上面的方法在实现的时候有一个小问题,就是visited里面没有加入最开始的那个接口,就是说,如果接口循环继承回来了不算为重复继承,老实说我也不知道应该算还是不算,但是这个情况过不了R003所以不会进入R004的判断所以无需考虑)

测试环节

对于前两次作业主要采用了自动化测试的方法,根据输入的uml图语法及json规则随机生成uml图与查询指令。
第三次作业需要针对性地生成无效模型,所以放弃了自动化测试的想法转为手搓数据,构造思路为覆盖有效及无效的每一种情况。例如对R001的测试

架构设计思维及OO方法理解的演进

本学期的oo课程带给我很大的收获,虽然一开始每周一次的ootime带给我很大的负担,强测和互测让人心理压力很大,但是经过一学期的锻炼,现在已经可以坦然在最后一天开始动手写了(bushi)。整体来说oo让我对java语言有了一个初步的熟悉,同时在实验里面逐步了解面向对象的思想。

本学期的oo课程一共分了四个单元,分别是:

个人对四个单元的难度排序是2>1>4>3
(电梯单元太痛苦了)
第一个单元算是oo的初步试水,一开始非常手忙脚乱,最终目的是过评测,对于面向对象的理解不是很深,评测过于依赖评测机,在构造数据自测方面没有做出努力,手搓的数据不能覆盖全面的情况。导致第一单元出现了一些非常简单但没发现的bug
第二单元重点是对多线程的掌握。三四单元则轻松起来了,也是从三四单元开始我终于下定决心要自己搭评测机和生成随机数据。三四单元的另一个收获是认真阅读指导书,对事件发生情况进行全面的考虑,以达到全面的覆盖测试。

课程收获

这学期的oo课程让我学到了很多,除了前面提的编程能力的提高,还有一些设计思维上的考虑。
荣文戈老师一直在强调不要上来就开始动笔写,要先设计好。一学期的实验充分验证了这句话,在一开始就考虑扩展空间会省去后面重构的时间和精力。
另外还有抗压能力的提升,最开始看到强测出大锅会产生很大的心理压力,现在变得更平和了,不就是bug嘛,非常正常,修就完了!

课程建议

  1. 第一单元的难度可以稍微降低一下,或是pre的难度稍微抬高一点,给出更充足的缓冲过渡阶段
  2. 提高中测的难度,稍微降低下中测和强测的梯度差异
  3. 希望能对一些课程实验具体内容之外的东西进行扩充,比如评测机搭建的方法

标签:oo,总结,HashSet,接口,查询,期末,为空,new,单元
来源: https://www.cnblogs.com/zjh-buaa/p/16422657.html