OO第四单元总结与课程总结
本单元三次作业的架构设计
第一次作业
第一次作业是只有类图,类图包含很多的UmlElement,于是我综合考虑了设计的可扩展性,采用了按照Uml模型的各种模型元素作为类来架构设计。我创建了一个顶层类MyUmlElement
,然后创建了MyUmlClass
MyUmlInterface
MyUmlOperation
来继承这个MyUmlElement
,我为什么只选了这三个类呢,因为只有这三个类在开源代码的基础上还需要存储更多的信息,例如MyUmlClass
里面需要存MyUmlOperation
UmlAttribute
等信息,这里就不再赘述,具体看我的Uml类图
实现思路
-
先在
UmlInteraction
类里面解析UML图,这里解析的过程为遍历Elements
数组,注意一定要先存好类和接口,只有这样之后存相应的Operation
和Attribute
才好存。 -
为了使得检索更加高效,减少遍历带来的无谓的时间消耗,我在所有需要索引的地方都采用了Map的存储容器形式
-
存储好已经查询到的一些数据,例如类实现的全部接口,类的顶层父类,类的所有属性的数量等等,因为这些都是不会变的,所以进行缓存以便将来重复查询是可以避免不必要的工作
-
算法方面我在能采用BFS的地方就用的BFS,第一BFS容错率更高,可以避免像DFS有爆栈的风险。
我踩过的坑
这次作业我遇到了一个bug,我de了两天,让我刻骨铭心。指导书中的测试样例我都尝试过了都没有问题,可就是在中测上有一个点一直卡着。然而却不告诉我反馈的结果,或者是WA还是RE都没有,只反馈了一个未通过测试点,我很是懊恼。终于,在我尝试了无数的测试样例后,我发现了是RE。也就是我出现了NullPointerException
,出现这个错误的原因在于我有一个方法传入了一个null作为参数,然后这个方法处理这个null参数的时候就出现了这个异常,出现这个错误的原因在于我天真的以为所有的方法都有参数
类图的总结
这里我总结了理解第一次作业的秘诀,下图展示了各个element
之间的关系,箭头指向的元素的parentId是发出箭头元素的id。然后一些细节的点我也在图中做了标注,我认为,如果提前就对此图充分了解,那么第一次作业将会很轻松很快速地完成
第二次作业
第二次作业相比第一次作业加入了时序图和状态图,同样为了模型的可扩展性,使其显得不那么复杂,我实现了源码中给的三个接口,创建了三个解析三种图的Interaction
交互类,这样可以做到分而治之,而解析类图的交互类可以直接使用第一单元的MyUmlInteraction
,以下是我的UML图,由于具体的方法和属性如果展开会过于复杂和冗长,因此这里主要展示类之间的关系
实现思路
由于这次作业增加了时序图和状态图的查询,因此需要增加对应的类,我增加了UmlInteraction类和UmlState类,UmlRegion类三种类,增加这些类的好处是在于大大减少了单个类的复杂度,实现模块化的设计,同时也非常地容易理解。
这里我有一个自认为设计的非常巧妙的地方是:我把getImplementInterfaceList()
这个方法分成了很多个小的方法,在求一个类实现的所有接口时,先求这个类自身所直接实现的接口,然后在接口类里面设置一个求这个接口继承的所有接口的方法,这样我们就获得了一个类(不含父类)所实现的所有接口,然后我们再对其所有父类做相同的操作。我发现这样做的好处在于把一个大功能细分成小操作,更容易实现,同时,这个设计也为我下一次作业带来巨大的方便(在第三次作业的地方详细说明),这也充分体现了层次化的设计
时序图和状态图的总结
箭头的含义同上,若箭头上标有单词,则意味着是箭头指向的元素是箭头发出元素的一个属性下
状态图
时序图
第三次作业
第三次作业是按照8条给定的UMl规则来判断图是否符合这些规则。我根据官方给出的接口有重新实现了一个standardPreCheck
类,这里我的设计优势就体现出来了,新加要实现的功能,只需要构造相应的接口并实现这个接口,并不需要更改原来已经写好的代码,这样可以减少bug的产生。
这里就体现了我上面所说的设计的好处,因为2,3,4条规则分别是循环继承,重复继承,重复实现,这些都要对图进行遍历,而依据我前面的设计方法,这样遍历一次后,我就获得了接口的继承的所有接口,类实现的所有接口等数据,将这些数据作为类的属性存起来,这样就使得我只用做一次遍历,便可以实现既对规则做了检查,又能直接应用于对后续的查询,这也使得我的强测的CPU时间很短,只有1s,这充分体现了层次化设计的重要性。
四个单元中架构设计及OO方法理解的演进
第一单元:表达式求导
第一单元的主要任务是表达式求导,由于刚开始学习OO,我的面向过程式的写程序方法还很严重,因此,这三次作业我几乎回回都要重构,而且每次都是那种需要大改,原因在于我一开始没有进行合理的架构设计。这个单元,我明白了合理设计架构的重要性,各种运算之间该如何设计,是设计成接口的实现关系还是设计成类之间的继承关系等等,并且我对OO有了基础的理解:抽象,封装,继承,多态
第二单元:多线程电梯调度
第二单元进入了多线程部分。之前从来没有接触过多线程的我进来就是懵的,于是我查阅了很多资料,才算是对其有了些了解。这个单元需要解决好同步与互斥的问题。我在架构设计上有一个比较大的遗憾就是,我的调度器只有一个主调度器,由于我的算法的特殊性以及我一味追求性能,导致我陷入了死胡同,越钻越深,三次作业都是这样迭代下来的,于是这个电梯看起来比较奇怪。现在回想起来,肯定应该为每一个电梯都设计一个调度器才是最优的设计。这个单元我明白了层次化设计的重要性,以及java在多线程编程的一些应用内容。
第三单元:JML
这一单元我学习了JML规格,可以说我受益匪浅。我发现了规格化地设计是解决大型工程的重要法宝,同时,规格也是编程人员和用户之间的纽带。同时我也学习了Junit,junitNG相关测试,对代码的测试有了更加深刻的理解和认识。这一单元,我对OO中的测试与规格化设计有了更加深刻的理解。
第四单元:解析UML图
这一单元的解析UML图的任务,我的理解是为了加深我们对UML本身的理解。事实上,我也确实对UML有了更深的理解。其实UML就是一个模型,里面有各种各样的UmlElement,这些UmlElement在可以认为是一个个类,这些类之间有着各种各样的关系。所以从这个角度看,UML本身其实也不是很神秘了。可以说UML图是一种将我们的实际编程代码浓缩起来的图,各种各样的UML图其实代表着各种各样的角度和方式来复现我们的程序架构设计。这一单元集前三单元之大成,让我理解了OO的精髓:层次化地设计。
四个单元中测试理解与实践的演进
第一单元中我的测试方式主要是人工式的代入实际的表达式求导,看对不对,这样的测试可能会比较有针对性,但是缺乏覆盖性。
第二单元的测试中,我认为自动评测机的测试是最好的,因为第二单元是多线程,而多线程具有不稳定的特性,因此光一次成功运行什么问题都说明不了,因为就算是同样的输入也有可能会出现结果不一样的情况。在实践中,由于我自身代码能力不是很强,于是我没有设计出来评测机,所以导致我的测试力度一般,也导致了我有很多的bug
第三单元中,我接触到了Junit测试,我发现Junit测试是大大提升测试效率的好工具,采用Junit测试后我的bug也大大地减少。这单元的测试方法我认为最完美的是对拍,因为在图过于复杂时,并不能保证自己认为的输出一定是正确的输出,所以,找一个大佬同学对拍也是这单元很好的测试方法。
第四单元中我发现了测试如何才能既有针对性又有覆盖性的方法,其实可以认为所有的输入都是按照类型的,例如这单元有8种类型的错误,把每种针对每种类型的测试数据都进行测试,将数据分类,可以保证,是一种好的测试方法。我也采用了这种测试方法,在原有的指导书中给出的测试用例的基础上,我又在上面进行更加复杂的设计,如果也能通过,就基本证明了我的代码没有bug。当然,对拍也是这单元一个很好的测试方法。
课程收获
- 掌握了面向对象式的程序设计方法
- 掌握了java语言中相关语法,包括java中的多线程设计部分
- 掌握了JML规格语法和Junit相关测试
- 掌握了UML语法以及UML中的各种图:类图,时序图,状态图等等
- 掌握了什么才叫层次化地设计
- 提高了编程能力,掌握了很多的大师级别的算法
具体改进建议
- 每次的作业一发下来,看完指导书就会有想当多的疑惑,指导书中偶尔也会有错误,或者没有说清楚的地方。每每遇到这些困惑,我都会去翻讨论区,一条条地翻,抑或是翻一翻往届学生的博客,生怕错过一个重要信息,总之,就是为什么不能把指导书做得详细一点,把问题说明白,把讨论区中的内容放一部分进指导书,或者把往届精华帖总结一下做成文件单独发下来,或者是把每个单元的同学们在讨论区中问的问题总结总结,因为作业每届学生都差不多,所以每届学生都有差不多的疑问,无论通过什么样的方式,如果可以减少大家的工作量,既减少助教的工作量,也减少我们学生的工作量,何乐而不为?为什么每年都要在讨论区中才能存活下来,所以我越来越不明白这到底是是面向理解指导书的编程还是面向对象的编程了
- 每次的实验做完了就完了,之后就杳无音讯。建议可以把标准答案发下来,我们心里也好知道自己错在哪里了,这样的实验起到的效果也会更好
- 每次都是周二晚上发作业,周六晚上截止,总共也只有4天时间,个人觉得时间稍微有点短,在这么短的时间内实现一个工程量浩大的任务,我反正是感觉有点无暇顾及架构上的设计了,有点得不偿失。建议可以周一晚上发布作业。
- 个人觉得可以多发点资料下来,像是第二单元的多线程编程,我认为可以在第一单元结束的时候发一些多线程编程资料下来,抑或是告知我们提前做好预习工作,这样听课的时候就不会一头雾水了
- 感觉每次的课程的ppt或者视频内容量有点大,说真的,我认为把一件事情讲清楚远比讲很多件事情要管用得多
线上学习oo课程的体会
经过了这一学期OO课程的学习,我发现OO课程的体系真的很完善。老师,助教的团队工作都很认真负责,平台也做得很不错,相比于离散数学,数据结构等课程,我可以说真心学到了很多实打实的东西。希望OO课程体系能够越来越好,成为计算机系一门扬名四海的课程!最后,感谢辛勤付出一学期的助教和老师们!!!
来源:oschina
链接:https://my.oschina.net/u/4352960/blog/4319280