大家都知道,很早之前我们中国就发现了“勾三股四腰五”的现象,但也仅仅停留在这里,因为当两条直角边时不是3,4时,斜边长度与两条直角边之间有什么关系当时就不得而知了。真正解决直角三角形三边关系的人是古希腊数学家毕达哥拉斯,我们把他的发现称为毕达哥拉斯定理。通过这个定理,我们就可以根据任意两边的长度计算第三边的长度,而不像我们只发现了一个特例。
毕达哥拉斯把变化的边长分离出去(两条直角边为a、b,斜边为c,而不是具体的数字),找到了直角三角形共有的特性,从而得出一个通用的公式:a^2 + b^2 = c^2 。这个过程就是一个典型的抽象过程---分离出变化的因素,找到共有特性。
抽象,除了让数学具有通用性以外,也能帮助的我们设计程序,使得我们的程序更具有通用性,方便了架构程序的同时,还能让我们的工作效率变得更高,因为代码能容易的复用到其他项目中。抽象能带来很多好处,那么,如何抽象一个程序呢。
在讲具体的例子之前,我先说说我在程序抽象时使用的基本原则,这个原则就像数学定理一样,他能指导我设计程序。这个原则主要有两点:
- 分离出某个功能的变化部分,找到这个功能的共同点
- 问自己一个问题,我实现的这个模块是否能容易的复用到其他项目中去
要做到这两点并不容易,特别在编程之前就能对功能做很好的抽象就更难了,因此要做到上述两点,除了要在编程前做一个分析以外,还需要在编程的过程中以及以后做代码维护时不断的重构代码才可能渐渐达到上述的要求。
下面我就以具体的例子来说明如何抽象程序,我先描述一下我们要解决的问题。
控制蜂鸣器实现提示音功能(图1)。要求如下:状态1时短响提示1声,状态2时短响提示2声,状态3时短响提示3声,另外,假设蜂鸣器一声响声的持续时长为100ms,两声之间的间隔100ms,如图(2)所示。
图一
图二 对于这个问题,要解决它并不难,但是做为一个说明程序如何抽象的例子却是不错的。
蜂鸣器的提示有3种状态,要现实这个功能,我们当然能分别编写3个独立的控制函数分别控制蜂鸣器响1、2、3声。如果真的这么做了除了造成蜂鸣器功能管理上的麻烦(因为你需要协调3个函数控制一个蜂鸣器),还有一个就是程序复用性不好,如果我还需要一个3声的提示音,那是不是还要再编写一个控制函数呢。显而易见这种做法虽然能实现但是并不可取。
仔细看看问题,这些提示音之间的区别仅仅在于短响提示的次数不一样,控制蜂鸣器的逻辑其实都是相同的。因此,基于这个特征,我们抽象出相同的逻辑控制部分,把变化的提示次数独立出来,这样就能保证程序在一定程度上的复用性。具体的做法如下。
|