OO第四单元总结

OO第四单元总结

第四单元架构设计

Homework_13
  • 实现一个UML类图分析器,要求解析类图的构成要素并且理解其中元素之间的关联。

  • 类大致如下:

  • 其中,MyUmlInteraction类用来分类解析输入的元素,并且进行指令的查询;MyClass类基于UmlClass类建成,另外包含了属性、方法、关联、父类、子类、实现接口等属性,以类为单位进行存储,方便查询;MyInterface类基于UmlInterface类建成,另外包含了父、子接口以及关联、方法等属性;MyOperation类存储了参数、返回类型等属性,封装以便后续操作。

  • 流程如下

    • 由于输入的顺序影响着存储元素的难易程度,所以首先对输入进行了调整,此处应用了几个循环对元素分别处理,如先解析类、接口元素,再解析继承关系,再解析方法、属性等,以此类推。

    • 解析并且存储类图。利用一个大的HashMap存储每一个元素的id-元素自身关系,方便通过id直接索引到对应元素;判断输入元素是否为某种特定元素并进行特定的解析,属性、方法根据对应的parentid存储到相应的类或者方法之下,由继承关系得到类或接口的父和子,通过对UML类图元素及其之间关系进行分类存储。

    • 利用已经构建好的类图进行查询,此处MyUmlInteraction类中包含了所有UmlClass和UmlInterface,通过这两者即可索引到所有需要查询的元素。

Homework_14
  • 在第一次作业的基础上,扩展类图解析器,加入UML状态图和UML顺序图的解析和查询。

  • 类大致如下:

    • 完全在第一次作业的基础上实现,加入了与状态图和顺序图相关的类,实现思路与第一次基本相同,重点是理解状态图和顺序图之间的元素层次关系。
Homework_15
  • 在前两次作业的基础上,完成对模型的有效性检验。

  • 类与上一次作业基本相同,加入了一个新的Check类,用于放置相应方法,检查相应规则。总UML类图如下:

    • Check类中实际上包含了Rule1-4的检查方法,需要利用BFS等方法进行图的检查,而由于Rule5-8较为简单,在解析输入的时候即可判断,所以可以增加额外的属性存储,检查时可直接判断是否符合规则。

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

  • pre

    ​ pre大概是我第一次接触java语言,也是第一次接触面向对象的思想。在学习面向对象语言之初,只知道面向对象的三大核心“封装,继承,多态”,但是不太懂其中的意义,不太明白为什么一个Main函数可以解决的事情,却要建如此多类的意义,不太明白继承的用法及原则,不知道多态到底是什么,从一个懵懵懂懂的小白,就这样走上了OO的不归路。

    ​ 感慨于IDEA相比较于Dev-C++的美观便捷后,同时也体会到了java语言相对于C语言的优势。从书籍管理系统到正则表达式,一路跌跌撞撞,在尝试中摸索,也初步了解到了面向对象相比于面向过程的优势。可以说,面向对象是一种面向现实世界但又不直接表达现实世界的一种语言,记得马克思主义理论中抽象与具体的关系,OO就很生动地诠释了这一点,首先从现实生活中获得需求,也就是在具体事物中发现问题,然后将事物分类高度抽象化,一类事物成为一个类,事物的特点、需要记录的因素作为属性,需要的操作作为方法都归于这个类下,事物与事物之间也有关系,这就成为继承、关联等类与类之间的关系,事物可以有行为,行为作为接口需要类实现,这就构成了事物与行为的抽象化系统,而实际运行时,需要将其实例化,也就是创造出真正的对应于现实世界的事物,又将抽象转化为具体,构成了具体-抽象-具体的链结构,成为了提取重点、解决问题的利器。

  • 第一单元

    ​ 第一单元表达式求导,可以说,第一次作业基本上还在应用面向过程的开发方法,直到第二次作业,由于作业难度陡然上升,才逐渐向面向对象转变。将表达式一步步拆解成项、因子,再把因子分类处理,构建出表达式树,最后依据树进行求导的过程中,一步步慢慢地理解了抽象的意义,把相似的一类事物的核心提取出来便可以创建一个类,若有共同的操作也可以提取出来创造一个“解析类”“检查类”来使代码更加直观、更加简洁。虽然当时知道接口是OO中很重要的一个工具,包含着重要的思想,但是奈何不太熟练,所以并没有使用,现在想来,使用接口会使得程序的整体性、可读性更好。

    ​ 第一单元最重要的大概就是架构了,从看懂需求,思考架构设计到真正落笔写代码的这段准备时间永远不会太长。

  • 第二单元

    ​ 第二单元是多线程电梯作业,个人认为是四个单元中最难熬的一次作业。从输入线程到调度器线程再到电梯线程,架构似乎很明确,各个类都有明确的对应的实现主体,各个类的任务明晰可见,但是从电梯的调度算法到多线程并行的线程安全问题,个个都不是省油的灯,都需要耗费巨大的精力解决。在探索中,也逐渐理解了线程运行,明白了如何避免死锁,如何保证线程安全,虽然未来可能不太能接触到,但却也是新奇而有用的知识。在本单元中,同时也学会了一点点java的设计模式,如观察者模式、状态模式,学会了利用现有的模式对问题抽象化、简单化。

  • 第三单元

    ​ 第三单元是根据JML规格实现代码,是较为中规中矩的一次作业。架构基本已给出,无需自己过多地实现,只需要阅读每个方法的JML规格,思考使用什么样的容器以及什么样的算法实现即可。性能要求较为严格,使用了Dijkstra算法的堆优化、读取时存储减少遍历等方法防止被卡爆。本单元学会了阅读JML规格以及实现JML规格。

  • 第四单元

    ​ 第四单元是对UML图进行解析和检验。通过源代码,可以得知需要处理的元素,而架构可以根据UML图中各个元素需要制定,不过如何存储、如何处理各个元素之间关系都需要思考。通过构建新的MyClass类、MyInterface类等可以将其中的操作、属性归于统一,方便对各个不同层次下的元素操作。本单元加深了对UML类图、状态图和顺序图的理解,了解了它们的构成以及含义。

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

  • 第一单元由于时间比较充裕,学习了使用C语言随机生成样例,以及利用python完成评测机自动输入与标准答案对拍,虽然随机生成的样例强度不高且针对性较弱,但也有一定的收获。只是可惜的是,以后的作业由于时间、能力等原因,都未完成自动化测试,但也学会了一点点测试的思想以及理论方法。

  • 第三、四单元接触到了单元测试,了解到在系统化程度不是那么高的程序中可以对每个方法进行测试,针对不同方法构造边缘样例,编写测试程序,可以完成覆盖性测试并且精准定位错误方法。由于无法通过已有程序得到标准答案,所以可以采取对拍的方式验证正确性。

  • 静态检查也是一种测试的方法,需要检查细节、检查代码逻辑,但是需要全面了解清楚题意并且理清程序逻辑。

  • 了解了全面思考可能出现的各种情况、构造特殊样例的必要性,例如可能出现的死循环导致TLE、边界数据未处理好等情况,尽可能实现程序的“健壮性”。

  • 由于实践较少,所以理解可能不是很深刻。希望未来有机会可以对测试有更深入的探索。

课程收获

  • 学会了面向对象的编程思想,如上文所说,从一个懵懵懂懂的小白,逐渐成长为一个可以独立编写一个较大、较完整程序的计算机学院的学生(虽然还是很菜)。在实践中,理解了抽象对于面向对象的意义,抽象可以给问题带来简化,给程序带来简洁,或许哲学中的思想也可以在此体现;理解了课上一遍一遍强调的层次化的重要性,自顶向下的编程使得逻辑性更加明确,结构更加清晰;理解了封装、继承、多态的含义,封装可以将代码成为”黑匣子“,只提供简洁的输入输出接口,而在内部完成逻辑,减少耦合性,继承使得代码复用性提高,有父与子关系的类可以共享属性和方法,而不必每次都实现一遍,多态使得程序可以将自身所支持的操作套用到其它类型的值,提高了”模糊性“,不必对类型有如此清晰的界限,在一定程度上简化了逻辑。

  • 说实话,除了知识与解决问题的能力,大概最大的收获就是抗压能力嗖嗖嗖地增加了吧。其实我之前不是一个ddl选手,一般会在ddl前很多完成需要的工作,但是OO让我打破了以往的规律(于是现在也变成了一个ddl选手)。周五上午或者晚上开始思索架构设计,周六正式动工,每次都是死亡周末(哭)。遥记第一单元第二次作业,周五理解完递归下降后,浑浑噩噩地写了一部分递归的代码却完全心里没底,周六上午写完后半部分用颤抖的手点击调试,一步步跟踪后发现问题不大,长舒了口气,周六晚上继续完成后半部分求导的工作,逐渐逼近的ddl让我的内心已经开始产生恐惧,到最后看到一片绿色终是放下了心。想着应该最恐怖的时候已经过去了,又迎来了第二单元第一次作业,周五晚上加周六一整天的时间也没搞明白多线程到底应该怎么设计,脑子里都是乱糟糟的线程安全、锁、调度……最终迫于巨大的压力只得通宵,万幸后来发现先减少一个线程会省事很多,在第二天早上八点的太阳升起的时候成为了有效作业。OO的经历让我明白了人在压力的鞭策下的潜力是无穷的,或许可以发掘一下(但还是身体最重要)。

  • 除此之外,我还学会了如何在一个复杂程序中一步步定位自己的bug,如何用尽量小的改动修复自己的bug;学会了如何对原有的架构进行修改、补充,以实现更加强大的功能……

一点点建议

  • 关于pre

    pre2是帮助我们初步理解面向对象的思想,可以理解,pre3则是正则表达式,不知道是否是为第一单元作业做一个铺垫,这样的话,是否可以也为第二单元设计一些预习题目,从稍微简单的多线程开始。因为个人总觉得第二单元有点“前不着村后不着店”,和其它三个单元关系都不大,难度又对于初学者来说不小(而且多线程可能对于绝大多数都是初学者),刚开始第二单元的时候理论知识还没讲太多,就要开始自己动手完成一个较大的作业,难度增长过大,所以不知道是否可以考虑在pre中增设相关内容,可以加一些多线程相关的阅读材料以及与多线程有关的较为简单(比如不涉及调度)的多线程程序,这样有了一个铺垫会好一些。

  • 关于作业

    感觉有些作业难度跨度较大,希望可以稍微平均一下(或者和OS的时间协调一下)。第一单元第一次作业难度可以稍稍提升?不然第二次感觉确实有点困难,又要学习如何解析表达式,其中涉及到递归下降、表达式解析等本身就不简单的OO之外的内容,又要处理后面和OO关系更紧密的求导环节。第二、三单元作业难度上升曲线较为平滑(就是第二单元第一次起点比较高。第四次作业可以把第一次作业和第二次作业难度平均以下,毕竟第一次又要处理图的解析(我甚至一开始根本不知道如何下手)又要完成相应的方法,方法中还涉及到BFS、递归等不那么直接和容易的算法,而第二次作业有了第一次作业的基础,方法也较为容易,难度和上一次相差有点大。

  • 关于实验

    每次考完实验都有点迷茫,可能因为没有反馈结果也没有答案吧。如果说OO实验的目的不是考试的话,那么我觉得想要发挥它更大的意义的话,是可以公布反馈或者给答案的,这样大家可以有针对性的发现自己的问题并且解决问题,了解到这部分的学习情况,而不是只是做了个题目然后就结束了(苦涩)。

posted @ 2021-06-26 17:05  Miffy0  阅读(88)  评论(0编辑  收藏  举报