BUAA_OO_2020_Unit4_Wandy
总结本单元三次作业的架构设计
除实现了MyUmlInteraction之外
第一单元
新增了MyElement用来管理类,详情如下:
private UmlElement umlElement; //用来存放此Element的UmlElement,似乎是叫适配器模式
private MyElement parent; //它的父类,没有则为null
private HashSet myInterfaces; //接口
private HashSet myAttribute; //属性
private HashSet myOperation; //Operation
//operation
private int inParam; //in 方向的 Parameter
private int reParam; //return 方向的
private HashSet myParameter;
private int assoCount; //与之关联的数量
private boolean freshAsso; //标记位,用于缓存法
private boolean freshImp; //同上
private HashSet myAssociated; //相关联的MyElement
private HashSet ends; //相关联的UmlElement
由于觉得还没复杂到使用继承,因此没有将其按照ElementType分类,仅采用了一下的构造函数来节省不必要的空间,扩展性不高但实现简单,请勿模仿。
public MyElement(UmlElement umlElement) {
this.umlElement = umlElement;
parent = null;
myInterfaces = null;
myAttribute = null;
myOperation = null;
myParameter = null;
myAssociated = null;
ends = null;
switch (umlElement.getElementType()) {
case UML_CLASS:
myInterfaces = new HashSet();
myOperation = new HashSet();
myAssociated = new HashSet();
myAttribute = new HashSet();
assoCount = 0;
freshAsso = false;
freshImp = false;
ends = new HashSet();
break;
case UML_INTERFACE:
freshImp = false;
myInterfaces = new HashSet();
myAttribute = new HashSet<>();
checked = false;
checkAns = false;
break;
case UML_OPERATION:
inParam = -1;
reParam = -1;
myParameter = new HashSet();
break;
default:
break;
}
}
所有函数几乎都已封装到了MyElement,实现Interaction仅起到调用功能。印象中有点麻烦的函数用了dfs缓存法,比较常规。
第二单元
新增了 MyFlow 和 MyState 两个类与之对应,
//MyState
private UmlElement umlElement; //本体
private ArrayList states; //本 State_Machine 的状态们
private HashSet nexts; //后继状态们
private HashSet subSequent; //后续序列
private int transNumber; //transition的数量
private boolean freshSub; //缓存法的标记位
//MyFlow
private UmlElement flowElement; //本尊
private ArrayList lifelines; //本 Interaction 的生命线们
private int incomings; //incoming 的数量
private int messageNumber; //Message 总数
同样,各种函数已被封装好了。
第三次作业
新增了 MyShrift 类,为了解决 MyUmlGeneralInteraction.java 过大,将其初始化程序重构到 MyShrift 类而且将 check 函数的所有具体细节封装到 MyShrift 的静态方法,缩减为406行。
所用算法有 缓存法 和 tarjan。
四个单元中架构设计及OO方法理解的演进
四个单元,变态求导,蜜汁多线程,划水JML,摸鱼UML
也许是难度逐渐降低,或许是我对OO和java逐渐熟悉,每周OO所需要的时间越来越少(被OS代替)。架构设计也越来越得心应手,从对于一些原则的强行遵循到可以自由的做出取舍,也能独立想出一些已经被设计模式起了名字的架构,更好平衡了时间和空间消耗。
四个单元中测试理解与实践的演进
从整体测试到局部功能测试,从 py 到 Junit。说到测试就不得不提每次试验的bug,正好在此总结一下:
- 第一单元
- 第三次
- 互测中有一个,原因为 Factor.toString() 要对括号里的 para 进行判断是否可以当作因子,因为这样可以少输出一个括号,但是我用了字符串自带的 matches() 方法,我以为它是整体匹配的,没想到只是从头匹配。
- 强测也有bug,是完全将sin()括号里当作 Poly 处理了,忘了表达式因子必须带(),所以sin(1-x)在我这里是合法的。
- 分析:大意了,还是测试的不够完全,没有测试这种格式错误的,自己搭的评测机又测不出来带不带括号,还是测试不够充分(测自己的热情远不如测别人),写代码时粗心大意了。
- 第三次
- 第二单元(损失最为惨重的一个单元)
- 第一次
- 多线程问题,有个地方没加锁
- 第二次
- 多线程问题,导致有时候判断不出来人满
- 第三次
- 写了个评测机,但因为测不出来cpu时间,还是TLE了,两个破绽:一个是由于电梯选择策略是static块的初始化,导致第一次用的时候才开始初始化,不在一个线程容易出事。还有一个是在一个人所有策略都行不通时,会标记而且把它放在队尾,让下一个人上,即 remove 后 offer,可惜,我用的是
PriorityBlockingQueue
,会自动排序,导致一直轮询
- 写了个评测机,但因为测不出来cpu时间,还是TLE了,两个破绽:一个是由于电梯选择策略是static块的初始化,导致第一次用的时候才开始初始化,不在一个线程容易出事。还有一个是在一个人所有策略都行不通时,会标记而且把它放在队尾,让下一个人上,即 remove 后 offer,可惜,我用的是
- 第一次
- 第三单元
- 第三次
- dijsktra求最短路径,初始值本应该为较大整数,但一时脑抽 初始化为2000,导致无法出现长于2000的路径,错了三个点。
- 第三次
- 第四单元
- 第三次
- 有多个 initial_state 时,将它们迁出状态的数量算到了一起,因此会导致正确的情况下也会出现008错误。
- 第三次
- 前两个单元都是搭了评测机的,帮我测了不少bug,但是还是有不少问题,后两个单元到是没怎么测试,但bug更少,可见难度还是逐渐降低了。
课程收获
理解了部分OO的思想,更加熟悉了 Java 这门语言,对多线程运作更加了解了,有一个好的设计可以减少很多需要用锁的地方,不要暴力,Jml,Uml,学了一点相关的算法,感觉手速更快了。
JML使得每个方法仅关注自己的事情,且由明确的表述使得验证起来更为容易,不容易出现差错,极大提高了编写代码的速度,而且调理清晰出错率低,但是感觉不够简明,光是写JML规格都是一项大工程了,可能这也是其无法流行起来的原因吧。但是确实好处很大,在团队合作中,这种规格,在提升团队协作效率和正确性可以产生巨大的优势。感谢 JML,使得我在 OS 的折磨时期,免受 OO 的侵袭。
UML作为一种统一的软件建模语言具有广泛的建模能力。UML是在消化、吸收、提炼至今存在的所有软件建模语言的基础上提出的,集百家之所长,它是软件建模语言的集大成者。UML还突破了软件的限制,广泛吸收了其他领域的建模方法,并根据建模的一般原理,结合了软件的特点,因此具有坚实的理论基础和广泛性。UML不仅可以用于软件建模,还可以用于其他领域的建模工作。
总而言之,OO的思想对于我的影响还是很大的,相信对于以后的工作学习,都会产生不小的积极影响。
立足于自己的体会给课程提三个具体改进建议
这么完美的课程哪儿来三个建议
线上学习oo课程的体会
OO课程是舍友同学们谈论最多的话题,增强了大家的友谊,是大学生活一笔重要的财富,我的OO老师纪老师年轻,有活力,热情饱满,敬业爱岗,给我留下了深刻的印象。同学们讨论区的参与度也非常高,助教对于实验平台的维护和更新也十分的及时,讨论课的主持也很热情,起到了很大的作用。总而言之,这是一门不可多得的好课,是很多人的很大付出才能构建出的一门课,体验极佳,希望以后还能上到质量这么高的好课。