面向对象课程第四次博客总结
太阳尚远但一定会有
一、论述测试与正确性论证的效果差异,比较其优缺点
测试和正确性论证分别从用户角度和开发者角度对工程进行评估。前者能够评测程序在一般情况和可预见的特殊情况下的执行效果,后者能够较为全面地测试到每一个细节。
测试是试图通过使用一些特定的、或是随机的输入,并预测代码的执行结果,来对结果进行检查。
正确性论证则需要对代码的行为进行进一步的抽象,并考虑每个代码部分之间的关系是否正常,是否存在潜在的问题。
前者的自由度很高,更加具体,但对潜在问题的覆盖性稍差;后者需要的代价较大但固定,抽象性更高,覆盖性很好。
代码规模直接限制了寻找问题的代价。测试可以以较小的代价达到寻找表层的问题,正确性论证可以以固定的代价达到控制潜在的问题。
测试的优点:
- 能够对功能性进行代表性测试
- 容易构造样例
- 便于保留样例回测
测试的缺点:
- 无法涵盖所有细节,无法保证通过测试就没有bug
正确性论证的优点:
- 逻辑严密
- 可信度更高
- 细节覆盖更广
正确性论证的缺点:
- 成本大,难度高,测试时间长
- 对代码做了小改动,可能就需要对整个工程重新论证;
- 抽象程度过高会导致与具体实现脱离,达不到效果
- 抽象程度过低则代价很高,与具体实现差别无几
二、调研OCL语言,并比较其与课程所介绍的JSF规格之间的相似和不同之处
OCL(Object Constraint Language)语言是面向对象设计中对图形符号的补充,能够完善建模元素的相关细节。为了解决约束表达问题,IBM公司设计了OCL,经过发展,OCL已经为标准化组织OMG所接受,成为UML标准的一部分。OCL语言虽然是一种形式化语言,但是它既具有形式化语言无二义性的特点,又消除了形式化语言的复杂性。它包含的集合类型有Collection, Set, OrderedSet, Bag和Sequence。语言要素包括类型,操作,表达式和语句。OCL相比JSF要复杂得多,因为它要保证严格的无二义性并且遵守一些列规范,复杂到几乎是一门编程语言。而JSF简化很多,也相对容易书写。
与JSF的相同之处:
- 都是一种形式化的语言
- 具有无二义性
- 每个变量都有类型
- 不会改变系统的运行状态
- 都采用前置条件和后置条件对方法的运行加以约束
与JSF的不同之处:
变量的类型:
- OCL有自己的一套变量(如Integer, Real, String, Boolean, Set, Bag, Sequence)
- JSF不仅支持Java语言定义的所有类型,还支持用户自定义的类型(比如有一个Request类, 则可以在JSF中用Request修饰变量)
变量的运算:
- OCL对变量规定了可以进行的运算方式(如 Boolean类型的and, or)
- JSF支持Java语言定义的所有运算方式
逻辑分支:
- OCL支持if, else一类的逻辑分支。
- JSF不支持if, else, while等逻辑分支。
上下文
- OCL支持用context表达上下文
- JSF不支持上下文表述。
符号系统
- OCL用pre, post表达前置条件和后置条件
- JSF用REQUIRES, EFFECTS表达前置条件和后置条件
三、UML类图、顺序图和状态图
1、类图
2、顺序图
3、状态图
四、整理总结一个学期所学所练
• 4.1 阐述四个单元模块知识点之间的关系
第一单元是入门和过渡阶段,让我们尽快熟悉java语言,在一定程度上扭转面向过程的思维,开始模仿并转向面型对象编程。并开始为电梯调度工程打基石,让我们体会到不用多线程的时候电梯调度是一件相对复杂的事,后面写多线程的时候才恍然领悟多线程和面向对象真的更配。
第二单元是多线程,从相对熟悉的电梯调度入手,是为了让我们更好的理解和入门。但是我觉得从电梯调度入手对我来说反而有点吃力,因为我以前的电梯调度偏算法,调度器就是一个大的面向过程型调度算法器,所以扭转思路变得很艰难,好在时间充裕,攻克了难关。回过头来看都是很简单的事情,但是在当时的情况下异常艰难,脑子是个好东西,越用才能越好使。这个单元从多线程入门过渡到线程安全、共享对象保护等内容,需要考虑较多的线程安全问题。
第三单元继续多线程问题,但是不仅限于多线程的实现基础(如线程安全问题),主要进一步对设计原则与设计模式展开了进一步的讲解。这一单元完成的代码任务虽然相对简单,但是设计思路却尤为重要,比如代码实现中SOLID原则的应用。我觉得这一单元上升到了软件工程的级别,讨论的是方法论,对写代码有着很大的指导意义。但是这些东西相对比较抽象,恰恰需要前面几个单元的代码积累才能真正体会到这些设计原则的重要性,以及怎样把抽象的方法论具体到工程中,这样安排顺序更有助于我们的理解与提升。
第四单元在进行完工程的设计与实现后,对测试、代码格式规范、正确性论证展开了进一步的介绍,这些是软件工程所需要的很重要的东西。写代码不仅仅要自己能看懂,更要让别人易于重用,才不至于都是低效的“一次性代码”,于是有了JSF规范,让代码成为一种语言,易于使用与维护。工程完成之后的正确性是客户最关心的问题,所以一定要有测试环节,针对性与覆盖性测试都是重要的测试环节。正确性论证在一定程度上证明了代码实现的合理性,但永远不能保证完全正确。
• 4.2 梳理自己所设计实现的程序,分析自己在设计、测试和质量上的进步
多项式处理
傻瓜电梯
ALS电梯
多线程ALS电梯
IFTTT文件系统
出租车调度系统
设计从无到有再到比较符合SOLID原则。
测试上从大数据集测试到阅读代码根据代码逻辑进行构造性测试。
程序运行的效率变高了,代码也更容易扩展,逻辑更加严密,交互更加友好了,每个方法的代码数量也逐渐都控制到了50行之内,类的分工更加合理。
• 4.3 阐述自己对工程化开发的理解
一般的工程化开发流程是:需求分析-->概要设计-->详细设计-->编码-->测试-->验收-->维护
需求设计:深入了解和分析用户的需求,避免设计时不必要的改动。
概要设计:确定设计层次、模块划分、接口规范、数据结构、出错处理等。
详细设计:实现概要设计中各个模块的算法、调用关系、说明每一个程序的设计考虑。
编码:根据详细设计补充代码、完成系统的功能。
测试:对编写好的代码进行初步测试,通过后交给用户,由其确认各项功能得到正确实现。
验收:用户验收软件。
维护:根据用户需求和环境的变化,对程序进行部分或全部的修改。
工程化开发的优势在于可以降低软件系统的复杂性,提高软件可靠性,提高开发、维护、测试的效率,减少系统内部的逻辑耦合,提高人员协作的效率。
我觉得工程化开发最重要的内容之一就是代码规范,多人协作完成任务一定要严格遵守代码规范,这样不仅利于开发,更利于后期的维护、修复与扩展。
测试是工程化开发很重要的环节,自动测试的覆盖率要尽可能高,这样在每次修改代码之后都能确保原来功能的正确性,这样大大提高了工程化开发的效率。
• 4.4 对课程的任何期望或建议
建议在理论课时提醒同学OO是在锻炼工程化能力,有一些问题是需要自己根据需求思考的,而不是一有问题就去问助教,让助教选择问题的答案。因为在OO课之前大家基本上都是做要求完善的算法类题目,对这一点可能没有很习惯。
建议完善互测环节。个人认为互测时测试者的态度应该是面向程序找bug,而不是面向分数和数目找bug,程序有bug理所应当要报告,没有bug当然不能无理取闹。建议申请仲裁环节如果有恶意报告bug的现象应该给予测试者一定的扣分惩罚。
建议集成自动化测试,适当减少互测所占比重,使得分数更客观。自动化测试的基础分适当增加,用例更加细化,以便让分数更客观,不至于总是发生“面向运气编程”的情况。将hack成功的样例加入自动化测试中,hack成功会得到分数的奖励,发现的bug类型会帮助自动化测试的完善。即以自动化测试为主,互测为辅,hack样例完善自动化测试的方法。
建议提前重点通知同学们不要泄露个人信息,并且提前提供一些删除word转PDF时个人信息的方法。或者直接在网站上提供统一的readme编写,直接在源头上防止个人信息的泄露,也便于查看恶意泄露信息交易的情况。
尾声
一学期的OO课程结束了,忽然很平静,第一件事情想是回去看看先导课的博客。
其实印象最深的是那些灯光暗淡的夜晚,苦思冥想构造更好的解决方案,不断针对架构实现发现问题时的欣喜。个人认为,在OO的每一个工程项目中,被锻炼的不是具体算法的精妙,而是系统间的配合与功能划分,在多线程程序中,考虑好要构造什么对象,每个对象完成什么,什么时候需要共享,其实就能解决一半的问题。这两个问题看似简单,但在实际问题中也不是那么好考虑,OO让我更加仔细观察生活了,因为这些实际问题往往都可以在生活中找到答案,大自然是很精妙的存在。
最后,真的很感谢吴际老师。我记得第一节先导课的时候,曾经慌张无措的我在eclipse里第一次新建了一个类,吴际老师手把手交了我最基本的语法,少了一些害怕,多了继续下去的勇气。那个时候吴际老师的启发式教学给我很深的印象,课堂氛围也很好,也许是去年夏天的愉快经历让我一直觉得OO这门课再累也是值得的吧。以及感谢助教们的辛苦付出,他们真的很棒,一直守着及时回答问题,很仔细的斟酌问题是需要同学自己思考还是要给出需求指导,还要承受各种被怼的暴击。感谢一直以来一起奋斗一起完善方案的小伙伴们,一起从崩溃的边缘勇敢迈回来,我们力量很渺小但是也能做到不是吗。
希望未来的自己,无畏,敢去挑战更多,去经历不一样的山川与河流。
“
昔年曾见此湖图
不信人间有此湖
今日打从湖上过
画工还欠费工夫。
”