BUAA_OO_第四单元以及期末总结

BUAA_Unit4

一、第四单元架构设计

类图如下图所示

 

本单元是要实现一个JML解析器,自己主要新建的类有

 

分了MyClassModel,MyCollaboration和MyStartChart三个类分别完成三种图的统计工作。在第三次作业中,为了进一步功能细分化,又设立了MyCheck类进行前置性检查,前置性检查中的所有信息统计与主体类完全独立,避免了由于数据不规范导致主体中的数据统计出现问题。

 

其中MyOp是为了完成类图中对于UmlOperation的统计而设计的,存储Operation的Parameter和name,其余UML元素的类采用的官方包里的内容。

 

 

核心算法

在第一次作业中,采用HashMap代替数组,存储了大多数信息。为了实现

 public int getClassAttributeCouplingDegree(String className)
        throws ClassNotFoundException, ClassDuplicatedException {
    return myClassModel.getClassAttributeCouplingDegree(className);
 }
 
 @Override
 public List<String> getClassImplementInterfaceList(String className)
        throws ClassNotFoundException, ClassDuplicatedException {
    return myClassModel.getClassImplementInterfaceList(className);
 }
 
 @Override
 public int getClassDepthOfInheritance(String className)
        throws ClassNotFoundException, ClassDuplicatedException {
    return myClassModel.getClassDepthOfInheritance(className);
 }

这几个方法,大量采用了递归搜多来书写函数。

第二次作业中,为了实现这一个方法

 public boolean getStateIsCriticalPoint(String stateMachineName, String stateName)
        throws StateMachineNotFoundException, StateMachineDuplicatedException,
        StateNotFoundException, StateDuplicatedException {

采用了bfs的方式进行判断

 vis.clear();
 queue.add(beginId);
 vis.add(beginId);
 boolean ans2 = false;
 while (!queue.isEmpty()) {
    String now = queue.poll();
    if (umlStates.get(now).getElementType() == ElementType.UML_FINAL_STATE) {
        ans2 = true;
    }
    for (String nex : state2stateTransitions.get(now)) {
        if (!vis.contains(nex) && !Objects.equals(nex, noValidId)) {
            vis.add(nex);
            queue.add(nex);
        }
    }
 }

在第三次作业中,为了实现CheckforUml003,采用了对每一个点进行dfs判断自身是否在环上。

 public void check003() throws UmlRule003Exception {
    HashSet<String> ans = new HashSet<>();
    //类
    for (UmlClass umlClass : preUmlClasses.values()) {
        HashSet<String> vis = new HashSet<>();
        if (dfs1(umlClass.getId(), umlClass.getId(), vis)) {
            ans.add(umlClass.getId());
        }
    }
    //接口
    for (UmlInterface umlInterface : preUmlInterfaces.values()) {
        HashSet<String> vis = new HashSet<>();
        if (dfs2(umlInterface.getId(), umlInterface.getId(), vis)) {
            ans.add(umlInterface.getId());
        }
    }
    HashSet<UmlClassOrInterface> tureAns = new HashSet<>();
    for (String id : ans) {
        tureAns.add((UmlClassOrInterface) umlElements.get(id));
    }
    if (!tureAns.isEmpty()) {
        throw new UmlRule003Exception(tureAns);
    }
 }
 
 private boolean dfs2(String aim, String id, HashSet<String> vis) {
    boolean ans = false;
    vis.add(id);
    for (String id1 : preGeneralizationSource2TargetInterface.get(id)) {
        if (Objects.equals(id1, aim)) {
            return true;
        } else {
            if (!vis.contains(id1)) {
                ans |= dfs2(aim, id1, vis);
            }
        }
    }
    return ans;
 }
 
 private boolean dfs1(String aim, String id, HashSet<String> vis) {
    vis.add(id);
    if (!preGeneralizationSource2Target.containsKey(id)) {
        return false;
    }
    String id1 = preGeneralizationSource2Target.get(id);
    if (Objects.equals(id1, aim)) {
        return true;
    } else {
        if (vis.contains(id1)) {
            return false;
        } else {
            return dfs1(aim, id1, vis);
        }
    }
 }

二、架构设计思维演进

第一单元

主要在努力遵守归一化的原则,力求更多的体现每一个类的共性,在这个过程中,体会到了归一化原则的威力,归一化的定义让Expr在Term类中的递归处理变的自然而然。在第三次和第二次作业中,体会到了设计的原则是追求正确性和性能的平衡,两者不可偏废。

第二单元

在第一单元归一化原则的基础上,进行方便多线程运行的设计(线程安全),更多地去进行线程类、共享资源类和中央控制器类的设计。由于时间不足,后期进行的主要是需求性增量开发,尽可能减少对于代码的改动,更多的进行类、函数和属性的增加。

与此同时,这一单元在优化上的探索也让我感触颇深,没有一种算法是完美的。最佛系的算法——自由竞争算法的表现竟然一直很优秀。

第三单元

本单元是契约式编程,对于契约的理解是一个很重要的环节,充分理解契约之后,基本不需要进行过多的架构设计,仅仅需要想办法高性能地实现契约的功能。当然为了避免代码超过500行和层次清晰,我将核心算法代码(两点间最短路径、最小生成树等)抽离了出来,放在了另一个类里。

第四单元

感觉这一单元主要还是面向过程编程,为了使代码层次清晰,我们抽离出三个不同的图表类负责不同的查询操作。设计函数遵循功能单一化的原则,让函数功能清晰,各司其职。

三、测试理解与实践

第一单元

主要采用的还是原始的手造数据进行测试,但测试效果欠佳,基本测不出什么bug,还是更多的通过对代码的分析来找出错误。

第二单元

构造了windows的命令行脚本和C语言的数据生成器,进行测试。相对来说更便捷了,也可以看一看运行时间。体会到了随机性数据的优点。

第三单元,第四单元

因为题目要求很清晰,主要采用与同学对拍的方式来比对对于题目的理解是否一致。

总结

总的来说,因为自己一直没有重视测试能力的培养,自己对于测试的理解和测试的能力都还是不是很到位的,这就导致了自己保证正确性的手段非常有限。

四、课程收获

1、面向对象设计的基本思维

2、一些具体的程序实现方法

第一单元:递归下降法解析文本,正则表达式解析文本

第二单元:一些设计模式,如单例模式,工厂模式。

第三、四单元:重温了之前学习过的算法,体会了算法在具体问题中的应用。

3、多线程设计的相关知识

4、契约式编程的相关知识

5、JML语言的相关知识

6、java的语法

五、改进建议

1、其实很多时候感觉课上的内容虽然很精彩,很有价值,但是和我们课下作业是有点脱节的。期望老师可以在课上多一些对于作业内容的指导与解析。因为个人感觉作业的挑战性还是很大的,自己的能力还是比较有限的,虽然和同学交流是个很好的途径,但是自己很期望能听到老师对于作业的指导与建议。感觉自己在在多进行几次实践之后在去做作业的效果会好得多。

2、很多时候看到有的同学的自动化测试进行的如火如荼,自己也非常希望课堂上能学一些自动化测试的手段。

posted @ 2022-06-28 10:33  李wk  阅读(26)  评论(1编辑  收藏  举报