其他分享
首页 > 其他分享> > oo第四单元总结

oo第四单元总结

作者:互联网

第四单元总结暨课程总结

一、作业分析:

1.第一次作业

这一次的作业是需要完成的任务为实现一个UML类图分析器UmlInteraction,学习目标为UML入门级的理解、UML类图的构成要素及其解析方法。

在刚拿到作业代码的时候感觉很懵,原因就是整个程序架构太庞大,代码非常多。但实际上需要我们理解的内容并不是很多,主要集中在以实现UmlElement接口的各种uml类型中。实际上这一部分的代码也不需要完全理解,我们需要使用的这些函数基本都是一些query函数,从名字都能直接看出来作用 。

根据staruml存储方式,我使用了树状结构,跟节点不存储数据,其子树保存各种类和接口,而类树下是方法树和属性树,方法树下还有参数树。然后写了一些找特定id或者name的element的方法。关于类名、属性名重复的问题我采用了一个map来存储是否存在重名情况。这样准备工作基本做好了。

这次作业要求的任务在做好准备工作之后其实并不困难,唯一一个比较难的方法是找类实现的接口,因为涉及到接口的多继承问题,最后采用了递归寻找的方法:

public Set<String> getInter() {   //类树中的方法
    HashSet<String> list = new HashSet<>();
    for (String id : inter) {
        InterfaceTree interfaceTree = (InterfaceTree) findTree.getTreeById(id, root);
        list.addAll(interfaceTree.getInter());
    }
    if (father != null) {
        ClassTree classTree = (ClassTree) findTree.getTreeById(father, root);
        list.addAll(classTree.getInter());
    }
    return list;
}
 
 public Set<String> getInter() {  //接口树中的方法
        HashSet<String> list = new HashSet<>();
        list.add(this.getData().getId());
        for (String id : fathers) {
            InterfaceTree interfaceTree = (InterfaceTree)         findTree.getTreeById(id, root);
            list.addAll(interfaceTree.getInter());
        }
        return list;
    }

最终存在bug也是出在这里,由于接口存在同名的情况,还要根据id将它们视为不同的接口最终输出。

uml类图:

2.第二次作业

第二次作业难度不大,在第一次作业的基础上添加了状态图和时序图两种类型,由于不同图之间不存在交叉关系,我新建了两个树来分别存储这两个新图。而要求写的方法难度不大,在建好树之后基本都能直接写出来。

这次作业出了点麻烦,是MyUmlInteraction长度超出了checkstyle规定的500行,原因是这个类的构造部分非常长,再加上后面的很多要实现的方法。最后我把整个类拆成两个类,第一类是构造部分以及很多类属性,第二个类就是各种要实现的方法,然后让第二个类作为第一个类的子类就可以继承构造方法和众多变量。

本次作业出现了一个小bug,是一个位置应该用父类定义的变量出错写成了子类定义的变量。导致之后出现了转型错误。

uml类图:

3.第三次作业

第三次作业在架构上与前两次相同,也就是说不需要添加新的树。这次作业要求对模型进行有效性检查。规定了8个要检查的点,其中前四个比较麻烦,后面几个都很简单。

由于本人算法能力不强,在遇到了r002部分,针对接口的环形检查遇到了麻烦。但其实就是一个基本的dfs就可以解决,但我自己在做的时候有点把自己绕进去了。最后在网上看了一下有向图的回路查找才弄了出来:

public ArrayList<UmlInterface> dfs2(InterfaceTree target,
                                    InterfaceTree now, Tree root,
                                    ArrayList<String> visited,
                                    ArrayList<UmlInterface> trace, boolean symbol) {
                                    
    trace.add((UmlInterface) now.getData());
    visited.add(now.getData().getId());
    ArrayList<UmlInterface> tmp;
    
    if (now.getData().getId().equals(target.getData().getId()) && symbol) {
        return trace;
    }
    
    if (now.getFathers() != null) {
        for (String id : now.getFathers()) {
            if (!visited.contains(id) || target.getData().getId().equals(id)) {
                tmp = dfs2(target, (InterfaceTree)
                        getTreeById(now.getFather(), root), root, visited, trace, true);
                if (isCircle(tmp)) {
                    return tmp;
                }
            }
        }
    }
    return trace;
}

最后出现的bug是要把所有成环的接口、类都输出了,但我只输出了其中一个回路。

UMl类图:

二、架构设计和oo的理解

在接触oo这门课之前,尤其是在oo的预习阶段,我把这门课视作了java语言的学习课。但是很明显这门课的内容要远远大于java的语言学习。在很长一段时间内,我不理解什么是面向对象,在解决问题的时候是用c语言式的解决方法,所以回过头来看之前的很多作业,尤其是第一单元的作业,真有些不堪入目。

为什么要面向对象?原因是面向过程的方法有如下缺陷:

  1. 面向过程所采用的设计思路不是将客体作为一个整体,而是将依附于客体之上的行为抽取出来,以功能为目标来设计构造应用系统。这种做法导致在进行程序设计的时候,不得不将客体所构成的现实世界映射到由功能模块组成的解空间中,这种变换过程,不仅增加了程序设计的复杂程度,而且背离了人们观察问题和解决问题的基本思路。
  2. 过程抽象是将问题域中具有明确功能定义的操作抽取出来,并将其作为一个实体看待。这种抽象级别对于软件系统结构的设计显得有些武断,并且稳定性差,导致很难准确无误地设计出系统的每一个操作环节。一旦某个客体属性的表示方式发生了变化,就有可能牵扯到已有系统的很多部分。而数据抽象是较过程抽象更高级别的抽象方式,将描述客体的属性和行为绑定在一起,实现统一的抽象,从而达到对现实世界客体的真正模拟。
  3. 结构化设计方法没有做到客体的整体封装,只是封装了各个功能模块,而每个功能模块可以随意地对没有保护能力客体属性实施操作,并且由于描述属性的数据与行为被分割开来,所以一旦某个客体属性的表达方式发生了变化,或某个行为效果发生了改变,就有可能对整个系统产生影响。

正是因为没有理解面向对象的深层次含义,第一单元的作业令我苦恼不已。多项式求导按照面向过程的思路去面对是很复杂的,有太多种情况要去分类讨论,但如果从面向角度去看,把运算符,项作为基本的接口,不同类型的项和运算符作为不同的客体,相关数据被绑进客体内,实现统一的抽象。这样整个工作就非常简单。

经过一个学期的学习,到了第四个单元,也涉及到一个相对复杂的架构设计。这次我自认为自己的设计有了很大的进步,我用一个接口tree把所有的element统一起来。然后再根据不同的element细分。按照这样的架构设计,整个作业难度感觉都下降了不少。

三、测试相关

没有经过测试的代码是不能解决问题的,当我拿到了第三单元第一次作业时候,高兴的合不拢嘴,三下两下做完就交了上去,居然一遍就过了中测。然后就躺倒觉得万事大吉。结果强测直接爆0。这就是不做测试的一个血淋淋的教训。

我们oo课程这四个单元作业,想做好测试其实并不容易。第一单元我根据指导书所教的方法进行了测试,三次作业下来就丢了一些性能分。但是之后的作业测试难度真的很大,没有使用一种具有普遍覆盖性的测试方法,基本是靠自己写的样例,和同学对拍这两种方式来进行简单测试。所以之后这几次每次都会多多少少丢掉一些分。

四、课程收获与体会

oo这门课是这学期我感觉最扎实的一门课。每周会占去我为数不多的学习时间中的一半以上时间。现在学习已经结束,回头看看这一学期,收获是全面而丰富的。

  1. 学习了java这门语言:上学期虽然学了一门java入门的选修课,但由于摸鱼的原因是真的没学啥东西。在这学期任务驱动性学习下掌握了java的基本用法。学习了继承实现、多线程、异常处理这些之前根本不懂的东西。
  2. 重新认识了编写程序:正如第二部分着重谈的,当我拿到一个任务时,我学会了用不同的眼光去审视问题。站在面向对象这样的高度上,我学会了从客体本质上去抽象,学会了用层次化结构分解问题。也就是从本质上来说,我的编程能力有了质的飞跃,这不是多学几门计算机语言就能提升的。
  3. 重新复习了数据结构相关内容:编码是脱离不了算法的,在本学期多次使用了数据结构中学习了的算法。算是一种很好的复习吧。

oo课程带给我的感受是多元的,有深夜de不出来bug的绝望,有忽然想到解决方案的欣喜,有爆0的惊讶,也有获得高分的安心。但一路走来回首看去,更多的是在未知中探索感受到自己的渺小无知。代码真的有无限可能,唯一限制我们代码能力的或许只有我们自己吧。

五、一点建议

  1. 建议在中测结束前两个小时内,公开所有的中测数据,这样既可以帮助能力较差的同学顺利通过,又可以避免其他同学一开始就使用中测数据来做检查。
  2. 三单元的中测是不是太简单了一点点。。。
  3. 线上实验难易差距比较大,有一两次难度真的很大,也有几次难度确实不大。。。
  4. 多线程部分内容感觉学的还不是很清楚,希望能增加课时。

最后衷心感谢课程组的老师、助教为oo课程付出的一切,这真的是一门很不错的课程

标签:oo,list,作业,接口,第四,客体,id,单元
来源: https://www.cnblogs.com/swampxhome/p/13166420.html