oo第四单元与课程总结

Part1 本单元三次作业架构设计总结

1.组织结构

由于官方代码中已经给我们提供了许多零散的类元素,如UmlClass``UmlAssociation``UmlParameter等,因此我首先将某些类按照我们平常的理解去进行组装,如UmlAttribute``UmlOperation等封装在MyClass内部,然后再将组装的类进行分级,层层调用。组装结果如下:

1592400898590

这样进行组装后可以将这些不便于直接使用的零散元素进行抽象,然后内部提供我们所需要的方法,从而更加便捷的去进行访问。

最外层的类MyUmlGenerallInteraction负责接收外界的输入,然后将元素封装好或者分配给下一级进行封装。

2.数据结构

数据的存储使用了HashMap,考虑到id的独一无二行,因此大部分的HashMap采用id为key去进行索引,如private HashMap<String/**ID**/, MyUmlClass> idToClass;,但是某些方法需要查询name对应的元素的信息,因此额外增加以name为key,索引name对应的id组,如private HashMap<String/**name**/, HashSet<String>> nameToClassId;

3.部分重要方法的实现
  • 缓存法

    考虑到大部分的方法都与类或者接口的父类有关,如“类的属性有多少个”、“类有几个关联等”,并且若想要访问完其所有的父类需要不断地遍历与循环,因此这部分采用缓存法,即模型有效性检查完毕后,使用一个容器存储所有class与interface对应的所有父类。

    状态机的后继状态查询``PTCP_OBJ_COUNT`也采用同样的缓存法

  • “R002:不能有循环继承”的实现

    对于一个结点,采用BFS的方式去遍历其所有父类,若通过BFS递归能够访问到自己结点,则说明存在一条自己向自己的环,则该节点存在循环继承。将所有的结点通过该方式遍历即可获得循环继承的结点。

4.不足之处
  • 我的开始的将官方元素组装的操作几乎都有顶部类MyGenerallInteraction完成,即“判断UmlElement类型->根据其信息将其加入到对应的类中”操作,导致该类在组装元素这一块显得特别冗长,不仅方法未能通过checkStyle,即方法超过60行,而且文件长度也非常大。

    应先做基本的分类,然后将元素直接传给下级MyClassAndInterfaceMyInteractionMyStateMachine
    再有下级进一步拼装,这样每次作业增加新的内容是顶部类不会因此而急剧扩大。

  • R002的实现采用对每一个结点用BFS的方式,若该点有循环继承,则能够较轻松的找到;若该点无循环继承,则需要遍历该点及其父类所构成的连通图,效率不是特别高。

P2四个单元中架构设计及oo方法理解的演进

1.第一单元

第一单元由于刚入门,对面向对象设计的认识很浅薄,因此架构的设计非常糟糕。

首先是可拓展性非常的低,每一次作业均只完成相应作业的要求,几乎每一次作业都要进行重构。比如第一次作业中变量就是有幂函数,因此除了MainClass,最顶部的就直接是Variable类,且该类只代表幂函数,忽略了后来的“表达式->项->基本初等函数”的结构。第二次作业引入了表达式与项的概念,再加上三角函数的引入,导致我不得不选择重构。但是第二次作业由于自变量都是x,因此在幂函数和三角函数里均未把自变量体现出来,导致第三次作业自变量可以为表达式的时候,我又不得不选择重构大部分方法与结构。我认为有时要对架构的改进进行适当性的预测,比如这次的自变量可以为表达式这一步骤,可以参考部分已存在计算器的功能,但是要做到相对完善的预测还是非常困难的。

其次是方法间的耦合性很高,一个低层次的方法很大程度上受到高层次方法调用环境的约束,而且要考虑很多特判条件。如对某些表达式求导或者打印的时候要判断很多情况,但是有时上级已经提供给了较为良好的条件,并且有些情况不可能发生,但是由于方法编写的时候方法之间关系过于混乱,因此增加了方法编写难度。

2.第二单元

第二单元有了相应的结构意识,因此重构的部分也比较少。

整体的架构设计为"外部输入->总控制器->电梯调度线程->电梯"的层层分级形式,每一级有较为明确的分工。但是第一次到第二次作业的架构改动还是较大的,因为第一次作业只有一部电梯,第二次作业开始就有多部电梯,一开始没考虑到采用一个总调度器管理所有电梯,因此添加了一个总控制器。但是第二次作业到第三次作业改动相对来说就小了很多,主要为将电梯类型进行分类。

同时函数间的特殊条件所引起的关联性也有所降低,且懂得了将函数的功能和目标更加合理化与具体化。如专门用来控制电梯运行的电梯运行算法,用来分配乘客请求的请求调度算法。

3.第三单元

第三单元因为官方已经帮我们设计好了架构,并且jml写的很详细,因此本单元没有架构设计,oo方法理解也没有演进。

4.第四单元

第四单元我的架构设计是将官方所给的零散的元素进行相应的封装处理,内部提供我们所需要的方法,然后通过层层访问调用,以实现我们所需要的功能,总体为分级形式。

我认为该单元很好的体现了面向对象程序的设计。因为首先教我们如何将一个非程序的现实问题进行分解,如这次的对UML框架图、流程图、状态图的分解,然后让我们去进行合理化的组装,提供不同模块间合理的交互过程。并且大部分抽象封装分级过程由我们自己实现。

然后该单元还让我体验了良好的团队合作,及官方经过分解操作提供给我们一些需要进行交互的类,剩下的解析访问与检查交给我们自己来实现。

P3测试理解与实践的演进

1.第一单元

第一单元我的测试主要以自己手动捏数据的黑盒测试为主,但是面对一个较为复杂、情况诸多的程序来说,靠人工来进行完整的黑盒测试是非常困难的,因此我有很多地方没有测试到,产生了较多的bug。

2.第二单元

第二单元开始白嫖大佬们的自动评测姬,不得不说评测姬的效果还是非常的好,通过大量的数据测试也确实非常的有效,检查出了很多bug,并且评测姬还实现了现实总运行时间的功能,因此性能部分也得到了保证。

3.第三单元

第三单元继续白嫖大佬们的评测姬,但是由于评测姬部分数据未能检测到,再加上我对评测姬过度的依赖,自己几乎没有做什么测试,因此有一次作业产生了非常严重的bug。自此我意识到了不能够过分的依赖评测姬,于是使用了老师教的junit工具测试法,去对每一个具体的函数块进行功能测试。但是要想测试完所有的函数是非常耗时的,因此我选择对某些核心且较为复杂的函数进行较为完全的呢测试。但是手动测试也有很大的不足之处,即无法测试程序的性能,因此采用了junit测试+评测姬双管齐下的方法,去进行测试。

4.第四单元

第四单元由于官方提供给了我们较为方便的数据生成工具,即通过starUml建立相应的图,然后通过图来生成具体的测试数据。由于图形化的测试方式,会给测试结果的检验带来很大的便利性,并且图形化的测试也比较容易发现一些特殊情况与边界数据,因此本单元大部分测试以自己手动建图为主,然后评测姬加以辅助进行测试。

5.总结

人工的力量去进行黑盒测试是非常苦难的,因此黑盒测试部分应交给评测姬去进行测试要用魔法去打败魔法。但是通过一些数据去进行基本功能的测试也是非常重要的,可以与评测姬互相验证准确性。同时白盒测试也异常重要,他让我们将整个程序按照功能去进行分割,对功能专一的函数块去进行测试,因此测试难度也会大大降低,这对关键易错的函数的检验是非常重要的。

P4课程收获

1.java基础知识的掌握

除了最近本的类、接口、容器的使用,经过四次作业我还学习到了正则表达式、多线程基础知识、基础jml语言、uml架构图。

2.架构设计

通过整个oo的学习,我认识到了将一个庞大的问题进行分割,将共通性元素进行组装的重要性;通过第三单元的学习,我明白了函数的前提、结果应当是明确的,函数功能应当是专一的;通过第四单元的学习,我学会了将不同的类进行层级上的分类,不同层级的类合理的进行上下级的调用。

3.测试

我学会用Junit去对一些核心的、关键的函数进行一个较为完整的测试。学会了白嫖同学的评测姬。

除了上述的几点,我还认识到了一个好的程序除了应该有正确性的保证、良好的架构设计,还应当具有良好的性能,如第一单元中最终表达式的长度应当尽量短、第二单元中服务所有乘客的总时长应当尽量短,以及三四单元如何更快的从图中搜索出相应的结构。

P5课程改进 建议

1.课程顺序问题

首先是开幕雷击的第一单元,明显能够感受到第一单元的难度程度均高于后面的单元,一是其设计完全由自己来实现,二是对输入的分解以及抽象并不是那么好做,再加上刚开学,对java的熟练程度并不是特别高,因此对当时的我们来说难度是很高的。

然后就是第三单元,明显能够感受到其难度以及要求与前两单元的脱节,对于一个主要培养结构设计的课程来说,出现在这个位置的第三单元我感觉是意义不明的甚至由于时间的遗忘,反而会一定程度降低我们结构设计能力。但是其模块化的编写函数的思想还是值得我们学习的,我认为应当将第三单元放置在第一单元的位置,同时有助于刚学oo课程的学生们去进行对java语言熟悉的一个良好过渡。

2.实验课问题

我认为实验课的效果不是特比好。经过了一学期的实验课学习,我感觉实验课的收获甚微。

一是实验课时间安排的并不巧妙,实验课就在理论课的第二天,每次实验课开始时我并没有对相应基础知识有非常好的掌握。

二是实验课每次的内容都显得非常奇怪。第一是较为局部,实验课往往会针对理论课中的某一点去进行考察,第二是与当时我们已到达的阶段有些不符,例如第三单元的两次实验课分别是jml编写和根据jml填补空缺,明显前一次实验开始时我们才刚接触jml语言,还需要一定的时间去进行记忆与掌握,但是却考察了非常细致的jml语法,且当时给的样例难度较高;然后后一次实验又变为难度非常简单的根据jml写代码,当时我们已经写完了两次jml作业了,对jml也能够较为熟练地阅读了,反而给出了一个难度不适的实验。

因此我认为每单元第一次的实验课应当带领我们对该单元大范围的基础知识进行了解,这样不仅会带我们更好的理解前一天所学的理论课知识,而且会对我们之后的作业书写带来帮助,然后每单元第二次实验可以进行相应的深度考验。

3.课程间联系

这一点其实与上一点较为类似,就是我认为理论课、实验课与作业并没有给我带来一种层层递进的感觉,总感觉理论课与作业之间少了一块巨大的空白。

理论课往往是给一个大致的框架,对一些知识的描述也是较为抽象的,因此有些难以具体理解,但是作业又要对具体知识有较为深得掌握。因此我认为让实验课去引导学生去较为广的、浅的理解大部分理论知识,然后再交给作业部分进行知识的打磨效果会更好。

希望能够增加理论课、实验课、作业间的联系与递进关系。

P6线上学习体会

我认为理论上线上学习效果应当是比传统教师学习效果好的,一是线上能够方便大家在群里进行讨论,极大的提升了讨论热度与同学间的交流程度与广度。二是课程能够录屏,当自己遗忘的时候是可以再次回顾复习的。

但是由于自身的问题,线上课程有许多并没有积极的看,讨论也并没有积极的参与进去,因此反而使得自己的学习状况不是特别好。

总之课程组和老师们的线上教学还是比较成功的,在此感谢老师们与助教们的辛勤付出。

原文地址:https://www.cnblogs.com/miku-mylife/p/13155288.html