BUAA_OO第四单元博客作业

BUAA_OO第四单元博客作业

一、架构设计

本单元主要考察类图、时序图、顺序图的规范表达。并根据一定的规则建立自己的结构层次,最后以此判断UML输入是否合法。下面详细介绍类图的结构

类图结构

在类图中新建MyClassMyInterfaceMyOPeration类来分别表示类、接口、方法函数体。更加方便地存储和查找元素所在地位置。例如将UmlAttribute以HashMap地形式存储在MyClass类中,依据是UmlAttribute地parent_id。这样就可以快速地得知某类地元素的个数及其具体性质,而不是通过遍历所有元素的parent_id进行查询了。

从而建立起一种类似树状的结构,从一个节点(MyClass)查到其所有的属性(UmlAttributeMyInterfaceMyOPeration)等,再根据此属性(MyOperation)进行递推,得到更下一层的内容(UmlParameter),就可以得到这个节点拿下的所有内容。

  • MyClass:类

    包含了类的元素、函数、父类、相关联的引用以及实现的接口等。通过HashMap的存储这些信息。

    private final UmlClass umlClass;
       private MyClass superClass = null;
       private final ArrayList<UmlAttribute> attributes = new ArrayList<>();
       private final HashMap<String, ArrayList<UmlAttribute>> name2attribute = new HashMap<>();
       private final ArrayList<MyOperation> operations = new ArrayList<>();
       private final HashMap<String, ArrayList<MyClass>> name2aClass = new HashMap<>();
       private final HashMap<String, ArrayList<MyInterface>> name2aInterface = new HashMap<>();
       private final ArrayList<MyClass> associatedClass = new ArrayList<>();
       private final ArrayList<MyInterface> associatedInterface = new ArrayList<>();
       private final ArrayList<MyInterface> implementInterface = new ArrayList<>();
    
  • MyInterface :接口

    包含接口中的属性、父类接口、相关联的引用以及函数方法。通过HashMap以name为键值指向对应的类。

    private final UmlInterface umlInterface;
       private final ArrayList<MyOperation> operations = new ArrayList<>();
       private final ArrayList<UmlAttribute> attributes = new ArrayList<>();
       private final ArrayList<MyInterface> superInterface = new ArrayList<>();
       private final HashMap<String, ArrayList<MyClass>> name2aClass = new HashMap<>();
       private final HashMap<String, ArrayList<MyInterface>> name2aInterface = new HashMap<>();
       private final ArrayList<MyInterface> associatedInterface = new ArrayList<>();
       private final ArrayList<MyClass> associatedClass = new ArrayList<>();
    
  • MyOPeration :方法

    包含参数等,通过ArrayList存储

    private final UmlOperation umloperation;
       private UmlParameter returns = null;
       private final ArrayList<UmlParameter> params = new ArrayList<>();
    
  • UML图

    屏幕截图 2021-06-26 144129

顺序图UML

屏幕截图 2021-06-26 144309

状态图UML

屏幕截图 2021-06-26 144433

二、四个单元中架构设计及OO方法理解的演进

第一单元

内容为表达式求导,主要学习的是继承、接口、容器的使用。由于第一次接触OO和java,对其中的一些原理和规范在理解上有一些模糊,所以做的比较困难。

但是从中学到了面向对象的一些基本用法,通过构建新的类,并建立每个类之间的联系,进而形成继承的层次结构,再通过一个父类的容器进行统一的管理,就可以实现对同一父类、不同子类的操作。同时在每个子类的内部会写有专门的重载(overloading)方法,在吊桶父类方法时便会自动调用子类特殊的方法,从而实现对不同对象不同的求导法则,这便体现了多态的好处,也让我更好的理解了多态的用法。

第二单元

内容为电梯调度,主要的难点是多线程的调试以及任务分配的算法。同样是第一次接触多线程,在理解其原理以及用法上花费了一定的时间和精力。帮助最大的是我在研讨课上的一次分享,使我对多线程有了更加深刻的了解,真正的理解了共享对象的作用以及其维护方法(临界区),同时学会了控制不同线程的等待(wait)与唤醒操作(notify)。这让我掌握了不同线程之间存在的逻辑顺序。在电梯调度方面,我采用了LOOK算法,在多天体任务分配方面,我采用了均分的思想,从而使性能得到了一定的优化。

第三单元

内容为JML,整体难度偏小,主要是想让我们了解在高端编程中java语言的规范,通过严谨无二义性的JML语言来代替自然语言,能够使庞大的工程拆分成具体的、精确的小程序。

但是在作业中还是存在一定的问题,例如CTE、RTE等超时问题。问题主要出现在对JML语言的直接搬抄,没有进行理性思考的结果。正确的根据JML书写程序的过程是:读懂JML,然后将其转化为无二义性的实际问题(自然语言),再通过一定的算法降低需要多重循环的语句的复杂度(一般采用空间换时间的方法)。在此单元中我学会了JML的规范,掌握了转换成无二义性java语言的能力,学到了如何有效的降低算法的时间复杂度(如差分集)。

第四单元

内容为UML图,难度偏低,主要学习了UML图的规范,以及在工程上的表示方法,开阔了眼界。除此之外,掌握了通过构建新类对多个元素进行归一、分类的能力,从而达到快速查询的效果。

三、四个单元中测试理解与实践的演进

第一单元

测试的方法主要是对拍机,数据随机生成,在时间充裕的情况下,根据讨论区自学了python中函数求导以及比较不同函数是否相等的功能,这为对拍测试提供了极大的便利。

但是由于测试数据的覆盖率较低,对一些隐藏问题没有测试到,从而导致了强测中出现超时的错误(后发现使递归的问题),这对我有一定的启示。

第二单元

多线程测试,这对我来说是一次巨大的挑战。根据讨论区的指导,通过C语言实现了定时输入的功能,对一个文档中的内容定时的读取,来模拟请求的随机到达。同时为了保证多线程可能出现的不稳定问题以及批量处理问题,我通过白那些.bat程序实现了对C语言文件的批量处理,如下

start cmd /k "echo testpoint 1: && cd ../Homework7/out/artifacts/Homework7_jar && timeInput.exe < input.txt | java -jar Homework7.jar && echo testpoint 1"
start cmd /k "echo testpoint 1: && cd ../Homework7/out/artifacts/Homework7_jar && timeInput.exe < input.txt | java -jar Homework7.jar && echo testpoint 1"
start cmd /k "echo testpoint 1: && cd ../Homework7/out/artifacts/Homework7_jar && timeInput.exe < input.txt | java -jar Homework7.jar && echo testpoint 1"
start cmd /k "echo testpoint 1: && cd ../Homework7/out/artifacts/Homework7_jar && timeInput.exe < input.txt | java -jar Homework7.jar && echo testpoint 1"
start cmd /k "echo testpoint 1: && cd ../Homework7/out/artifacts/Homework7_jar && timeInput.exe < input.txt | java -jar Homework7.jar && echo testpoint 1"

可以同时开启多个进程,有效的测试了进程的不稳定性,提高了测试的效率。

最重要的是因为多进程的不可复现性,采用打日志的成为了首选的方法,好的日志可以复现多个进程的切换顺序,可以更好的发现bug。当然,学会对多线程进行调试也是不可或缺的哦。

第三单元

Junit测试,通过编写Junit程序,对每一个方法进行全面覆盖的测试,测试代码具体如下

    @Test
    void contains() throws EqualPersonIdException {
        System.out.println("contains");
        MyNetwork n = new MyNetwork();
        Person a = new MyPerson(1, "1", 1);
        n.addPerson(a);
        Assert.assertEquals(n.contains(a.getId()), true);
    }
	void queryBlockSum() throws EqualPersonIdException, PersonIdNotFoundException, EqualRelationException {
        System.out.println("queryBlockSum");
        MyNetwork n = new MyNetwork();
        Person a = new MyPerson(1, "1", 1);
        Person b = new MyPerson(2, "2", 2);
        Person c = new MyPerson(3, "3", 3);
        Person d = new MyPerson(4, "4", 4);
        Person e = new MyPerson(5, "5", 5);
        n.addPerson(a);
        n.addPerson(b);
        n.addPerson(c);
        n.addPerson(d);
        n.addPerson(e);
        n.addRelation(b.getId(), c.getId(), 10);
        n.addRelation(c.getId(), d.getId(), 20);
        n.addRelation(a.getId(), e.getId(), 30);
        Assert.assertEquals(n.queryBlockSum(), 2);
    }

即通过对每个方法进行确定样例、确定结果的测试,这样有效的实现了多个样例的重复测试,实现了方法测试的全覆盖,这是工程上较为通用的测试方法,具有很强的严谨性。

第四单元

利用StartUML软件进行测试。将.mdj导入软件中,通过自行绘制特定的类图、顺序图、状态图来改变.mdj文件,再通过java包、命令行导出成输入样例,进而对程序进行特定、细致的测试。

四、课程收获

通过一学期的OO学习,我掌握了面向对象的本质内容,能供熟练的书写java程序,使用特定的容器以及java自带的处理函数(是真的好用),同时对java的原理知识有了一定程度的理解,这对之后的代码书写有很大的帮助。

并且通过第三、四单元的训练,开阔了我的视野,让我明白了java的书写规范,以及在团队合作中,无二义性的重要程度。

让我收获最多的是课程的循序渐进的体制,让我明白了代码不仅要能跑出正确的结果,更要有良好的可延展性,良好的架构。这边要求我在书写代码之前,要对代码架构有充分的构思,要想好在动手打码,这点在我看来比任何的实践、理论知识都要重要的,这直接决定了你的代码能走多远、能走多稳健。

五、课程建议

讲真,OO的课程虽然安排的挺紧,但是体验感还是不错的。说到建议的话,有以下六点

  • 加强理论课与课程作业的联系性。
  • 及时公布上机实验的答案。
  • 加强研讨课的积极性,可以开展研讨课的其他内容,如对理论或是课程作业中某一特定问题的详细解答。
  • 让同学们自主选择研讨课的内容,同时增加研讨课反馈机制。
  • 尽可能地排除课程作业要求的二义性(不得不说,助教们做的真心不错)。
  • 适当公开同一单元下一次作业的部分内容,这样可以将对同学们的重构概率,减少时间的浪费(重构真是痛苦)。
posted @ 2021-06-26 17:09  qlhh  阅读(88)  评论(0编辑  收藏  举报