面向对象总结博客

面向对象总结博客

一、UML单元两次作业结构

1)UML第一次作业

第一次作业只涉及类图,完成的操作也只是通过类名来获取一些和类有关的信息,也就是查询操作。所以大概的思路就是:类名->类ID->属性(operator,attribute等)集合->根据查询的具体内容分析。有了这样的一个思路的话,那结构大致就是用若干HashMap来建立映射,<类名,类ID>,<类ID,类属性/属性集合>。必要的时候也需要建一些属性ID和名字的对应等等。至于要用到继承的相关信息的时候,可能需要统计所有的父类等信息,大致需要一个类似图的结构来存储这类信息,我也是建立了HashMap来实现从子类到父类集合的映射。

至于对性能的分析,除开分析时候必要的时间以外,本来最耗费时间的应该是查找父亲们这个过程,但是由于我查询的时候,是按找迭代的方法,将相关的父亲信息存储在了映射中,所以只有第一次查询这个类的父亲时比较耗费时间,其后不论是再次需要使用这个类的父亲们,还是他某个父亲的父亲们,都只花费在HashMap中查询key的时间。所以感觉性能还是可以。除此之外并没有想到什么对具体分析过程的优化,所以具体的分析基本都是直接的遍历。

然后是本次的UML类图:

BUG分析:这次作业强侧的时候由于空指针的问题炸掉了,从测试上来说,只测试了很简单的情况,只考虑到测试类功能的正确性,并没有考虑到类如果没有相关信息却查询,应该返回0的情况,所以导致测试时并没有检查出这个问题。从设计上来说,按道理使用HashMap的时候,都应该先判断是否containskey,但是由于在写代码的时候,想要先写完大体的框架,然后再来补全判断containskey的问题,但是由于疏忽还是漏掉了这个地方。所以第二次作业的时候,我就在所有使用HashMap的前面都检查了containskey,依次来防止空指针的情况。

2)UML第二次作业

这次作业,除了覆盖上次的内容,还新增了对顺序图和状体图的查询,以及对他们的正确性检验,首先是顺序图和状态图,查询的基本思路和上次类图的查询是一样的,并没有什么差别。

然后是三个rule的检查,首先rule002是对于属性和对端end名重复的检测,大概就是如果有属性集合,就先检查类属性中是否有重复的属性名,如果有End集合,就检查End名是否内部自己重复,以及属性集合是否contain这个End名,值得注意的是这里End名可能为null。

对于rule008,检查是否有循环继承的情况。首先类只能继承类,接口只能继承接口,类可以实现接口,但接口不能实现普通的类,所以如果有环就一定是在类或者接口集合的内部,这里便不用检查类实现接口的情况。一开始考虑的使用DFS来查找环路,这样能够找到环路,但是标记之后的图并不能找完。所以第一次更改为了不标记的DFS的情况,但是不标记可能导致复杂度很高的情况,最后就改为了Tarjan的强连通分量的算法。

DFS存在的问题:

比如这个图,DFS从接口5开始,5->3->4->6->5,返回环,然后回退,会一直回退到5,这个时候3,4,5,6都被标记访问过。5->7->8,这个时候由于6已经被标记,所以不会再访问,就导致无法找出含有7,8的这个环,就导致了错误。

对于rule009,检查是否有重复继承的情况,按道理来说,本来的思路应该是检查上一次作业中,每一个类或者接口对应的父亲ArrayList集合时候有重复的情况,直接遍历就可以找到,然后将这种称为直接重复,之后检查由于类实现接口所导致的重复情况。而对于不是直接重复的情况,就只能是通过类实现接口来完成,如果能够返回这个类所实现的所有接口,包括接口的继承,类的父亲所实现的所有接口,这样就能够直接遍历这个集合来判断是否有间接重复的情况。所以我就通过遍历的方式得到了这个类所实现的所有接口。最后再检查类继承的时候,是否由于父类的重复而导致重复的情况。这样的逻辑里似乎会有重复的情况,但是为了保证不漏下任何一个错误,就没有对此做精简。

然后是这次的UML类图:

BUG分析:这次作业经过了大量的检测,也通过了强测,咋看之下没有什么问题,但是刚才在看rule002的时候,发现了一个bug,对于一个孤立的类,有两个重复的attribute,按我的理解应该报重复的错误才对,但是却没有报错,原因是我查找的类ID并不是全集,而是所有含有end对应的类ID,从而导致了这个bug,应该检查所有的类id才对。感谢老师和助教的不杀之恩。

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

第一单元:

一开始对面向对象没有理解,也不知道要怎么设计架构,一开始写的像c程序,到第一单元的最后一次作业的时候,大概开始有了面向对象的思想,知道要把相应的对象分类,相应的方法写在对应的类底下,相应的对象只完成自己的功能。

第二单元:

这次作业是电梯,这次的架构来说,比较好抽象成生产者消费者的情况,也谈不上什么设计,更像是套用架构,使得思路更清晰i一些,感觉上仿佛是有了面向对象的思想,在代码实践的时候,会想着要面向对象,降低类间耦合度,提高扩展性什么之类的。其余的好像并没有什么理解。除此之外好像对线程的相关知识了解的更多,以及面向对象方法在多线程,线程协作之间的作用。

第三单元:

第三次作业是地铁系统,这一次的设计感觉有了些许提升,知道要利用一些数据结构来实现存储信息的功能,通过一些算法来查询相关信息。也可能是因为这次作业比较明显,就是要建图,然后通过图算法来获得信息。大概流程就分为了建立数据结构,存储信息,通过算法来查询。至于面向对象方法的理解,实践了JML,学习到了规格的重要性。

第四单元:

第四次作业是UML类图,感觉好像并没有什么架构设计,就是利用一些数据结构,来存储,查询,优化查询的速度。然后对鱼面向对象的理解,是对UML类图,顺序图和状态图的细节理解,虽然这个图很早就在用了,但是这么深入的使用,还是加深了对UML类图的了解。

演进这个方面来讲,就是c程序->类java程序->套用架构的java程序->自己瞎设计架构的java程序

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

我对于测试的理解一直都是,首先是验证程序正常功能的正确性,包括边界情况的检查,特殊情况的检查,然后是对异常的处理的测试,不正常的输入,为空的输入等等异常的情况。对于特殊情况的检查,似乎检查并不是难点,难点在于考虑到这种特殊情况,感觉这一方面是经验,一方面是从数据可能的情况的全面的分析。然后是对于异常的测试,我就有两次是对于异常输入的测试不足,而导致了最后强测炸掉,相对于正常功能的检测,对于异常的检测是更容易忽略的情况,但对于异常输入的处理也是程序很重要的一部分,所以也不应该缺少。这是从测试的角度来说,但是但从测试来说,并不一定能够检查到所有的bug,因为大部分的测试输入都只是所有测试输入的子集,除非能够完成所有的检查,否则都是有可能出现bug的,所以相对于测试,感觉反复查看代码的结构,检查逻辑,对于找bug是更加好的方法,只是检查代码的时间复杂度通常会更高,但这样也更能检查出一些奇奇怪怪的bug。

对于测试,似乎没有什么理解上的进步,只是积累了更多的经验而已,比如看到数字的时候想一想是不是有可能有int不够用的情况,使用HashMap之前一定确保不会有空指针的情况,又或者条件里面两个东西是否相等,应该用equals还是==或者是其它的。至于逻辑上的正确性,这和每个不同的程序相关,也谈不上什么演进,也可能是我检验逻辑正确的方法的抽象程度不够,没办法归结或者是演进。

至于实践上的演进,大概是从手动随心所欲的测试,到有目的的测试,再到使用一些工具来辅助测试,和通过可视化(画图)的方法来检查逻辑是否正确,再到用junit进行单元测试。

四、课程收获

0.大量的编程实践经历

1.学会了java

2.对于面向对象的思想有了一定了解

3.对于多线程协作有了一些了解,以及实践

4.对于经典的模式有了一些了解,从别人抽象的结构中学习

5.对于如何设计架构有了我自己的一些看法

6.对于写bug,和处理bug有了一些经验,以及学会了使用一些工具来进行分析

7.对于规范有了一定的理解,包括JML规格,以及代码风格,虽然我及其讨厌代码风格,但是不得不说这是很重要的东西。

8.自己实践了一些算法和数据结构,

9.收获了很多测试时候的经验

五、建议

1.四个单元虽然循序渐进,每个单元有自己的侧重,单元之间的联系似乎并没有,感觉如果单元之间也还有些联系就更好了。

2.实验课的难度好像有点奇怪,有一次实验难度有点过于高,后面几次的难度好像又有点过低 ,不过每次实验想让同学初步了解一下单元内容,作为一个入门也还是很好的。

3.还有就是如果规则或者说需求更加明确就好了,就比如最后一次作业,强测中并不会又类的多继承这种情况,如果能提早说明的话,检查规则009的时候逻辑应该会更加简单,但是这个说明出的时间很晚。

 

posted on 2019-06-24 16:19  没心的先生懒  阅读(206)  评论(0编辑  收藏  举报