面向对象程序设计第四单元总结

面向对象程序设计第四单元总结

  本次博客总结主要就第四单元的程序设计情况以及在四个单元的学习中,自己在设计、调试等方面的思考感悟来书写。

第四单元作业设计架构

第十三次作业

  本次作业需求较为简单,主要是针对类图进行查询,如类的数量统计以及类内部方法属性的相关信息等。而根据官方包的相关代码和指导书中给出的提示来看,课程组的代码已经实现了从mdj文件中提取类图元素的工作,我们需要对提取出的元素做解析,之后根据要求给出相关的信息即可。观察题目要求可知,对于方法和属性等的查询都是以类的名字来索引的,如果不进行缓存的话,在查找信息时,就必须进行多次对类图的遍历,严重影响效率,因此,我们可以建立自己的MyUmlClass和MyUmlInterface等类对类图进行一步“还原“的操作。在MyUmlInteraction类中建立类和接口的表,使查询更加方便。之后主要就是按照要求判断是否存在异常并完成题目要求。
  在解析过类图之后,存在的一些难点就在于具体方法的实现。比如获取一个类实现的全部接口要通过递归的方式进行,因为一个类实现的接口包括本身实现的接口也包括父类的接口,而其本身实现的接口也可能继承自其它接口,因此可以考虑分两次递归来进行查询,并可以考虑对一个类实现的接口以及接口继承的全部接口进行动态维护,进一步提升性能。

第十四次作业

  本次的作业是在上次作业的基础上加入了新的需求。新加入了对状态图和顺序图的解析。这次作业对数据的预处理与之前一致,给我们提供了解析好的UML元素数组,由我们编程实现数据的汇总与处理。这次作业的主要难点在于对状态图和顺序图的理解要正确。不同类型的元素其parent、reference等因子代表的含义往往不同,我们可以通过自己绘制简单的UML图来进行观察,先明确不同的UmlElement各个组成部分的意义,再进行编程,思路就能清晰不少。从整体上来看,本次要求设计的MyUmlGeneralInteraction可以将上次的Interaction进行对外接口的改造,整体作为MyUmlGeneralInteraction的一个子模块,无需进行过多的代码改动,然后新建两个类分别解析状态图和顺序图,其逻辑与对类图的处理几乎一致,只是具体涉及到的UmlElement不同。

第十五次作业

  本次作业是针对mdj文件的有效性做检查,没有新的解析需求增加。在设计时,首先考虑的一个问题是有效性检查放置在哪个部分。根据题目的叙述,在完成类的初始化后,AppRunner会自动调用8个检查用方法,因此我们只需要考虑实现接口中对应的方法,无需手动对check方法进行调用。接下来代码架构上就不需要做太多考虑了,主要目标集中于设计方法完成题目需求。本次作业中涉及到的需求中,需要递归实现的很多,因此要做一些剪枝等操作,控制时间复杂度和空间复杂度,避免出现CTLE和stack overflow等错误。

Bug分析

  本单元的强测中,每次都出现了一个点的错误,都属于非常低级的错误,但是也暴露出了我写代码中的一些思维漏洞和不好的习惯,同时在自己完成代码并进行初步测试期间,也发现了若干bug。
  在第一次作业中,我出现了CTLE的错误,败在了课程组精心设计的“菱形图”手下。我在查找实现的全部接口时,没有进行剪枝,导致深搜时出现了大量的重复,搜索量几乎呈现出指数型增长的趋势,严重超时。第二次作业则出现了很低级的错误,在if语句块内部实现的功能不完整,这就暴露出了我测试不够充分的问题,自己测试的强度太低,覆盖面太窄,导致了本次bug出现。第三次作业中,我又在“菱形图”的处理上出现了问题。虽然汲取了第一次作业的经验教训,进行了剪枝处理,但是由于写代码时,思考的不够多,因此剪枝操作的效果实际上非常差。在最初的设计中,每次深搜,对已经搜索过的节点进行标记,避免循环重复。然而我取消标记的条件太弱,导致几乎每次深搜都要重新标记一遍,因此在实质上做出的优化很小,导致了最后的超时,对剪枝操作进行稍微改进后就可以避免CPU超时。

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

第一单元

  在学习第一单元时刚刚开始接触到面向对象的思维模式,在本单元的作业里,我在main方法中实现了大量的方法来对表达式进行预处理和WF的判断等,导致了代码的冗杂且其他同学阅读起来往往感觉没有清晰的思路,可读性很差。同时,不同模块间的耦合度很高,发现bug进行修改时,往往要牵扯到很多地方。并且在设计代码架构时,往往没有考虑到迭代开发的问题,导致几乎第二次第三次作业都进行了全盘的重构。在迭代的过程中,通过总结规律,我发现需要处理的表达式可以拆分成单个的元素,因此采取了工厂模式对表达式进行拆分与解析,在一定程度上优化了程序架构。

第二单元

  本单元设计的主要目的是通过面向对象的思想完成调度工作以及实现线程之间的同步。在开始设计之前,首先要对设计目标做抽象化的处理,通过考虑不同目标之间的交互关系确定选择哪种元素作为对象能更好地帮助我们实现设计。汲取了上个单元作业的经验教训,我在选择程序的结构时比较小心,在本单元的任务中,应该总体上都是对于电梯的调度,因此调度器应该单独抽象成一个对象,而管理的电梯也应该抽象为一个对象,有利于实现对多部电梯分开处理,以及调整电梯的功能等。基于这样的考虑,我进行了设计,在后续迭代中发挥的效果还不错。另外在本单元调试的时候,我也意识到了线程同步和交互有很多细节需要注意,例如实现了换乘的逻辑后,何时输出换乘信息也是值得注意的事情,如果在乘客出电梯后输出out信息前切换到其他线程,就可能导致先输出in信息再输出out信息,导致逻辑错误。同时不同电梯之间的协调也需要考虑清楚,例如在第三次的作业里面,由于涉及换乘,因此不能提前关闭一些已经完成自身任务的电梯,以备其他电梯调用。在本单元的作业中,我没有刻意使用某一种设计方法,而是先理出了整体的代码框架,然后发现很自然地顺应了“生产者-消费者”模式的基本思路。经过分析,我觉得这一设计模式思路清晰简洁,可以针对不同任务做出适应性的改进,同时能很好地分离关联性较弱的数据,因此十分适合于处理多线程问题。

第三单元

  这一单元的作业要求根据JML实现一系列对模拟社交系统的查询和插入等方法,整体上为一个动态维护的过程。整个单元的逻辑架构不需要我们考虑,我们只需要利用课程组提供的官方包进行方法的自动调用和输出即可。重点主要在于JML的学习以及具体方法的实现。通过本单元的学习,我对于JML有了深一步的了解,“万事万物皆有规格”虽然可能很夸张,但这句话还是给我留下了深刻的印象,让我在每次开始编码前,都充分的考量题目需求在抽象后是否与我当前的思路一致。本单元的作业对于我们算法设计能力也提出了小小的要求,如果全部使用暴力计算的方法,很可能导致超时,因此动态维护、选择合适的容器和计算方法等都纳入了我们思考的范围。但是最开始对于JML的理解过于刻板,我每次作业都把所有方法放在一个类里实现,导致了结构混乱,文件过长,甚至还出现过超过500行的文件,这一问题,如果不及时改进,在第四单元中将暴露的更加充分。

第四单元

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

课程收获

  经过一个学期的理论课学习、每周写作业以及在研讨课上听大佬讲授经验,我对于OO的学习,逐渐从迷惑变得清晰。在思想层面上,从最开始的以为OO就是把程序写成模块化的样子,到后来能比较准确的从一个问题中抽离出我们需要重点关注的对象有哪些,并进行封装和处理。在代码能力上,从最开始的一个bug就de一天,到现在能用各种调试方法比较好地定位问题。同时,在每周作业的压迫下,我也提高了写代码的效率,对于一些具体细节的实现更加熟练,于是在后期可以较快地完成作业。在每个单元的学习中,都穿插着一些对于设计模式的学习,Java常用的设计模式可能只有几种,但背后的学问还是很深的,我们充分学习理解设计模式,有利于今后更加灵活高效地实现代码。同时多线程、类图等在我们今后对其他科目的学习和工作后可能遇到的各种问题中都发挥着很重要的作用,可以说,正是这些理论知识点把我引进OO的大门里,也让我对OO有了更多的思考。

对课程的建议

经过一个学期的学习,我认为总体上难度设置比较合理,但是第一单元前两次作业的难度和第三次作业的难度差距比较大,我在写第三次作业时遇到了比较多的困难,虽然感觉第三次作业整体难度是合理的,但是希望能够把三次作业的难度分配更加均匀一些。

在第三个单元和第四个单元的学习中,主要针对具体的JML和UML等知识点进行了考察,但是希望助教学长们考虑一下在这两个单元继续加入一些对设计模式等的学习。或者再加入一些多线程的简单要求。

希望理论课能讲解更多实例,比如也像代码作业一样,分几次课的时间,讲解一个规模较大的工程如何实现,而理论知识更多地可以让同学们自学。

关于线上学习的体会

  可能与本课程的特点有关,我认为OO这门课在线上学习的效果和带给我的体验都很好。在遇到困难时,无论是请教老师、助教还是在讨论区发帖和同学们一起讨论,都能很快地得到回复,并且能获得很多新的思路,而且同学们除了在研讨课上的经验交流外,也经常在讨论区发表新的学习心得,很能带给我启发。而在线学习理论课的过程中,有小测和课后的讨论,能帮助我们比较及时地发现知识盲区。有一点感觉体验不太好的地方的话,就是每次实验课的提交通道会比较拥挤,然而这个问题也是我们很难解决的,最好的方法就是提前提交来进行合理规避,尽量做好预习,避免出现压线提交的情况。总体来说,我认为OO课程的学习效果是得到了很好的保障的。
  在此感谢课程组每一位老师和助教学长的辛勤付出。

你可能感兴趣的:(面向对象程序设计第四单元总结)