zoukankan      html  css  js  c++  java
  • OO第四单元总结&期末总结

    OO第四单元总结&期末总结

    第四单元总结

    这一单元需要解析UML类图、顺序图和状态图,还需要检查类图的有效性。在解析UML类图的过程中,我对UML的整体结构和各种继承、实现的关系更为了解,有了很多收获。

    第一次作业

    1. 任务需求

      这一次作业主要是解析类图,我们通过开源接口得到类图中的一系列UmlElement,转换为对应的类型后,分别将所涉及到的诸如继承关系、接口实现、关联关系等信息存储起来,然后需要提供基本的查询功能。

      这次作业涉及的细节很多,容易出错,而纷繁复杂的关系信息正好锻炼我们的能力,也深化了我们对UML的理解。

    2. 架构设计

      考虑到了这次作业所需的容器和方法极多,为了避免MyUmlInteraction类中代码过多形成“屎山”,我把所需的方法分门别类写在MyClass、MyOperation中。

      再把类中的属性以id和name为key,把类的信息作为value分别建立HashMap进行索引,以应对查询的不同需求。将索引和属性利用类做中转,通过分级,使得结构更为清晰。HashMap查询的性能十分优异,分类之后各种索引关系一目了然。

    3. 重构

      在这中间经历了一次重构,因为之前方法全写在一个类中,所有属性单独作为HashMap的value写起来实在令人痛苦。重构的过程也让我对整体的需求有了更深入的了解和思考,也发现了之前的半成品中的bug。这也算是意外之喜。

    4. 做完后的思考总结

      这次作业整体难度并没有上一次高,但是正如助教所说的“深度不大,广度很大”,所需考虑到很多细节,所以对于架构的要求更高了,需要在设计上下功夫,不能硬莽,只靠爆肝的确是行不通的。

      同时,由于有2s的时间限制,在保证正确性的同时,性能也是不能忽视的一个重要方面。在数据存储问题上,我使用HashMap,借助其O(1)的查询复杂度减少用时。除此之外,我还在回溯查询Top父类时,将中间结果保存下来,用记忆化搜索的方法防止多次查询父类超时。

    5. bug分析

      没有bug

    第二次作业

    1. 任务需求

      这次作业共有四个任务:解析UML类图、查询UML顺序图、查询状态图和对类图的有效性检查。

      也是类似于第一次作业通过开源接口获得UmlElement信息,加以分别存储,再进行操作。只不过多了有效性检查操作,新增了状态图和顺序图。

    2. 架构设计

      解析UML类图直接沿用第一次作业的代码。

      查询UML顺序图、查询状态图:整体上与第一次作业差不多,将状态图和顺序图以id和name为key,以类的信息作为value分别建立HashMap进行索引。

      有效性检查:

      R002:重名检查

      通过一个HashSet,遍历时存储属性name和关联对端的name,如果遍历时要存入的name已经在HashSet里面了说明重复,最后再抛出异常。

      R008:循环继承

      检查是否有循环继承时,我使用了dfs进行搜索,将搜索中经过的类或接口存下来。

      如果再次访问到了同一个类或接口,则说明存在循环继承,把之前存储的所经过的类或接口在异常中抛出。

      R009:重复继承

      这里需要考虑类对于接口的继承,如果有两条路径能够到达同一个点,则将这个类和接口以及其所有子类和接口加入到Set中,最后抛出异常。

    3. 做完后的思考总结

      还是类似于第一次作业的思想,将不同的方法归类,解耦合,降低思考难度,使得代码清晰,便于debug,防止陷入“屎山”无法自拔。

      在搜索的时候注意记忆化搜索,避免时间复杂度过高。

      在第二次作业初次提交后发现还是会存在NullPointerException,所以对于代码里面所有使用get等方法的HashMap和HashSet都再在前面补上是否为null的判断。

    4. bug分析

      没有bug

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

    1. 第一单元

    这一单元是多项式求导。

    1. 第一次作业:a*x^b的求导
    2. 第二次作业:a*x^bcos(x)^c*sin(x)*d的求导
    3. 第三次作业:表达式求导

    第一单元的第一次作业是简单的正则表达式,在这次作业我还是没有体会到所谓的面向对象的思想,使用的仍是大一时接触的类似C语言的面向过程的写法。

    但是,很快在第二次作业、第三次作业,我越发觉得这样行不通了。在大规模重构后,我实现类的分层、分级,对不同类型的表达式实现封装,降低耦合。

    2. 第二单元

    这一单元是电梯。

    1. 第一次作业:单部电梯,不需要捎带
    2. 第二次作业:单部电梯,需要考虑捎带
    3. 第三次作业:多部电梯,需要考虑换乘

    需要考虑多线程的运用和生产者消费者模式的运用,在controler的设计时需要考虑分层。

    使用多线程时,需要考虑死锁问题,在临界区需要加锁。

    生产者消费者模式是多线程的经典设计模式,可以很容易地帮我们实现功能的拆分。

    只有单部电梯时,controler只使用了一个类就完成了所有的控制。但是到了第三次作业,不同电梯各自需要控制,而不同电梯的换乘等同步操作需要一个整体控制器,需要将控制器分层,对电梯分级调控。

    3. 第三单元

    这一单元是JML。

    1. 第一次作业:设计Path和PathContainer两个容器。
    2. 第二次作业:查找最短路径
    3. 第三次作业:地铁换乘

    这一单元体现了对于算法的时间复杂度的极高要求。

    第一次作业主要学习了HashMap等容器的使用,利用O(1)的查询效率避免超时。

    第二次作业运用了dfs搜索的方法解决最短路径的查找。

    第三次作业运用了拆点的神奇技巧避免超时。

    在这几次作业中我对之前数据结构中所学到的图的相关算法有了更深层次的了解,并在几次重构中对更深入地体会了架构的重要性,正如张少昂助教所说良好的架构是好的算法的保障,架构混乱写出来的代码也必然满是bug。

    4. 第四单元

    第一单元是UML。

    博客第一部分已做了详细分析,故不赘述。

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

    第一单元

    这一单元我按照讨论区中的方法写了测试脚本,借用python中的scipy库进行正确性检验,利用jar包进行自动化测试。

    在第一次、第二次作业中这种利用scipy的正确性检验可能还不是十分重要,用肉眼也可以做出判断。

    但是,在第三次作业中,由于表达式的出现为求导和化简增加了不少难度,此时scipy就显得十分重要了。

    不仅是检验自己的正确性,也可以做互测时发挥很多作用。

    第二单元

    这一单元的测试困难了很多,我最后用了python检验了所写的java版本不同线程输出的结果的正确性。

    可能是我写的测试脚本有问题,或者是多线程本身的不确定性,自己检测出了别人的bug都没有成功刀到别人。

    但是这次利用边界条件测出了一些代码逻辑不够严密的同学的bug。

    第三单元

    这一单元,我学习了很多关于单元测试的技巧,利用JUnit等工具能够实现普通测试做不到的完全覆盖,与单纯暴力盲测相比这种测试更为有效和有意义。

    但是在这一单元中真正使用JUnit时我还是遇到了很多困难,由于某些模块的设计耦合度太高,难以使用JUnit测试。

    第四单元

    这一单元我自己构造了很多复杂的UML,设计了很多特殊边界条件的情况。通过与他人对拍,我找到了自己设计上的不足与考虑上的遗漏。

    在测试的过程中,我加深了对UML类图的思考,更充分理解了顺序图和状态图的构成和作用。

    除此之外,我也对starUML工具更加熟悉了,这的确是一个好工具。

    课程收获

    在考期结束后,我终于能怀着激动的心情写下这一部分作为整个OO课程的一个句号。

    从寒假到暑假,一个学期都过的很充实。从星期一到星期日,一整周都被安排得明明白白,没有丝毫空闲。

    不得不说我的收获是很多的,下面我分几点对我的这个学期的OO学习经历进行总结。

    1. 设计模式

    在电梯作业中,我学习了单例模式和工厂模式。这是我之前写面向过程的C语言完全没有遇到过的。这些设计模式将面向对象的思维发挥了出来。我在看牛客网上的面试经验时就看到了许多开发岗会问到“了解过多少种设计模式“这种问题,我能在OO课上接触到这些东西感到很有收获。

    2. 合理封装与降低耦合

    在第四单元中,我在重构后将类的属性封装起来作为HashMap的value值,避免了重构前所有属性都单列一个HashMap所造成的代码冗杂的问题。

    封装可以对代码的安全性提供保障,让用户只访问到他需要的东西,避免重要信息外泄,这在以后的实际开发工作中会是十分必要的。

    同时,封装的过程也是对于代码的不同模块的一个拆分过程。在封装时,我们就将不同部分的耦合度尽量降低了,有利于代码的维护,提高可读性。

    3. 代码风格

    从一开始,课程组就使用checkstyle检查提交代码的代码风格。

    在之前的数据结构的学习过程中,说实话,我的代码非常混乱,根本不知道驼峰命名,变量名混杂着大小写和下划线。

    但是在OO的学习过程中,我也逐渐养成了重视代码风格,重视代码可读性的习惯。事实证明,通过良好的代码书写习惯,我现在重新审视第一单元的作业的代码时仍能够大致理解当时的思想,不至于出现自己看不懂自己写的代码的尴尬情况。

    在实际生产的环境中,一个项目通常是多人协作,为了让一个团队能够更好交流、互相理解,代码风格就显得十分重要。

    课程建议

    整体来看,OO课程应该是我目前在六系所接触到的最为满意的专业课,但是仍有一些小细节希望课程组能够做出改进。

    1. Junit建议在课程上做出更详细的介绍,而不是让学生自学。

      Junit的使用本身就较为复杂,想要用好、想要能够真正帮助我们找bug是更为困难的,所以建议课程组做出更详尽的讲解。

    2. 每次实验课做完建议提供自己的得分。.

      不知道正确与否,没有什么反馈,所以相应的收获也少。

      即使像助教在水群中暗示的那样实验课有用来调分的作用,我觉得至少得公开一部分能够体现出成绩的东西。

      这里出一个馊主意:可以把最终结果乘以不公开的系数,到了期末在对成绩不理想的同学进行调分操作。

    3. 降低强测的耦合度

      在bug修复过程中可能会发现错了很多,但都是一个bug。而强测又是最终得分的重要依据,这就导致了很多不必要的失分。

  • 相关阅读:
    索引初识
    python数据类型之 元祖、列表字典
    linux常用命令之网络命令
    linux命令之查找find &grep
    python数据类型之可hash,不可hash
    python面向对象之封装,多态与继承
    python之新式类与经典类
    python之random随机函数
    CSS3选择器(一)
    关于居中
  • 原文地址:https://www.cnblogs.com/sherpahu/p/11075610.html
Copyright © 2011-2022 走看看