结对编程の优缺点
【刚刚结束结对编程之初体验,来此汇报一下,顺便领鸡腿。】
AssertTrue((大神·王若愚 && 渣渣·李云涛).CompleteProject)
所谓结对编程,简单来说就是两个程序猿坐在一台电脑前面,一个手扶键盘手指飞速移动,一个沉思状在一旁默默盯着电脑屏幕不时还稍微吐槽几句。就像下面这张图片这样
那么问题来了。码字的不想被不干活的指点,吐槽的又看不惯对方的做法,这种情形在初期尤其明显。因此,结对编程的缺点在前期表现的非常明显,如:
由代码规范之类的小问题激化出较大矛盾。
编码过程中出现意外的交流话题,导致跑题。
两猿都希望自己按照自己的想法做,于是产生矛盾,合作分裂,项目不能完成(,得不到工资,进入恶性循环)。
一个键盘直接导致码字效率减半,开发时间变长。
某猿可以以沉思猿的身份滥竽充数,不执行领航猿的工作。
编码过程中身后存在奇特生物监视,瘆的慌。特别当奇特生物具有较长时间的生存经验时尤其严重。
......
这些问题或多或少会影响到开发效率。但是习惯这种开发方式、工程进行到后期时,会发现结对编程带的优势是非常大的:
最重要的一点是:代码质量高了很多!!!一只写一只看的模式杜绝了很多小错误的出现,而这些小错误常常是很难发现却至关重要的(比如分数中比较大小的负数问题)。后期调试时间大大缩短。
呆马质量提高,所有编码规范都能被有效执行,尤其坚决杜绝Tab空格混用的情况。
两只程序猿可以在自己擅长的领域发挥强大的编码能力,如一只码算法,一只码界面。
遇到困难问题有两个脑袋考虑,效率高。
于是经过了一段时间的结对编程,让我来点评一下渣渣程序猿(我)和大神攻城狮(队友)
渣渣:
顾名思义,非常渣,于是锻炼出了静下心来码程序的技能。可以连续码程序很久并屏蔽外界中断和系统调用。
顾名思义,非常渣,因此为了避免错误反而会注重代码中的规范,会严格遵守。
顾名思义,非常渣,于是经常学习各种东西,导致各种东西都听过一点。
顾名思义,非常渣,所以经常会犯很小的错误,而且不容易发现。
大神:
顾名思义,非常神,各种高端算法直接默写。
顾名思义,非常神,神速发现代码中出现的各种Bug。
顾名思义,非常神,读代码能力很强,渣渣的各种奇葩代码一遍读懂。
顾名思义,非常神,神到不在意某些细节,如变量名的选择、代码规范的统一。
于是渣渣这次幸运的在大神的帮助下完成了此次任务,就像这样。
设计方法及实践
Information Hiding:
信息隐藏,隐藏调用者不需要知道的信息,并拒绝用户访问不应被直接访问的信息。
实现方法:所有类成员变量定义为private,操作类成员必须通过调用相应的方法。对类使用额外的接口层进行封装,只能通过接口调用到类内部。本次实现中全部对象均只提供方法调用,不提供直接的访问权限,所有功能被封装在一个大的接口下。
Interface design:
接口设计,应尽量简单、清晰,调用者很容易通过接口了解到相应的功能。
实现方法:选取合适的命名,给合适的参数和参数名。在命名时应按照规范进行。
Loose coupling:
松耦合,即减少模块与模块之间相互依赖的关系。当双方中的一方改变时,另一方无需变动功能照常。
实现方法:面向对象的思想就是松耦合的一个体现。对象封装属于自己的数据和操作方法,供外部调用的只有方法而没有直接的数据。所有接口一旦定义好功能不再修改,每次修改代码不能对输入要求更严,但是可以更松,输出应相同,产生的副作用可以更少但不能更多。本次程序功能模块与用户界面实现松耦合,核心利用接口层接收用户输入的参数,传入到相应的模块进行处理,返回处理结果。前端无需知道后端的实现方式。
单元测试
对于本次程序,使用了单元测试以确认每个部分是否正确。如下图所示。其中每个测试针对功能中的一个模块,测试了不同分支路线的处理情况。
核心模块类关系UML图
BasicNum类实现了一些基本数据类型的高级运算功能。
Number类用于记录算式中出现的数,提供了分数的多种方式创建、存储、运算以及按格式输出功能。
Formula类记录多项式,内部的数为Number类对象,提供随机生成功能,可以设置参数。
Program类为顶层接口类,将所有功能封装为统一的接口模式。
在实现中使用了一些小的技巧。
对于数字的存储,无论输入是分数或是小数,均使用了假分数的形式(小数化为分数),这样在处理时可以统一。重载输出方法,满足各种格式的输出需求。
算式的生成模拟后缀表达式的运算过程,括号为逻辑添加而不是人工随机添加。
随机生成数字和算式均有参数控制,作为各自类的方法而存在。
对于极端参数,如过小的最大数值和过大的生成数量,程序判定为:连续生成50个均失败即为参数不合法。此阈值可以根据性能需求方便修改。