OO第四次博客

 

4html

1.测试与正确性论证的比较

这二者在我看来不可比较。前者是对代码正确性的验证,是对代码实际运行结果与预期运行结果的比较。后者是检查代码逻辑与规格逻辑的一致性。git

在我看来,前者的优势在于,当“预期”具备正确性时,它能够确确实实地保证代码的正确性。缺点在于,“预期”自己有时候难以获得,当程序过于庞大、复杂,例如一台每秒几万响应的大流量服务器上的程序,对于它而言,“预期”是极难经过人工得到的。github

然后者,正确性论证的优势在于它不须要进行测试那样的穷举操做,顶层的正确性能够分割成底层的正确性,论证复杂度逐层下降,易于实施。缺点在于哪怕程序经过了正确性论证,它也不必定是对的,由于一方面规格自己不必定正确,不必定可以得出预期的结果;另外一方面,人工进行正确性论证这件事情自己就极有可能出错。web

2.OCL语言

OCL: Object Constraint Language.它是UML标准的一部分。wikipedia里面的说法是:canvas

OCL はUMLを補うものであり、天然言語の曖昧さを排していると同時に複雑な数学的記法を扱わなくてもよいという特徴がある。OCL は、図に基づいたモデルのためのナビゲーション言語でもある。ruby

翻译过来就是,OCL是对UML的补足,在去除了天然语言的暧昧性的同时,也避免了复杂的数学记法,是用于基于图的模型的标记语言。服务器

与JSF的类似之处……都是描述性语言?OCL一般也使用前置条件、后置条件、不变式来描述方法、类。微信

与JSF的区别之处在于OCL没有抛弃天然语言,它考虑到它自身是一种标记语言,更多的是为人所阅读,而没有采用极为复杂的数学记法。JSF恰好走了相反极端。markdown

3.UML图

类图

时序图

状态图

4.总结

4.1四个单元的联系

第一个单元讲的是OO,第二个单元是多线程,第三个单元是规格,第四个单元是测试&正确性论证。多线程

第一单元所讲的面向对象思想是实现后三个单元的基础,不然实现复杂度会太高。

第二单元的多线程,这个说实在的我以为和咱们的课程没有太大关系,在我看来这只是为了提升做业难度而额外拓展出来的课程内容罢了。

第三单元的规格,是第一单元OO思想的延伸与补足,也是第四单元正确性论证的基础。在代码的基础上再追加一层逻辑抽象,而这一层抽象相较于代码而言更加容易验证。

第四单元的测试、正确性论证,是1、二单元的收尾。不管是OO,仍是规格,其初衷归根结底都是为了实现“正确的程序”,这个正确性包含了现有逻辑自己的正确性、拓展后的正确性。第四单元的测试、正确性论证从两个角度去尝试实现这一目的。

4.2自身成长的梳理

那我就实实在在,不掺半点水分地梳理一遍吧。

最先的多项式、单线程电梯那里,我依然延续之前的风格——尽量多地考虑到后续可能的拓展。我会这么作是由于我之前写的代码都是我自用的。这种代码的初次编写须要较高的耗时,测试也每每较为繁琐。不过优势在于后续拓展每每是简单的,虽然手续上可能较为繁琐,可是逻辑上相对简单。测试也每每由于较低的逻辑复杂度而偏向于平凡测试。这符合我自用的需求——没有DDL,且我随时均可能会有新的想法要去实现。

后来的多线程电梯我也依然延续这种风格,不过由于多线程接触得较少,因此那次我花了极多的时间在设计上,在设计这个层面花了极多的精力去避免多线程陷阱。结果也很好,事实上多线程电梯中我基本彻底复用了单线程电梯时的代码,虽然代码层次愈来愈深,可是每一个层次的复杂度依然很低。追加的线程部分的代码与多部电梯的调度逻辑,都很好地和原来的代码分离了开来。在实现多线程电梯的过程当中,注释、标记、日志的使用让我为之一振,它们的出现虽然让代码看起来变得繁琐,可是在复杂的多线程测试中,它们的存在极大地下降了测试复杂度。输入输出的重定向实现,测试线程的应用也让我由本来的批处理测试转向了具备更高复杂度的自动测试。

是的,在这一阶段,我以为我每一次做业都在成长。虽然这份成长恐怕没法体如今我找到的别人bug、别人找到的个人bug上。

可是这以后的IFTTT,让我今后中止了这种风格的代码——我再也不多写,也再也不追求测试的完备性。缘由很简单,我没那么多时间。需求变动过于频繁,推翻重来成了屡见不鲜,许多需求甚至没法明确。我察觉到了之后当我成为社畜之后这会变成常态。若是我依然延续之前那种完备的代码风格的话,之后我可能会变成一个码农,最后过劳死。如我以前所说,虽然我本来的代码风格由于冗余的设计而易于拓展,可是每次修改的手续是复杂的,这没法适应频繁变动的需求——每一次修改我都须要耗费一两个小时去改,而每每我刚刚改完,需求就又变了。

我确确实实地察觉到了个人代码风格不适合这种需求环境。因而我改变了个人代码风格、测试风格。代码中虽然依然保持各个逻辑的分离,可是再也不进行任何冗余设计,尽量地将每次微小改动局限在一小段代码中,哪怕多是要重写整片代码,哪怕逻辑可能复杂——可是修改量很小,修改时间很短,只是对“我”的要求很高。测试风格也再也不追求高覆盖率,不然每次需求变动我就几乎每次都要从新准备测试样例。我转而仅仅只针对需求的每一条独立地进行测试,在这之上再进行随机测试。

这种风格的转变在以后的若干次出租车一直延续了下去——我不知道何种风格是好的,我只是选择了一种“我能完成一份有效做业,同时不会花费过多时间”的方法。对于我而言,“进步”这个概念在IFTTT以前都确实存在着,可是这以后,我可能更多地是在适应。

4.3对工程化开发的理解

按照个人理解,如今我遇到一个矛盾:

  1. 工程化开发应该力求逻辑的简单,“傻子也会敲的代码”,我一直都是如此要求本身的,这种作法能更好地进行协做、测试,也更易于维护。
  2. 工程化开发应该力求变动的快速,这一点是我从IFTTT中明白的,如此要求不是为了代码的质量,而是我本身的生活质量。若是我不能适应快速的需求变动,那等待着个人就是生活时间的被压榨。

这二者是否能够并存?我也不知道,我缺少经验。或许我须要做为一我的、做为一个敲代码的,逐渐寻找这二者的平衡点。

4.4对课程的建议

请思考如下几个情景:

  1. 假设有两位同窗在第一次出租车做业的申诉过程当中遇到不可调解的矛盾,这个矛盾的根源是指导书的不明确,他们两人申请了仲裁,然而这份仲裁的结果直到第四次出租车做业都还没出来。他们其中一人每次都按照本身对指导书的理解去编写代码,这四次出租车做业都由于那一个“指导书的不明确”而被报bug,而每次都申请了仲裁。最后这位同窗在最后一次博客做业的时候收到本身4个仲裁都输了的消息。
  2. 一位同窗虽然每次本身代码没怎么很差好写,可是他很是热衷于互测,每次都会反反复复地发issue、发微信,和多位助教积极沟通,由此得到了较好的成绩。
  3. 一位同窗虽然每次都认真地写本身的代码,可是他为人很是心软,不舍得扣别人的bug,每每虽然测出来一堆bug,可是最后想了想也只挂了一个bug,把测出来的bug都写在了备注里告诉对方。最后他的成绩很是靠后。

以上情景都是我胡扯的,和具体人物没任何关系。

我想说的有不少,浓缩成一句话的话就是:还好这门课挂不挂科和排名不要紧,若是规定倒数多少名直接挂科的话,这门课——不,可能这个系就完了。

相关文章
相关标签/搜索