• BUAA_OO第四单元总结及期末总结


    BUAA_OO第四单元总结及期末总结

     

    一、第四单元三次作业的架构设计

    本单元主要是要求我们去实现一个UML解析器,并通过这一过程了解到与UML相关的一些知识。由于从标准输入中输出的UML元素不能很好地反映出自己和其他元素之间的关系,于是我按照StarUML软件中UML类图的样子对输入的元素进行还原,最终的程序的架构如同在StarUML中我们可以看到的图类似。

    总体思路是按照一定的先后顺序对不同信息需求层次的元素进行分批处理。对于某些要求不可以重名的元素我建立了将名字name映射为其出现的次数的Hashmap,进行相关的查询时首先询问相应name出现的次数。另外,为了提高效率,由于我的查询大量的采用了递归进行查询,因此我的程序会在递归查询的过程中保存好已经查到的相关信息,避免多次递归时造成时间上的浪费,这一类似于记忆化搜索的方法在实际测试中效果也非常的不错。

    第一次作业

    UML类图

    如类图所示,我基本上按照两个查询的主体UMLClassUMLInteraction进行了架构。由于官方的UMLClassUMLInteraction不能存储其内部的相关信息,因此我采用了适配器模式封装了自己的MyUMLClassMyUMLInteraction用来存储自己内部理应存在的元素以及实现与自己相关的查询方法。

    具体实现上。 首先是在构造器中进行解析,遍历elements数组中的元素,分三个大批次进行解析。第一批解析UML_CLASSUML_INTERFACE,建立自己的MyUMLClassMyUMLInteraction对象并且在顶层使用id作为索引存储好相关的对象。如果不是这两种就放到一个ArrayList中作为第二批再分析。第二批处理UML_ATTRIBUTEUML_OPERATIONUML_ASSOCIATIONENDUML_GENERALIZATION UML_INTERFACE_REALIZATION,将相应的关系以及元素放到对应的位置。如果不属于这些类则放到第三批进行处理,第三批包括UML_PARAMETERUML_ASSOCIATION,找到UML_ASSOCIATION的两个对端,添加好关系。 在每一个具体的指令执行时,首先查找nameclasshashmap查看是否存在,然后查看namecounthashmap查看是否存在重名,这两步如果有异常要抛出,之后才能进行查询操作。如果正常找到了class,则调用该对象的相应方法。两个我认为比较复杂的方法都使用了内部类进行实现,感觉不是很优雅。 具体的具体方法中,我简单谈一下递归缓存的使用,做了缓存设计,后当继承链条为A->B->C->D时,我如果已经调用了B的方法,则A调用方法时只需要递归到B这一层即可获取B已经缓存好的结果。这个设计充分体现在各个方法中,最典型的是getImplementInterfaceList方法(在自建类中直接调用的是getImplementInterfaceNameList方法)首先获取的是名字List,那么要先找到这个类实现了哪些接口,包括这个类自身直接实现了哪些接口,这个类所实现的接口继承的所有接口,以及这个类的父类实现的所有接口。通过上文提到的递归缓存很容易实现本次的作业。

    第二次作业

    UML类图

    本次的作业是在上次作业的基础上加入了新的需求。新加入了对状态图和顺序图的解析。 架构上分三个Package分别封装了三种图中所含的不同元素,十分清晰。本 次作业的主要难点在于对状态图和顺序图的理解要正确。不同类型的元素其parentreference等因子代表的含义往往不同,注意好这些按照三类图将所有元素分发解析并不是很困难。

    需要注意的是状态图的后继状态的查询时可能出现状态成环的情况,设计时不能简单的采用递归求解, 会出现很多神秘问题。综合考量后我选择了bfs算法。

    第三次作业

    UML类图

    本次作业是针对mdj文件的有效性做检查,没有新的解析需求增加。在设计时,首先考虑的一个问题是有效性检查放置在哪个部分。根据题目的叙述,在完成类的初始化后,AppRunner会自动调用8个检查用方法,因此我们只需要考虑实现接口中对应的方法,无需手动对check方法进行调用(中测时浪费了两次机会在上面)。

    检查循环继承采用了n次bfs这种比较稳妥的方式,即从自己开始再找到自己即为循环继承。在寻找接口多实现和接口重复继承时,采用了判断set.size == father.set.size + self.interfacesize的方式,修改了第一次作业中的递归查询,满足了题目的要求。

    Bug分析

    本单元公测未出现bug。

    二、四个单元代码架构和设计方法总结

    四个单元的内容是按照层次化设计、线程安全设计、规格化设计 、模型化设计的逻辑进行的。详细的架构设计在每单元的总结博客中都有,这里简单谈一下每个单元带给我设计方法上的体会。

    第一单元

       第一单元学会了面向对象的一些最基本的概念。我将一个长表达式按照一定的层次分解成不同的对象,这些对象中蕴含了求导方法。通过多态实现了求导的操作,比较不错的通过一个面向对象的方式完成了对复杂多项式求导。

    第二单元

      本单元设计的主要目的是通过面向对象的思想完成调度工作以及实现线程之间的同步。 在这个单元我采用的都是消费者生产者模式来处理这个问题。基于这个考量我就设计了一个调度器类Dispatch以及电梯线程Elevator和输入线程Input这两个线程。 调度器类Dispatch以及电梯线程Elevator我设计成了强耦合的形式,双方互相包含,现在看来可能不是很优秀、安全的设计,但是在我开发时也能满足我的要求。

    第三单元

    第三单元是关于JML的。JML是用来对代码规格进行描述的,在实验课有根据代码写过JML,而这个单元的三次作业则是针对JML来补充代码。其实只要能够读懂JML代码,这个单元的作业就只剩下对于算法的考量和取舍了。架构的话课程组已经给好了,我在这个单元利用了内部类实现了一些操作,发现了内部类的一些好处。

    第四单元

      此前对于第四单元代码的具实现已经说得比较详细了,在此不再赘述。本单元在学习中另一个很重要的一个部分是对于UML中三种类型图的理解和运用,通过本单元的作业,我能够很好的了解UML的元素和工作原理。对UML图中的常见信息进行分析查询,这些信息其实都是我们在阅读UML图时需要重点关注的对象。UML图对我们迅速上手了解一个工程项目非常有帮助,它简洁而直观,能帮助我们很快地发现关键信息。同时也能让我们及时发现写出的代码和设计要求是否相符合。

     

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

    在前三个单元我都写了评测机进行测试,第四单元由于数据量与实践的限制十分宽裕,我只构造了一些我认为容易出现问题的例子,实测能够满足要求。

    第一单元中用pythonxeger自动生成数据,利用sympy库进行结果正确性的判断,实测自动生成的数据没有自己手搓的数据强大,但是我通过这次编写本次评测机,掌握到了数据生成、结果比对的对拍测试方式。(但是好像第三次作业公测对于WF的测试不是很充分?我在测试时发现很多同学对于一些情况的WF没有判断,但是互测又无法对WF进行hack,希望课程组可以解决这一问题)。

    第二单元的自动测试难度较大,我在参考了其他一些同学的测试代码后以及一位同学魔改后的接口后也自己实现了一个评测机,special judge部分工作量巨大。最终的评测机效果不佳,只测出了同学们线程无法正常结束的情况以及其他一些个明显的错误。

    第三单元学习了Junit的使用,可以让我的每个方法避免一些非常简单的错误。之后还是用python实现了一个数据生成器,程序通过维护图中节点的关系,能够自动进行数据生成,让我避免了很多的bug。

    测试的目的是为了发现自己的错误,通过几次评测机的编写,我熟悉了python和一些缓存机制的使用,发现了很多不易察觉的bug。

    四、课程收获

    在学期开始之前,我只对JAVA和面向对象有所听闻,没有使用JAVA的经验也不知道面向对象与C语言的面向过程有什么区别。但是在一个个作业的push下,我可以自豪的说我对于JAVA的使用已经十分熟练,对于面向对象的思想也有了很好的理解。

    面向对象的表现形式为继承·多态·封装,这一点在第一单元得到了充分的体现。

    第二单元我了解到了企业开发中必然用到的多线程开发,了解到了很多的设计模式并且对于解决线程安全问题有了自己的理解。

    第三、四单元 JML、UML等许多新的知识也让我收获很多。我了解了之前一直没有用过的Junit,复习了数据结构的一些个算法,发现了将枯燥的算法应用到解决实际问题上的快乐。

    五、三个具体的改进建议

    1、互测加入选取本小组的一份或几份代码给出自己对代码的见解,通过加分等方式鼓励同学们积极参与。在现有的互测机制之下,我们过分关注hack得分与被hack失分的情况,互测往往就是搭建好自己的评测机,将小组内所有成员的代码放到评测机里面去跑,但是我认为这样对于我们OO水平的进步只有一定程度的帮助,孔子曰:"三人行则必有我师",小组内同学的 代码应该在某些方面具有可取之处,有着一些我们自己没想到的架构方式或者某些局部有些很巧妙的小trick,因此我感觉在互测时课程组有必要引导同学们去仔细思考别人代码的优点与缺点。还有就是每单元都给出优秀的作业代码以供同学们学习,通过学习别人来使自己得到进步。

    2、第二单元的多进程部分可以适度的多加入些内容。在网上查阅资料时我了解到,多线程的部分在企业生产中有着非常重要的应用。《JAVA多线程设计模式》 中介绍了12个重要的线程设计模式,而第二单元的作业我只对于生产者-消费者模式有了一个较为深入的理解,其他的设计模式鲜有接触,建议课程组可以在作业或者实验中加入应用其他设计模式的一些练习。

    3、研讨课不只局限在同学们参加,一个学期的研讨课下来,感觉同学们一直在讲述自己是如何实现自己的作业,而没有讲述清楚自己是如何一步一步的架构出自己的项目的。我认为相较于接触OO时间较短的同学们,课程组有经验的学长学姐可以更好地教给我们解一个规模较大的工程如何实现的。理论知识同学们可以自学,但是一些工程上的东西、设计上的“好味道”与“坏味道”在目前看来也只能通过有着丰富项目经验的人来让我们更好地理解。因此我建议有助教学长可以分享自己的架构经验以及其他一些具体的项目经验。

    关于线上学习的体会

    本学期由于疫情的影响,授课只能采取线上授课的方式,这是一段很奇妙的经历。相较于线下的课程,线上课有着自己的特点,能够进行回放去回顾自己不懂的知识点,也可以让我们自己安排好时间进行学习,具有很高的灵活性。但是线上学习oo相较于线下课程就可能在讨论交流上有一定的限制,虽然有腾讯会议等软件, 但是感觉大家的参与度没有线下见面时高。

    在这里我要感谢课程组每一位老师和助教的辛勤付出,OO是体验极佳的一门课,我通过OO真的学到了很多很多。

  • 相关阅读:
    sqlserver创建链接服务器连接sqlserver脚本
    两步快速获取小程序源码
    SQL判断是否存在该数据 有则更新,没有则插入
    利用c#+jquery+echarts生成统计报表(附源代码)
    每晚定时重启IIS和数据库服务可节省服务器资源
    SQL中的循环、for循环、游标
    sql的行转列(PIVOT)与列转行(UNPIVOT)
    SQLServer 简单数据拆分
    IIS安装与MVC程序部署
    (六)HTTP和HTTPS(转)
  • 原文地址:https://www.cnblogs.com/sexyyxy/p/13161075.html
Copyright © 2020-2023  润新知