zoukankan      html  css  js  c++  java
  • OO第四单元UML作业总结兼OO课程总结

    一、本单元架构设计

      第一次作业

      本次作业的内容是完成一个UML类图解析器,主要工作是构建合适的数据结构并完成类图解析所需要的查询函数。我本单元作业采用的思路都是,先将UML模型中的各个元素按照一定的从属关系进行构建和分类,然后再进行查询。

      集体而言本次作业的数据结构组织如下:

      总体上来说本次作业难度不大但有些繁琐,主要考察的是对UML类图结构和作用的理解,需要注意的是类的继承关系关联关系和接口的多继承,以及部分方法的复杂度。UML图如下:

      

      第二次作业

      第二次作业相较于上一次增加了对于顺序图和状态图的解析,但仅增加了6个很简单的方法,涉及到的元素类型也比较少,所以我没有对涉及不到的元素类型进行处理,我采用的数据结构组织如下:

    第二次作业,整体上并不困难,但是因为增加了两类模型,所以代码量变多,如果单纯在上一次作业的基础上迭代的话,很容易单个文件超500行,以至于不能通过checkstyle,但是因为写这次作业的时候我脖子拉上,不能长时间敲代码所以我选择了压行的方式来强行过checkstyle。UML图如下:

      第三次作业

      第三次作业,增加了有效性审查的部分,有部分方法有一定复杂性,本次作业中我进行了重构,重新设计了架构,让其更为合理,采用了三个manager类来管理三种模型,在数据结构的组织上与上次作业大同小异,但因为测试没有做足,以至于最后发现了bug但没来得及改。UML图如下:

      总体上来说作为oo的收尾单元,本单元比较简单,但从结果上来说,我还是有缺憾的,因为在最后一次作业中没有做足测试,最后测出了bug也没时间改了。通过本单元的学习,我了解了一些模型化设计的理念和方法,但我认为,本单元作业更倾向于了解UML这个模型化设计的工具,而非模型化设计的理念,有些遗憾,但仔细想来,这一方面是为了进行作业布置和评测,另一方面也是为了让我们对于UML图有一个系统的把握。但是相较而言,我认为本单元两次实验更能体现模型化设计的思想。

       完成了三次作业了解了类图顺序图和状态图之后,我们脑海中对于UML图理解也大致构建了起来,三者之间虽有不同但实为一体,并非互相割裂的。三者是从不同的角度来描述设计,需要结合起来理解,UML类图描述是是类与类和类接口之间的关系,更倾向于描述设计的静态架构,可以让我们对于系统有一个整体的把握;UML顺序图描述的是对象之间的交互过程,可以让我们明确程序运行过程中的时序组织;状态图描述的是类的状态转化情况,可以让我们明确类产生变化的条件,是对于类图的补充。这三者互相依托相互补充,绝不可孤立看待。OO的最后一次实验课的内容是检查类图、顺序图和状态图三者之间的一致性,其目的也是让我们加深对于这一点的理解。

    二、对OO四个单元的总结及对OO的理解

      第一单元

      第一单元的内容是表达式求导。这个单元是OO的第一个单元,尽管有之前的两次预习来熟悉java的编程方式和面向对象的思想,但在实际实践中却依然不容易。在第一单元的作业中我没能真正理解面向对象的思想,在实际编程中想的依然是如何以最直接的方式解决问题,仍然是面向过程的思想。例如,在第一次作业中我只设置了两个类,一个Main一个Func,实际上至少将一份“面条代码“里的部分拆出来封装成一个函数而已,并没有以面向对象的角度思考问题,也没有做好对代码的可拓展性的保证。尽管当时写完代码的时候觉得自己优化做得还不错代码整体也不错,但实际上经过一学期的学习,再回头去看当时的代码只能用”惨不忍睹“来形容,可以改进的东西太多了。但这毕竟是OO的第一单元,主要目的是对于面向对象编程的入门。

      下面是我第一单元第三次作业的UML类图,可以看出我只是按照函数的类型进行了大题的分类,没有很好的利用java的种种特性和践行分层的思想,单独独立出来一个类来描述方法更是于面向对象——封装数据和函数的思想有违背。

      

       第二单元

      第二单元的内容是模拟电梯调度。这个单元主要是多线程编程,从难度上来说我认为是OO历次作业中难度较高的一部分,难度主要来源于对于线程安全的理解和应用。对于多线程编程,一不小心就会出现死锁或者死循环的问题,而且多线程编程的结果有一定的随机性,遇到问题难以复现,这也加大了多线程debug的难度。本单元作业中,我吸取了上一单元中的一些教训,在架构方面进行了较为认真的设计,践行了层次化和模块化的思想,效果也是很不错的。在第三次作业中得到了99.881的成绩,但是让人非常遗憾的是,在第二次作业中我忽略了system.in的线程安全问题,导致了强测爆零(永远的痛)。

      第二单元,我采用了读入器、调度器、电梯三类线程。每一层处理都追求高内聚、低耦合,线程之间的协作图如下所示:(详细的设计分享见我的第二单元总结

      第二单元第三次作业中我的UML类图如下所示:

      

      

      第三单元

      第三单元的内容是根据JML的描述写代码。本单元的主要目的是让同学们了解契约化设计这一理念,因为契约化设计在实际的工程开发中可以避免对于需求认知的偏差以提高协同效率,但真正将这以点落实到作业实践中,我认为效果却不是很好,因为JML语言的读和写都是十分繁琐的,尽管可以避免自然语言的二义性。但是将脑海中的自然语言转化为JML再将JML转化为脑海中自然语言形式的理解并没有那么容易,从这一点上来说单纯使用JML来描述需求实际上并不一定能起到提高效率的效果。我认为在实际的协同中应采用自然语言和形式化描述并存的方式,这样既能降低理解门槛也能避免二义性的问题。本单元基本上都是写函数,没有什么架构上的问题,问题基本都出在对于需求的实现上。需要牢记的是,JML只是描述一种需求,并非描述期望的代码逻辑,具体代码怎样实现还是编程人员自己的自由,如果按照JML照抄代码,吃亏的只能是自己。(例如作业中就需要十分注意复杂度的问题)

      第四单元

      在这里就不对第四单元的内容赘述了,想说的内容已经在上面提到过了。

      总结

      经过四个单元的学习,我对于面向对象编程思想的理解相较于学期之初有了长足的进步,也逐渐理解了java“封装、继承、多态”的三大特性及其重要性。同样一句“面向对象本质上就是对数据和方法的封装”从初闻到现在感受已截然不同,很多时候一个道理或者一种思想,只有自己亲自践行过才能够真正的理解。面向对象相较于面向过程更接近人的自然思维,它的封装程度也更高,可以提高程序的重用性、灵活性和扩展性。但凡事都是有代价的,实际上面向对象编程再获得以上优点的同时也牺牲了一定的效率,面向对象编程继承的特点也让后续的工作对之前的工作有所依赖,一旦过去的架构满足不了现在的需求,就可能要面临大规模的重构(可扩展性也是有一定的限制的)。总之,编程的思想没有绝对的好坏之分,编程语言之间也没有,只不过适用的场景有所不同罢了。面向对象编程是一种解决问题的利器,但并非无往不利。

      回归到课程本身来说,我个人在四个单元作业中对于面向对象编程理解程度的增长速度从大到小排序是:第二单元、第一单元、第四单元、第三单元。每个单元都有所收获,但前两个单元的收获是最多的,但其实在我的预期里对于面向对象编程理解增长的高峰应当在第三单元,但实际上第三单元并没有给我这样的感觉,实际上感觉更像是在考算法。

    三、关于测试

      对于OO作业的测试,单纯手动出数据很多时候是满足不了测试的需求的,这时就需要使用自动化的测试手段来提高测试强度。自动化测试也是工程项目中很重要的一部分,在OO的作业中我构建自动化评测的方式是,使用python生成测试用例,然后再运行代码获取输出,最后将输出和标准输出或者别人的代码的输出进行对拍,来判断正确与否。本学期的OO课程中,我在第一、二、三单元都编写了评测机来进行自动化测试,虽然整体思路都相同但实现方式都有差别,下面我将详细阐述我每个单元的评测机:

      第一单元

    获取输入数据 python xeger库
    运行代码获取输出 java Process类运行命令行+输入输出重定向
    获取标准输出并比对 python sympy库

      这一单元的内容是表达式求导,由于python中有xeger类来根据正则表达式生成字符串,所以可以利用这一点来生成评测的输入,而之后运行代码的部分我使用了java中的Process类运行命令行并将输出重定向来获取代码的输出,最后使用python的sympy库来求导获取标准输出,并比对正误。这样做的优点是,java语言比较熟悉,开学之初刚接触shell并不熟悉,可以使用java来进行替代(顺便也能练练手hhh)。但本单元中的自动测试需要注意的是一定要确保生成样例的正确性,也就是说明确wrong format的情况有哪些,不然就算测试做得再多,最后还是会因为wrong format而失分。

      第二单元

    获取输入数据 python
    运行代码获取输出 python subprocess库运行命令行
    获取标准输出并比对 python 按照输出模拟

      本单元的内容是模拟电梯运行,在获取数据方面本单元只需要随机生产初始楼层和请求楼层即可,十分简单,无需赘述。在运行代码获取输出的方面,我采用了python的subprocess库来进行,总体上和java的Process类并无区别,但使用起来更为简便。最后的评测环节,我采用的方法是,让python按照程序的输出进行模拟,看是否有运行错误的地方(人没送到目的地、没开门人就有进出等)。因为本次评测都是采用python编写的,所以代码相较于上次整体感更好,修改和测试也更为方便。

      第三单元

    获取输入数据 python
    运行代码获取输出 shell
    获取输出并比对 shell运行别人的代码并用diff比对

      本单元的内容是根据JML来写函数。获取数据方面较为简单只需要生产相应的指令即可(和上学期的计组自动化测试有些类似)。运行代码获取输出方面,我在这次使用了shell,实际上shell是最直接的运行程序获取输出的方式,重定向也极为方便,但因为语言我并不是很熟悉,所以拖到了第三单元才使用。在评测正确性方面,本次作业的代码逻辑有一定复杂性,使用python模拟并不能保证模拟程序的正确性,所以我采用的是与别人的代码对拍的方式,即运行我们的代码并使用diff工具进行比对。

      总体上来说自动评测虽好但也不能完全保证我们程序的正确性,提高代码质量,多看讨论区,集思广益对于我们程序的正确性也是十分关键的因素。

    四、课程收获

      一学期oo的学习中,我学习到了很多东西,有知识上的也有人生感悟上的,我将分别进行阐述:

      知识方面

      经过一学期的学习,我掌握了java语言的使用,了解并实践了面向对象编程的思想,学习了多线程编程,了解了JML规格,契约式设计,学习了UML建模方式,掌握了IDEA,Jprofiler,JUint,StarUML等IDE和工具,熟练了对于python的使用,进一步学习了shell,理解了分层的设计思想,学习了多种设计模式……oo带给我的收获是十分丰富的,尽管每一周都有的作业和中强互测让人崩溃,但熬过这一切,回头一看会觉得自己经历过的都值得,只有经历了痛苦才能学到真正的知识。

      感悟方面

      其实相较于知识方面,我觉得人生方面的感悟更为重要。在一学期的学习中,面对一次又一次的作业,我没能做到每次都达到自己的期望,在第二单元的第二次作业和第三单元的第一次作业中我没有进入互测,强测爆炸,细究其原因都是些“微不足道”的小地方几行就可以改过来,但是“千里之堤,溃于蚁穴”,尽管我改完这个小问题之后测试可以拿到满分,但是就因为这一点问题就让我从满分跌到了零分,这样的感觉真的让我十分崩溃,但是在崩溃之后,需要的是反思,我从这两次经验中的到的教训是“细节决定成败”,“差之毫厘,谬以千里”,以及这世界从来也不是公平的,你就算付出了自己最大的努力也往往不会有好的结果,但是就算这样我们还是要勇敢地面对这操蛋的生活,只有这样我们才能去抬起头追寻自己的梦想,而不是低下头去执着于过去的得失。来学计算机,并不应该是完全为了分数的,分数高自然好,但学到真东西学到技术才应该是最重要的事情。除了这两次刻骨铭心的教训之外,就在OO最后一次作业中,我自以为做好了测试,也知道应该用前两次测试的强测数据做一下回归测试,但是却没有当回事,在临结束提交还有15分钟的时候我找到了bug,但是已经来不及改了,这感觉真的追悔莫及,这让我想起了大刘在《三体》中的一句话:”无知和弱小从来都不是生存的障碍,傲慢才是。”程序一途理应求知若渴,虚心若愚。

    五、对于课程改进的建议

      1. 希望取消JML单元或者将其移至第一单元的位置,其余单元顺延。JML的体验并不是很好,也没有深刻体现面向对象的思想,整体而言更加贴近面向过程编程,将JML移至第一单元也可以让同学们尽早接触JUnit,以便于接下来进行单元测试。

      2. 希望助教出数据的时候将强测中的一两个点放在中测中防止因中测强测的评测环境差异过大,导致爆零(亲身体验,痛不欲生)

      3. 希望助教不要嫌麻烦,一定要把样例的期望输出给出以便于同学理解题意,有时光靠语言描述并不能保证含义确切。(指最后一次的指导书,不过扪心而论,助教的指导书还是相当好的)

    六、线上学习的感想

      其实我感觉对于oo这门课来说线上优于线下。在理论课方面,因为采取的是录播的形式,所以有忘记的部分可以随时复习,这一点是线下理论课所做不到的。而研讨课方面,使用腾讯会议相较于线下的投影更加有利于同学们的展示和交流,一方面画面和语音更加清晰,另一方面也避免了一部分上台说话的尴尬。实验课和作业部分的话,我认为和以往也没什么不同,反正都要用电脑的嘛hhh。所以综上所述,我觉得对于OO来说线上学习确实是一种比较合适的方式,体验还是很好的。

      好啦,面向对象这门课的路途到此就告一段落了(我两次暴死估计也当不成助教了hhhh),但是我们的coding之路和人生才刚刚起步,我想我在OO课上学到的一切都将会在未来的实践中成为我的一部分和我一起走向更远的未来,真心地感谢老师们和助教们的付出,我们有缘再见(抱拳hhhh)

      

  • 相关阅读:
    c学习第3天
    [BZOJ2124] 等差子序列
    CF710F String Set Queries
    Cow Hopscotch (dp+树状数组优化)
    CF528D Fuzzy Search (bitset)
    Gym 101667L Vacation Plans (dp)
    Codeforces 432D Prefixes and Suffixes (kmp+dp)
    [题解]BZOJ2115 XOR
    洛谷 P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm
    从中国矢量图筛选出江苏省行政区划图
  • 原文地址:https://www.cnblogs.com/BladeMonster/p/13123552.html
Copyright © 2011-2022 走看看