BUAA OO Unit4 总结 && OO 课程总结

本单元是通过输入UML类图、顺序图、状态图来查询其中的元素,相关内容以及检测该UML模型是否符合规范,有些类似于不给JML实现一个第三单元的感觉,依然是比较简单呀,当然这篇博客还包含了对于整个学期这门课程的总结

Unit4架构设计

先上第三次作业的类图,之前的因为每次都是在前一次基础上加东西所以不放了:

image-20220622200133537.png
  • 首先是用代理模式对官方包中的各种UML元素进行粉装,建立自己的MyUML*类,同时往类中添加相关方法与容器实现对于UML模型的快速查询

  • 大的框架上分为了\(4\)个部分,类图包,顺序图包,状态图包,每个包中分别是自己实现的对应UML模型的元素类,还有就是一个MyImplementation类,主要负责将输入元素分发到各个图中,以及调用各个图中提供的相应方法实现指令查询

    以其中的类图包为例,其余两个包类似,通过类ClassDiagram接收来自MyInplementation传入的相关元素,然后分别解析每个元素以及负责将下层元素分发给下层进行解析存储,同时大部分需要查询的指令做离线查询处理,提前保存结果

  • 对于第三次作业加入的异常处理,我选择将每种异常的判断都放在MyUML*里面进行判断处理而并未单独新建类然后解耦,主要原因在于考期来了,这样做比较容易实现

  • 关于算法方面,查询循环循环继承我采取的是\(Tarjan\)算法,时间复杂度为\(O(m+n)\),也可以用拓扑加\(dp\)来做,或者是写起来最简单的\(Kosaraju\) ,两遍\(dfs\)解决一切。其余查询继承,实现,以及重复继承都直接普通递归或者\(dfs\)

  • 关于容器基本采用的都是Hash*,其中不乏HashMapArrayList,前者键值为\(name\),键值即为ArrayListArrayList中存储同名元素,方便于快速判断重名以及不存在异常

架构设计思维与OO方法的演进

  • Unit1:第一单元参考了实验代码,通过将表达式依靠不同的运算种类拆分为不同的因子,并将因子抽象为类,同时依靠表达式的层次结构将类与类之间的关联,继承关系建立。在更高层的因子中进行低层因子的运算,同时在大框架上将代码逻辑分为\(3\)个部分:

    \[input\ \ \&\&\ \ parse \rightarrow calculate\ \ \&\&\ \ simplify \rightarrow output \]

    自我认为架构还是不错的,即使现在再来实现一遍第一单元也还是会用这个架构,但是具体实现到了后两次及其不美观,多处地方用了instanceof还有非常多特判与重复代码,同时代码的耦合程度与圈复杂度也非常高,不过由于当时刚刚接触Java与面向对像,对于美观的代码没有太高的追求于是忽略了这些问题

  • Unit2:第二单元接触了多线程,主要是在一个生产者消费者模式上进行一些架构的设计,如是否使用调度器,将调度策略与电梯分开实现,从而使它们解耦合增强可拓展性等等,但由于架构都比较简单所以看不太出优略。当然这里比第一单元还是长进了许多,通过将各部分如调度策略,电梯,调度器等等解耦后的代码从idea的代码分析上看没有一处标红的方法,并且从这个单元中我学会了要在合适的时候抽象出接口与抽象类同时减少一些不必要的方法,从而减少重复代码。当然这个单元最大的难点在于多线程本身,而不是在于架构设计方面。在这个单元中我不断地从自己的bug中开始对多线程有了一定的理解,比如同步块该如何确定,是否要上锁等等

  • Unit3:第三单元学习了JML语言体系并且初步接触了契约式编程,体会了完全给出规格实现是一种什么样的感觉,这个单元其实架构是一开始就给好的,但是就每个函数而言给出的只是规格并不是具体实现方法,因此要自己探索,我认为自己这点做都还不错。于这个单元比较简单,因此大半的时间都是在思考如何写出更加简短易又懂高性能的代码,比如用三目运算代替if else,用streamforeachmerge等等的容器内置方法代替自己手动的for循环。可见这个单元提高了自己对于代码美观的追求,而不再像第一单元那样只追求\(0\)bug

  • Unit4:这个单元学习了UML模型,实现了对于一个给出的UML模型相关内容的查询,有点像是不给JML的第三单元或者是第一单元的简化版,这个单元总的来说除开学习了UML的一些元素结构关系外,就是将自己从第一次到第三次每个单元所学到的编程技巧oo方法加以运用,比如运用第一单元学到的的从上层到下层拆分的方法、第二单元学到的通过一些接口抽象类将重复部分解耦合(状态图的state就可以做成一个抽象类)、第三单元学到的简化代码的技巧等等

总结一下:从架构上我通过oo课有了遇到新的一个项目的基本处理方法并且在历次作业中不断的实践:先将任务元素提取特征拆分抽象为类,接口。然后再根据具体的任务思考如何实现更加优雅简短,以及为类、接口之间添加什么样的关系以及方法从而在完成任务的同时提高拓展能力

测试理解与实践的演进

  • Unit1:第一单元通过PythonSympy库比对结果是否正确以及递归下降生成数据实现对于自己代码的测试,当然其实最重要的还是自己构造的小数据进行随机的测试,毕竟真的有问题一般很短的数据就可以暴露出来问题
  • Unit2:除了写了点数据生成以及一些测试接口,剩下的spj什么的就抱大腿了,当然多线程的测试并没有这么简单,并不是代码逻辑以及一次运行结果正确就行了,除了一般的功能测试还必须进行线程安全测试,因此还需要对每个线程的状态进行分析,于是我选择了JProfiler通过分析给出的代码运行时个线程状态折线图以及方法的cpu占用时间检查线程安全问题
  • Unit3:这个单元只用写数据生成器以及简易的对拍程序,但是也有难点,就是如何提高数据的覆盖度,一个是提高数据量还有就是针对代码内部逻辑以及抛出的异常设计数据,最后用Junit分析数据的覆盖度
  • Unit4:最后一个单元由于要期末备考于是选择用别人的数据生成器以及对拍器测试以及肉眼debug的方法,当然我觉得这个单元最好的\(0\)bug策略其实是多看讨论区别人的提问检查自己理解的有没有问题以及第一遍实现的时候就应该仔细小心而不要为了爽一下子就写完了,最后说不定一堆bug,然后即使de了也不一定de干净了

总结一下:从测试上其实各个单元没有太大的递进关系,只是让我们学会了面对不同的任务如何做测试

课程收获

  • 对于面向对象有了一定的理解,所有的事物都可以抽象出类来,而不是像c语言那样直接将方法属性全都暴露出来,这样做封装性很差,在代码量达到千行以上时阅读理解起来是一件非常痛苦的事,比如学习os
  • 多了一些多线程相关知识以及JMLUML等等这样的技能,码力也得到了较大的提升,以前一份代码写得最多的可能就是什么平衡树两三百行,现在平均一个单元就是\(1000\)行左右的量,当然这是经过我优雅的实现才有的结果
  • 提高了自己写代码的优雅程度,无论是代码风格还是实现的方法以及命名等规范都得到了提高,比如现在看到有些人python代码用Java的脱驼峰命名,导致的Pycharm警告就会忍不住血压升高,毕竟小写下划线才是正道,看到别人换行不规范,一堆if else的代码更是想骂街
  • 抗压能力,赶ddl能力也还是有一定的提高,因为第一,二单元第一次被搞残了,一个是写到凌晨三点,一个是一个bug从中午de到晚上\(10\)点,当然这也让我从第一单元第一次作业之后每周就是周一开始一天写一点点,周四左右就写完了,当然最后两个单元有点简单一般周一晚上就写完了

改进建议

  • 第二单元多线程可以多一次任务,第三或者第四单元少一到两次任务。首先是因为多线程本身难度较大,我认为需要加强练习,其次第三第四单元比较简单我认为没有必要花太多时间,因为除开第一次作业外基本学不到太多东西,可以将这两个单元的第二三次作业合成一次作业,反正第二第三次作业都简单,基本就是考考简单算法,最后就是因为考期还要写oo有点难受
  • 第三第四单元的研讨课感觉属实没有学到什么东西,其中有些演讲的ppt的内容就是让我CSDN上搜索半个小时再花半小时准备ppt,最后再花半个小时练一下的工作量,并且台上的人讲的也很浅薄,相反像第一,二单元那样研讨课是架构分享而不是一些很宽泛的东西比较有用
  • 建议加强强测的强度,让同学们自己通过互测发现和加强强测强度不矛盾吧,例如第一单元强测数据也太弱了吧,并且有些优化都没有被测到,其次我认为代码性能也可以作为评测的指标。同时比如第二单元第二次作业我就一个bug结果WA好多点,但是第三次作业有一个我认为十分明显的bug(到同一层楼但是没有横向电梯),却一个点都没有,这说不过去吧,不如每次都强测搞\(100\)个点,再分不同的强度以及类型分开给分,一晚上的时间评测机不会这么不给力吧。。。

总之我还是很喜欢oo这门基本纯coding的课的,最后祝oo课越办越好,完结撒花!!!

posted @ 2022-06-22 20:16  Harahan  阅读(40)  评论(0编辑  收藏  举报