面向对象课程第一次博客总结

  虽然已经写了三次作业,分别是计算多项式,模拟傻瓜电梯,采用接口和继承模拟能捎带请求的傻瓜电梯,但是不知是不是因为三次作业的量还远远不够,我对面向对象编程的理解依然还只是停留在表面形式上,也就是class{},属性和方法这样的组织格式,而这种属性方法的封装模式在跟深层的设计层面上对程序究竟有着怎样的影响,我觉得我的理解还是很浅层甚至模糊的。

  下面是对三次作业的分析和三次作业后对面向对象的一些个人理解。

 第一次作业:计算多项式

1、度量分析 

2、类图

 

3、我的BUG

  公测与互测未被找到bug。

第二次作业:小傻瓜电梯

1、度量分析

  在这一次作业中,reader方法的循环复杂度较高,嵌套层数较深,分支嵌套主要是因为采用了递进式的从整体到局部的输入格式正则匹配,因此建立多个分支判断是否满足前提条件,循环主要用于获取输入,输入获取和格式匹配是同步的,所以嵌套过深也就同步增加了循环体的复杂度。

2、类图

 

3、我的BUG

  输入括号匹配问题。问题实际上出在提取输入的括号对里面的内容时,使用的正则表达式采用了非贪婪模式,导致内容提取得不完整。这一点是因为正则表达式使用不多,理解不够透彻,心思不够紧密。但是整个格式检查的设计应该是没有什么问题的。

 

第三次作业:小聪明电梯

1、度量分析

 

  由于第三次作业直接继承自第二次作业,第二次作业的问题也被继承了下来,同时,在第三次作业中,调度器的功能过于集中更凸显了这一不足。

2、类图

 

3、我的BUG

  一是未判断首条指令是否为(FR,1,UP,0),这是因为没有仔细看指导书的要求而被忽略掉了。二十指针异常,问题在于从请求队列中获取主请求时,未判断请求队列是否为空,导致了指针异常。在最开始的设计中通过一个内部方法获取主请求时,其实依靠外层循环的控制表达式对请求队列做了是否为空的判断,但是后来在检查bug时发现了另外的问题,为了解决新的问题,在原本的获取主请求的方法中加入了新的判断分支来实现在不同的情况下获取正确的主请求,然而就在新添的分支中,没有考虑到也要做相应的队列是否为空的判断,导致新情况下的获取主指令发生了指针异常。

 

测试程序策略

  测试程序,一般先后采用两种方式。首先阅读源码,然后做压力覆盖测试。

  阅读源码是从理论的角度寻找算法层面的缺陷,产生bug的根本原因是代码,没有代码也就没有bug,只要测试者的心思逻辑足够清晰和缜密,就能通过阅读源码找到设计上的漏洞。因此这种方法在根本上很有效,但同时也意味着对于测试者水平的要求很高。所以,只有在第一次作业测试时,程序的设计复杂度还很低,我通过阅读源码发现了被测试程序两处设计上的小问题。然而第二次、第三次作业后,代码量逐渐增大,代码逻辑逐渐复杂甚至混乱,这种方法就失效了。但这种方法却是内源性的主动测试法,拥有本质上的全面性和有效性。

  压力覆盖测试是对应于阅读源码的外部被动性测试,其效果取决于覆盖的全面性。错误分支树是构造测试样例的重要指导,但是错误分支树也很难保证完整,漏洞千奇百怪千千万,唯一的只有正确答案,这也给我们在设计程序时以启示,与其全面考虑千万种可能的问题输入,不如只针对分析检测唯一的合法输入。在实际的使用中,相较于阅读源码的方式,依托错误分支树的压力覆盖测试依然是最有效的方法,针对每一个叶子结点构造相应的测试样例,在第二次作业时,通过这种方法找到了对面的时间顺序判断问题。

 

心得体会

从C到java——过程与对象

  第一次作业时首先写的C程序,数据结构上采用链表储存多项式,整体控制流程采用了状态机模型做输入检测,在不同的状态调用不同的函数做不同的处理,比如进入到读完一个项的状态,就调用insert函数,将新的项添加进入多项式链表中。

  而面向对象的设计是以课堂上的程序为模板基础写了三个类,分别是CulculatePoly类,它的属性是一个多项式数组和一个操作符数组,方法是用操作数组处理多项式数组,它的功能就是计算多项式,至于多项式长什么样,具体的计算操作如何他并不考虑,因此这个类是一个框架,是多项式计算的最高抽象,就好比C语言中的main()函数。然后细化层次,Poly类,明确定义了CulculatePoly类中不关心的多项式数据结构,并针对该数据结构实现了具体的计算方法。此外,Reader类,辅助专门处理输入。

  第一次作业设计比较简单,因此C语言的面向过程程序和java语言的面向对象程序在物理结构上是相似的,处理输入并初始化多项式,循环取出一个多项式,操作一个多项式;但在逻辑结构上,面向过程的多项式和操作多项式其实没有太多紧密关系,一个是数据结构,一个是函数,而面向过程中多项式和操作多项式被封装进入了Poly类中,具有了配套使用和完整解决方案的味道。

  第一次作业后,我觉得面向对象的在抽象的过程中和面向过程还是很类似的,但是比较于面向过程,面向对象更是一种加强数据结构和函数之间逻辑联系的思想正对应与类中的属性和方法,这样一种联系强化,可以更好的管理调用程序中的数据结构而不容易发生混乱。面向过程缺乏这种联系,可能和C语言结构体的功能弱有关,结构体只能容纳属性。

  第二次作业,我觉得面向对象是一种分治策略,它的划分依据是综合考虑各模块结构和功能,对应于抽象类的属性和方法面向对象的设计有一种拟人化或拟物化的味道,每一个类可以看作是一个拥有特殊技能的人,或是模拟了一个真实的物,它比简单的函数功能更加强大。

因此按照分治的思想面向对象的程序设计可以分为两步:第一步是依照功能及结构分类,也就是抽象出各个类;第二步是将各个功能结构组装起来形成具有完整结构功能的主体,也就是在主函数中摆放各个类的位置,设计他们之间的运行规则。

  结合第二次作业,我觉得指导书中预先规定的五个类为第一步操作构建了较好的框架。电梯、楼层、请求、请求队列、调度器五类在功能和结构上正好组成了较为真实的电梯系统。因此在这个框架基础之上,详实描述各个部分在实际运行中的行为,使各个类丰满起来,具有各自的结构和功能。经过第一步之后一个电梯系统就有了基本的组件,也就能进行下一步的组装。在组装步骤,也就是在主函数中,让五个对象相互作用,在从而模拟出电梯按照递增的请求时间的运行情况。比如在我的作业中就是scheduler不断从requestqueue中拿取请求并分析,然后作用到floor和elevator上,floor和elevator作出相应的反应。

  但是到了第三次作业,我发现我的面向对象程序对象性在减弱而过程性在增强。表现在调度器的功能过于集中,整个计算流程都在调度器内部实现,架空了其它类的功能,比如电梯、楼层和请求队列类,使得他们的主体作用就是充当数据结构,对应方法很薄弱,甚至请求队列的引用直接被初始化为调度器的属性,电梯的并不需要移动方法,只依靠调度器内的命令队列做记录,这和面向过程的设计区别仅在于开始时把数据放在了不同的文件中,使用时又把所有数据调入主文件,主文件也就变成了一个面向过程的程序。这样的情况在我的测试任务中也有出现,被测程序的楼层类甚至直接是一个空类,不知道是不是因为指导书的类抽象层次并不符合他的抽象思想。

  因此第三次作业暴露了我许多亟需解决的问题,实际上,三次作业的类几乎没有哪一个是我自己抽象出来的,全靠指导书建立的框架,再去填补这个框架,面向对象如何在高内聚低耦合的指导思想下去抽象一个类,类的划分细度又如何,看来需要在今后更多次的作业去汲取经验了。  

posted @ 2018-04-03 23:17  何方程  阅读(207)  评论(1编辑  收藏  举报