2019OO第四单元总结

一、关于OO第四单元的UML作业的架构设计

在这个单元的作业中,第二次作业只是在第一次作业的基础上增加了一些功能,但在架构上并没有改变,因此这里我主要说第二次作业的架构。

在MyUmlGeneralInteraction类中,有一个HashMap,用于把id转换成对象。

Class, Attribute, Operation, Parameter这些类,用于建立自己的类图保存机制,在MyUmlGeneralInteraction的构造方法中,调用了HandleUmlElement中的handle静态方法,在handle方法中,UmlElement被转换成了这些类,

由于Class中包含很多Attribute和Operation,Attribute中包含很多Parameter,我自己写了诸如XxxContainer的类,作为包含Attribute/Operation/Parameter的容器,在这个容器中有一个HashMap,用于把名称转换成对象。

在MyUmlGeneralInteraction类中,有一个HashMap,用于把id转换成对象。

在状态图的解析中,可以把状态图看成有向图,在查询一个state所有的后继时,通过BFS算法得到它的所有后继。

在检查UML图的UML008合法性时,可以把类图看作一个有向图,把类/接口看作结点,继承关系看作有向边,通过DFS算法就可以知道这个有向图中是否有环路。

 

二、关于这学期的OO课程的总结

(1)在四个单元中架构设计及OO方法理解的演进

1. 第一单元作业:多项式求导

这个单元主要是让我们熟悉Java语言的一些特性,包括类和对象,以及继承和接口的使用。对于这次的多项式解析,还用到了一些正则表达式的知识。

在第一次作业中,我写的特别面向过程,只使用了一个含有多个静态方法的主类,代码很不清晰,而且有很多bug,导致程序复用性较差。在互测环节中,我看到了别人的代码之后,决定在第二次作业中重构自己的代码。

在第二次作业中,我重构了第一次作业的代码,根据表达式的特性,自己写了Exp类(表达式)、Factor(因子)、Term(项),使得程序的结构较为清晰。在求导的时候,把每一项都变成a*x^b*sin(x)^c*cos(x)^d的形式,然后在求导、合并同类项。

在第三次作业中,由于在多项式中出现了函数嵌套,我在第二次作业代码的基础上,增加了Func(函数)类,Nest(嵌套,里面有很多函数,对应的就是第二次作业的Factor),通过链式求导法则和乘法求导法则,对整个多项式进行求导。

在这三次作业中,我体会到了面向对象的要点(尤其是第一次作业到第二次作业的重构),但是在代码中仍然有很多面向过程的部分。

2. 第二单元作业:多线程电梯

这个单元主要是让我们熟悉Java语言的多线程的设计模式。多线程的编写和调试(相比于第1、3、4单元的单线程程序)是一个玄学问题,但只要明确每个类的需求和作用、使用线程安全的类、使用synchronized给共享对象加锁以确保安全,多线程的问题就能迎刃而解。

在第一次作业中,不用考虑捎带,因此调度器就简单很多,用一个先进先出的队列即可。

在第二次作业中,需要考虑捎带,我采用的捎带是类似于现实生活中的电梯,走到请求的最高层/最低层,然后捎带同方向的请求。调度器用于告诉电梯最高层/最底层是几层,电梯在途中的一些楼层停下,该楼层符合要求的请求进入电梯。

在第三次作业中,有3个电梯,每个电梯都有最高容量,且每个电梯都有不能停的楼层,因此需要考虑换乘问题。对于必须换乘的请求,我的方案是将它先送到3个电梯都停的楼层,然后在让合适的电梯捎带它;对于无需换乘的请求,只有合适的电梯才会捎带这个请求。

在这三次作业中,必须考虑到死锁的问题,应当适当调整synchronized的方式,防止死锁的发生。在提交代码之前,由于多线程程序运行的随机性,应当在本地运行多次(这里我用的是一位大佬写的用于定时投放请求的jar包),如果本地多次运行出现了问题,说明代码有问题,应当进行改正。在这一单元中,我体会到了面向对象在多线程中的应用,对线程安全的类有了一些自己的思考。

3. 第三单元作业:JML和地铁查询

这个单元主要是让我们了解JML,在作业中需要实现官方包里的接口,通过阅读源代码中的JML注释,明确代码中方法的作用。但是这次作业对运行时间要求较高,应当在代码中使用合适的架构。

在第一次作业中,主要的问题就是id和Path的一一对应的问题,所以应当有id→Path和Path→id的HashMap。

在第二次作业中,主要问题是要进行两点之间最少步数的查询,这里应当增加一个无向图的结构,在无向图中使用BFS算法,得到两个点之间的最短路径。但是BFS所需的时间较长,因此需要考虑建立缓存机制,在图结构没有变化的情况下,从缓存中查询数据即可。缓存的结构大概为u->(v->dist),即HashMap<Integer, HashMap<Integer, Integer>>,通过u和v查询最终的结果,只有在缓存中没有结果的时候在进行BFS。

在第三次作业中,主要问题是需要考虑换乘,通过p号线到u点,和通过q号线到u点,是不一样的。在这里,我使用了拆点的方法,把通过p号线到u点和通过q号线到u点看作两个点,在用Dijkstra算法计算两个点之间的最少票价等问题上,对这两个点区分对待。

在这三次作业中,我学会了一些工具(比如JUnit和JMLUnit)的使用。

4. 第四单元作业:UML文件的解析

关于架构,在前面已经有了阐述。在这个单元的作业中,我对UML设计模式有了更深入的理解,明白了这种建模手段的优点,对面向对象的一些特性有了更深入的理解。

(2)总结自己在四个单元中测试理解与实践的演进

1. 第一单元作业:多项式求导

我采用了编写脚本的方法,输入一个多项式,通过自己的程序和sympy进行求导,并验证求导的结果是否相等。

2. 第二单元作业:多线程电梯

我使用了 https://github.com/Mistariano/buaaoo-elevator-test-suit 这个黑箱测试的IO接口,并且通过print大法进行调试,由于多线程程序运行的随机性,通过多次测试的方式,验证程序是否正确执行。

3. 第三单元作业:JML和地铁查询

我使用了输入输出的方式进行测试,虽然我也曾考虑使用JUnit、OpenJML、JMLUnit等工具进行测试,但是体验很不理想(比如JDK的版本不能高于JDK8,以及各种蜜汁报错),我之后还是考虑最朴素的IO测试方法。

4. 第四单元作业:UML文件的解析

我自己手动编辑UML文件,然后通过自己写的小脚本,使用官方包把UML文件转换成json,然后把json和输入的一系列查询指令整合在一起,之后通过管道的方式进行测试。

(3)总结自己的课程收获

1. 代码风格的提高

代码风格测试很严格,比如一行不能超过80个字符、方法有最大行数限制,但是这些限制让我对我程序的结构有了自己的思考(比如增加一些方法,使得代码更加层次化),让我的代码可读性得到提高。

2. 对“面向对象”更深一层的认识

还记得我在学OO之前,对于类的认识就是“带函数的结构体”,现在我绝对不会这么说了。

3. 编程能力的提高

在之前的C语言程序设计课和数据结构课上,我写的代码都比较短(300行就算比较长了),而在这次OO课上,代码几乎都是上千行,对我的编程能力有很大的提高。

4. 学习能力的提高

在OO课上,并没有对Java语法有太深入的讲解,也并没有讲解Java的各种类的使用,我为了完成这几次作业,在网上学习了Java的语法以及正则表达式(对于第一单元作业)的使用,并通过读Java源码的方式了解Java中各种类的使用,使我的学习能力有很大的提高。

(4)立足于自己的体会给课程提三个具体改进建议

1. 实验课的改进。上午刚讲完相关理论之后,下午就开始实验,使得实验课的效果不是很好。应当让理论课和实验课的时间间隔长一些,让学生有更多时间理解理论课的内容。

2. 希望指导书能说的更清楚一些。比如最后一次作业,讨论区里说了很多限制,但在指导书上并没有说清楚,即使最后说清楚了,学生剩下的时间也不多了。

3. 最后一次作业的应用性不强。最后一次作业,可以说是“面向starUML编程”,学生并没有体会到UML在面向对象程序设计上的应用。最后一次作业,倒不如出一道比较简单的题,先让学生画出一个UML图,然后再让学生根据这个图编写程序,这样可能就会好很多。

转载于:https://www.cnblogs.com/zzy-cnblog/p/11077962.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值