OO总结

Posted dglr123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OO总结相关的知识,希望对你有一定的参考价值。

OO总结

第四单元分析

问题分析:

本单元要求完成一个简易版的UML解析器,其中包括对UML类图、UML状态图、UML时序图的解析,这三者中难点在于类图的解析,需要全面地存储类和接口的相关信息,编写程序时会更进一步发现涉及到类实现多接口和接口的多继承是本单元的难点中的难点,关键在于不遗漏还有快速地查找到需要的信息。

编写思路:

编写思路分为两部分,主要程序架构和部分方法实现

本单元实质是对图的存储与查找,但图中的结点有“主次”之分,拿UML类图举例,最重要的UMLElement无疑是UMLClass,以其为中心,有UMLAttribute、UMLOperation等,还有UMLClass之间的关联和继承关系,UMLClass和UMLInterface之间的实现关系,UMLInterface之间的继承关系。基于这样的逻辑关系,本次单元我的设计思路如下:除Main类外所有类继承自UElement类,UElement类中有通用的属性并配置set和get方法,如下:
技术图片

设置通用类之后剩下的就要为有特殊行为的UMLElement设置专门的类,类图中有UClass、UInterface和UOperation,状态图中有UStateMachine、UState和UTransition,时序图中有UInteraction、ULifeline和UMessage。状态图和时序图无须特别说明,类图中发现类和接口有很多重合的地方,如都有属性和方法,都可以继承,可以互相关联,因此把这些共同点提取出来组成一个类UPoint,让UPoint继承UElement,UClass和UInterface继承UPoint。剩下的就是每个类中存储与自己有关的类,如UClass需要存储继承的UClass、有关联关系的UClass和UInterface、有实现关系的UInterface、UOperation、以及没有专门设置,由UElement代替的Attribute、AssociationEnd等。完整的UML图如下:

技术图片

MyUMLInteraction的构造方法中传入了一个UMLElement的数组,在构造方法中将两次遍历这个数组:第一次遍历,将所有的UMLElement转换为我自己的类,也就是UElement,并以id为key存储在一个HashMap中,id为key的目的是第二次遍历中查找方便,第二次遍历需要把每个类放到对应的“位置”上,比如遇到UMLAttribue,由其ParentId为索引找到一个UClass,把这个UMLAttribute(对应我自己的UElement)加入到UClass的为Attribute设置的容器中,第二次遍历还要将UClass、UStateMachine和UInteraction加入到以name为key的HashMap中,在方法中方便查找。两次遍历后还有一个dfs,以UClass和UInterface的topfather为起点,将父亲的方法和属性、关联的类和接口(以及实现的类)转递给所有继承意义上的后代。

第三次作业中重点在于前三个规则,R001难点在于理解其含义,真正理解后实现难度并不大,R002和R003都要dfs遍历且有些许不同。R002实质是找到图里所有在环中的结点,我采用tarjan算法,遍历中刚遇到某个结点时将该结点的low值设为dfn+1,遍历完该结点的子结点后若low<=dfn,说明这个结点在环中,就要放置到抛异常需要的那个set里。R003中由于类不会有多继承所以不用检查类,只需要遍历UInterface,遍历中把自身继承的类(接口)给子类(接口),然后看有没有重复的(之后发现这个方法很傻,只要看继承的数量就行)。

bug分析:

三次作业的bug都来自于类的实现多接口和接口的多继承上……

OO四单元总结

四单元架构设计及OO方法理解

面向对象程序设计无疑比面向过程程序设计更符合人们对于事物的认知,从而使程序员能够更好地抽出需要描述对象的主干逻辑,从而进行建模,进而一步步实现。四个单元的作业,使我对OOP的理解不断加深:

第一次求导作业,那个时候对继承、实现等概念还不太熟悉,但使用之后才发现:代码竟然还可以这么写!将三角函数因子、加法因子等的共同点抽离出来,之后只需要写不同的部分,如求导,就可以大幅度省去重复的代码,并且阅读起来体验更佳;第二次电梯,不得不说这个单元相当的经典,给人印象深刻,需要解决线程安全问题,这包括对synchronize机制的理解透彻,notify、wait等方法的熟练运用,还有高效、准确地调试,同时还涉及到调度算法,编写这一单元时就会触及到几个OO的设计原则,如是否需要设立一个“全知全能”的控制中心来调度其余的电梯线程,我一开始这样设想过,但是后续发现编写难度和维护难度超出了我的预期,遂中途放弃;第三单元JML建模,需要读懂每个JML规格描述然后从整体开始设计,最后逐一满足JML的要求;最后一单元又是一个综合性很强的作业,既要设计好整个的框架又要写出高效的查找算法,这四次作业无一不考研着编程人员对整个架构的把控,如果架构上出现失误,严重时可能将导致重构。总结下来,我对OO的理解便是:将需要描述的信息以“对象”的方式聚合起来,同时考虑到层次关系,将同一层次中相同的信息抽离出来放到更高层次,并通过继承来避免重复,优秀的层次关系能够更大程度上易于阅读,并在扩展时不修改原有代码。

测试与实践

经过一学期的学习,测试无疑是我最薄弱的环节,大部分是靠随机生成的样例进行测试,不能够突出重点,现有的很多测试工具,如JUnit,JML的OpenJml,听起来都很美好,但实际操作起来……

我现在发现很多测试问题都是形式化验证不充分,经常漏掉一些很难遇到的情况,测试了好多数据过了,然后中测过了,很开心,结果强测结果一出来瞬间傻眼了,后续学习的重点应该在于怎样有针对的进行测试。

课程收获

这门课的名称是面向对象程序设计,起初以为只是java,后续发现除了java之外能够学到很多意想不到的东西(奇怪的知识增加了.jpg)首当其冲的就是抗压能力,各个单元第一次作业都是最痛苦的,因为要充分理解这个单元的内容并设计出整个单元的架构,通常规划一堆东西,然后实现时总发现有各种各样的问题然后不断修改,并且要不断进行取舍,比如写法1可以让程序跑的更快,写法2更易于阅读,让程序更美,写法3又丑又慢,但是最好写,然后一看时间,当机立断选择写法3……(能跑就行.jpg)不断修改程序的同时与ddl进行斗争,有时会以失败告终,这时就要安慰自己,彻底放松一个晚上,第二天起来再慢慢改bug。

然后就是学会了使用很多小工具,比如python脚本,JUnit测试等等,还有学会了一些图论的算法,如tarjan。

改进建议

  1. 如前文所述,每个单元的第一次作业压力太大,既要理解整个单元的设计意图 ,规划好整个架构,还要作一些测试准备,而后续作业在不重构的前提下只需添加一部分内容,与第一次作业压力差距过大,但其实在题目层面上很难对这个问题改进,或许有可能把每个单元第一次作业的ddl延后?
  2. 每个单元的第一次实验安排在这个单元第一次课的第二天晚上,但是此时还来不及完成第一次作业,通常在学习的过程中光看理论只能有个大概的印象,只有做作业,在实践中才能加深对问题的理解,所以每个单元的第一次实验感觉都不太好,是否有可能将实验整体退后一周?
  3. 暂时没有更多的建议,那就希望课程组能够看到同学们的建议后能最大程度的改进,从而满足同学们的需求,带给同学们更好的OO体验。

线上学习小结

对我而言,线上学习的效果整体来说是不如在学校的学习效果,可以感觉到明显的差距,当然这也因人而异,对于我来说自制力偏弱,写东西时有意无意会拖延,并且在看理论课时容易走神,有些不明白的地方也就漏过去了,只有之后遇到问题时才会找答案,对自身的要求会不断降低,写代码前有很多预期,但写着写着就只管能不能出结果而忽视了架构(再一次 能跑就行.jpg)这个问题课程组对于课程组而言可能没有好的解决方法,只有期待能够早日返校了

结语

谢谢课程组一直以来的付出,正是有老师和助教们的不断努力我们才能有如此难忘的OO课,如果可以真想在学校上这门课。


以上是关于OO总结的主要内容,如果未能解决你的问题,请参考以下文章

迎来OO的曙光,总结规格的意义——OO第四次博客总结

OO 第二单元总结

OO第四单元总结~~

OO第二单元总结

OO_Unit4总结&课程总结

OO 第三单元总结