接着继续(OO博客第四弹)

、测试与JSF正确性论证

  测试和JSF正确性论证是对一个程序进行检验的两种方式。测试是来的最直接的,输入合法的输入给出正确的提示,输入非法的输入给出错误信息反馈,直接就能很容易的了解程序的运行情况。但是,每次测试只是在程序涉及的整个问题空间取一个元素进行测试,一次测试只能确保程序对于测试中的样例和同类样例是正确的,并不能确保全局正确性。而为了追求全局覆盖性,就需要大规模的测试样例轰炸了,但是这时测试的最致命缺陷就出现了,一是如何构造如此大量且属于不同类别的测试样例,二是如何确保构造的测试样例能够覆盖所有的语句和分支,三是对于一些复杂的,可靠性要求高的程序,这样的测试级别还不够,还需要更高级别的组合测试,例如,现在有两个分支1和2,分支1有a,b两种情况,分支2有c,d两种情况,单纯的分支测试只会保证a,b,c,d都被执行过,但对其中的组合情况没有考虑,而这正是实际问题中bug容易发生的地方,多重分支的叠加最后达到一个编程人员在设计很难预料到的情形,从而发生错误,而组合测试就需要将可能发生的组合:ac,ad,bc,bd全部测试一遍,而随着问题规模的扩大,测试样例的数目将呈指数级上升,这将带来非常大的测试难度。

  正确性论证是一个上限很高的方法,如果能够完整且正确地对一个程序完成论证,那么这样分析过后的程序的可靠性几乎是100%,能够归纳覆盖整个问题空间。但是,正确性论证对于使用者的要求很高,一些复杂的论证需要很高的数学技巧,论证多分支情况时也很难保证完全不出错误不发生遗漏,这需要使用者对于该程序有非常高的熟悉度和强大的全局驾驭能力。此外,正确性论证需要的步骤很多,需要严格的证明,且主要是人来完成,因此需要大量的时间。同时,面对多分支组合问题,论证时也将面对指数级增长的划分数,这导致工作量会变得更大,非常消耗时间。

  因此,我认为更合理的方式是结合两种方法,即使用正确性论证的思想来进行划分,对于每一个划分的情况构造通用性高的测试样例进行测试,最终得到具有高覆盖率的测试集。同时,应该做到测试与设计并行,在设计时也要适当考虑测试因素,对每个类和方法做更多的规约和异常检测,减小问题空间的维度,为测试减小压力。

 

二、OCL语言 VS JSF

  OCL语言介绍:OCL(Object Constraint Language)语言,即对象约束语言,通常与UML一起使用,用来表达对于UML图的约束,而一个约束就是对一个(或部分)面向对象模型或者系统的一个或者一些值的限制。

  二者相同点:

  (1)都是声明式语言(Declarative),即表达式仅仅描述了应该去做"什么",而不是应该"怎样"去做。因为OCL是宣言式语言,所以UML中的表达式被提升到了纯建模的领域,而不必理会实现的细节和实现的语言。JSF也是说明了方法执行前后产生的影响,而不描述具体是如何产生影响的。

  (2)都是基于数学(集合论和数理逻辑),取数学符号和自然语言的折中方案,使用逻辑表达式来描述约束内容,但是具体的元素可以使用自然语言说明。

  (3)都有不变式,前置条件,后置条件这样的语法。

  不同点:

  (1)OCL是强类型语言,任何表达式的值都是属于一个类型的。这个类型可以是预定义的标准类型例如Boolean或者Integer,也可以是UML图中的元素例如对象。也可以是这些元素组成的集合,例如对象的集合、包、有序集合等等。JSF中对此没有很严格的规定和要求。

  (2)OCL规定了很多具体的操作符,数据类型和表达式语法,而JSF中更着重于一定要按照逻辑运算规则进行推理,更加要求符合数理逻辑中的规则,而对于操作符没有很严格的要求。

  (3)OCL语言可以对类,类的属性和操作等等任意的进行约束,而JSF仅针对类和方法。

  (4)OCL通常结合UML类图使用,加之其支持对于各种上下文的约束,同时还要保证没有二义性,由于需要支持这么多的功能,所以它是一门“重型”语言,不像JSF是轻量化的语言。

 

三、第十四次作业相关UML图

 UML类图

  顶层package

  package:helper

  

   package:interface

  package:model

  package:model中Elevator类

  

  package:model中QuestQueue类

  package:model中SchedulerAI类

    

  顺序图

 

 

四、总结

4.1本学期OO的四个模块内容

  • (1) Java与对象(java速成+面向对象程序设计入门)
  • (2) 并发与安全(多线程程序设计入门)
  • (3) 抽象与规格(规格化和设计方法学入门)
  • (4) 测试与论证(单元测试+JSF论证)

  首先,四个模块是循序渐进,将整个工程化设计的内容划分成几大部分,然后分部分进行学习和训练。从大家最熟悉的程序语言开始,一步步深入到面向对象程序设计思想,多线程程序设计方法,直到工程设计方法,整体类似于一个自底向上的过程。但是呢,个人观点,在讲课的时候固然分成四个模块逻辑清晰,但是实际应用中四个模块的方方面面都是要涉及的,是否可以设计一些单元之间内容交互的作业,或者是综合作业,这样更具有综合性的东西才会更加让人感受到工程化方法的重要性,否则每次只针对一个点会让一些人可能产生应付该次作业的心态,当然这样的综合作业时间周期可以加长,专项作业中穿插综合作业,我觉得是更有意义的选择。

4.2个人收获与感悟

  作为一个从大学开始接触编程的人,前一年半基本上是在面向过程语言中度过,写了数不清的C代码,所以很多时候脑子里有很多C语言的设计思想,经常会想java中是如何提供这个语法功能的。本学期接触面向对象程序设计,最大的感受就是:原来编程语言相关的设计和思想这么精彩。先说个人的程序吧,首先呢,得益于几位大佬的帮助和课程的训练,代码能力上取得的进步是最大的,从命名规范,书写格式,数据结构,类和方法的设计,再到线程的规划与管理,都有了长足的进步。当然肯定要贴图对比才最直观了:

第一次作业:

 

如果硬要评价的话,这次作业就是满满的C味java,完全是C语言的设计思想,只不过假装建立一个类调了java类库的一些方法而已。

那么到了第十一次作业:

编程规范上已经有了长足的进步,同时也学会使用java的一些更加高级的语法,最重要的是,真正使用面向对象的思想来建模,逐步使用接口来对设计进行规划。

到了最后一次代码作业,即第十四次作业,即重构ALS电梯时:

代码风格已经趋于稳定,算是比原来的自己上了一个大台阶吧。

  关于文档和规格,其实我一向是非常支持注释和文档的书写,代码写的简洁高效易读,同时辅以良好的注释和说明文档,就像自己写的一篇文章一样。不过说实话,我对于以JSF这种方式进行规格撰写是不太支持的,我个人偏向于java类库中那种javadoc的格式,这个想做到自动化太难了,从理解的直观性来说,自然语言是要好过逻辑语言的,如果我们在设计上加以优化,二义性的问题也能得到很好解决,JSF的优势是能覆盖到问题的各个方面,绝无二义性,所以个人觉得也可以适当把JSF补充在可能出现二义性的地方。不过,规格书写的重要性,或者更深层次,设计规约的重要性,我在第十四次作业中得到了非常良心的体验。在进行JSF论证之前,我对之前的代码进行了彻彻底底的重构,自认为已经很完美了。但是在进行论证的过程中,仍然发现了几处很难表述的方法,而之后通过对划分执行情况,再对代码作进一步分析后发现,我的设计思路中有很多交叉和冗余地方,比如明明可以通过维护队列完成的功能,我在之前的设计中却给队列元素增加了两种标记,标记之中还有小的分类,致使代码功能虽然正确但是很臃肿,而通过论证时对于各类情况的剖析与划分,便能很容易的找出问题的原因所在,这也再一次告诫我,一定要设计优先,不要直接上手写代码。

  关于设计问题,我大约经历了这样一个过程:面向过程——无脑使用类,方法当函数用——抽象类+接口设计。仅凭大脑思考,基本是不可能驾驭大工程的,那么通过设计方法学来首先做设计规约,并把所有的设计思路具象化,在java中使用抽象类+接口设计的方式进行初期规划,并辅以文档和规格进一步对类和方法进行规范化,做完所有准备工作之后再开始写代码,这样,才能真正写出大工程。

  测试是我的一个很严重的弱项,老实说现在还处于对拍器对比输出结果的阶段。本学期初步接触了单元测试,但是感觉理解的还很不足,个人认为这部分内容最重要的还是在实际中使用,为了完成作业去编写单元测试意义不大,因为测试的代码基本上都是已经修复完bug的版本,少了测试——发现bug——修复bug——再测试这一环节,就很难深刻体会到单元测试的优点,这部分内容结合在复杂的几次作业中就更好了。

4.3 工程化方法之我见

  工程化方法包括很多的内容,一一说下来要列好长的清单,其实核心就在于如何解决个人有限的能力和工程无限大的复杂度的矛盾。实际工作中大工程需要很多人来合作完成,而每个人的能力,特点又不可能相同,所以1+1=2是绝对不可能的,那么如何在这样的情况下,尽可能的追求总体的最终的高效率和高质量,这就是工程化方法告诉我们的事了。当然,现在的工程化方法大多是建立在人的经验之上的。说不定到了未来,由于编程人员能力的提高(或者说机器自动生成底层代码),相关数据分析能力的提高,工程化方法将变成数据导向的产物,人类的思考只需做最高层的设计。毕竟,最核心的永远是解放生产力,让人的思考用到最关键的地方去呀。

4.4 关于OO

  关于OO课程,首先表示非常感谢这门课程,确实给我带来了很多变化。这门课程虽然被很多人诟病,但是我觉得还是很有其存在必要的,只是一些具体实现的环节仍然存在问题,因此,我希望能成为OO助教,真正去修补这些问题,而具体的建议,就通过实际工作来看吧,OO接着继续!

 

posted @ 2018-06-25 13:15  SwainZ  阅读(187)  评论(1编辑  收藏  举报