面向对象裸程序的例子≡显示器控制程序[连载五]

发布: 2009-11-26 17:18 |  作者: 来自网络 |   查看: 36次

继续上面帖子讨论的问题。前面我们提到,为了使用dispShowAChar()、dispShowALine()、dispMainThread()这三个函数,我们又引出五个新的函数来,这些新的函数最主要的目标,就是要实现调用者与被调用者之间数据的传递。电子园51单片机学习网DSNn m)]$Q
    对于程序设计来讲,数据传递与程序逻辑有着同样重要的地位,前者经常在最后会形成一种协议,后者则经常表现为各种算法
4}x~E6h$q7K0    在裸程序中,我们的思想应该主要是表现为一种灵魂,而不能如C++那样,去追求语法的完美,所以对于参数的传递,我们不能去追求语法上的完美,而是不拘一格用传递。除了函数可以传递数据外,直接调用值也是一种很快捷的方式,但是调用不能随便说调就调,而是也要学习C++上语法的习惯,尽量不能让一些专用的变量名称,出现在与专用变量无关的程序体中。例如,我们的设计中规定,我们这套裸系统对显示器最多支持65536色,那么我们就会用一个16位的无符号整数来保存这个指标。为了简化以后的说明,我们先定义两个数据类型:电子园51单片机学习网 I,`,A$M b1jD Z
typedef  unsigned int    UINT;
Xd Tz%gt0typedef  unsigned char    UCH;电子园51单片机学习网J_ oL#Vo7Yp0A
如果我们用函数来传递这项数据,我们可以用如下的方式:电子园51单片机学习网Zd b Ep8K{.ue
        #define Monitor01_MaxColors    0xFFFF电子园51单片机学习网1LV6e*scI8\[5e`
对于颜色调用函数则定义如下:
nO0G z6]"rQ0UINT  dispGetMaxColors()电子园51单片机学习网4]~p)V wH}R)Q
        {电子园51单片机学习网Q9ko7G;n]!K~~
            return  Monitor01_MaxColors;电子园51单片机学习网_ [#[`y$FAc2arua
        }
.I5t$Zco~5E9\S0很显然,如果另一个显示器是个单色显示器,则颜色调用函数只需要改为下列形式就可以了:
^gr5ZQ F0        #define Monitor02_MaxColors    0x0001
UYy3qH;n%A0        UINT  dispGetMaxColors()电子园51单片机学习网hrRC Vc'P
        {电子园51单片机学习网.l}(jPS3D2}#\\2n)F
            return  Monitor02_MaxColors;
v'Nwo$N[0o0        }
"e;N%} rQzY%s1h0    前面已经有朋友在帖子里提到过了,用数组,这可以解决很多问题。说得一点没错!上面的例子我们忽略了一个问题,那就是同一个函数名要去做很多不同函数所做的事情,而我们却没有在函数体内使用switch(),这显然是不对的。要真正实现不同显示器的共同属性MaxColors的传递,我们必须要添加switch()以区分不同的显示器类型。那么这里我们就需要引入一个新的父对象属性以指代它的第几号儿子:电子园51单片机学习网)P7X(PW F%A
        UCH  MonitorType = 0;    // 显示器类型,最多支持256种显示器
DC T%Mu0    并在初始化的时候,为该属性初始化为0,以作为缺省类型显示器的代号。以下命名我们就说一个约定,以让代码更具有规范的模样:父对象的接口函数用小写的disp打头,变量用Monitor打头,宏数据用Monitor开头并且内部至少有一个下划线,宏函数则用全大写字母组成。那么不用数组的情况下,上面的代码将会变成如下形式:电子园51单片机学习网7hW8{iQ1va5]7[
        #define  Monitor_00    0
%~BDB-lx0        #define  Monitor_01    1
.l(mO f GcE_0        #define  Monitor_02    2
JqK H \%hN0        UINT  dispGetMaxColors()
RGNaK0        {  // 以下用多出口,但这并不会破坏什么,为节约代码,完全可以使用
{8Cz5\1\&\+dN0            switch(MonitorType)
S#O Jw!qp0            {
hGAr(u[0q1J0                case  Monitor_01:  return  Monitor01_MaxColors;
qmN4U7S/d(r`8a0                case  Monitor_02:  return  Monitor02_MaxColors;电子园51单片机学习网;npN6w[ui6z
            }电子园51单片机学习网-UD"[II;hzE3w
            return  Monitor00_MaxColors;  // 缺省则返回默认显示器电子园51单片机学习网? b"G3p#Q lw"ZpTh
        }电子园51单片机学习网+p/J,SBu
    这样的形式很显然是太冗长了,尽管非常结构化,但是一般在优化程序的时候我们还是可能会废弃它的,所以这里就提到了数组的使用。既然是数组,那么它自然不能属于某一个子对象,而是应该在父对象中定义的,尽管这样做我们每次在添加新显示器的时候我们比如在父对象中添加难以理解的新的数据,但是为了节省代码,我们还是能忍受这样的痛苦。如果改用数组,则上面的代码将改变为如下形式:
*Iq y [%@'`0    #define  Max_Monitor_Types    3                     ***电子园51单片机学习网 ~,C;w5P [8W f
    #define  Monitor00_MaxColors    1
X#v@7A-]$w(t0    UINT  code  MonitorMaxColorsArray[Max_Monitor_Types] =电子园51单片机学习网:Q"l y(YF)cQ3v6?D
                        { Monitor00_MaxColors, // 缺省为单色
5{I!d:jWu#m0                         Monitor01_MaxColors,电子园51单片机学习网5S!|6w5I/|T;DzD.i
                         Monitor02_MaxColors,
,wcheA0Cp1OR |0                        };                             ***
$VV+N4NG K@0    打***的语句将是未来扩充时不断需要修改的句子。那么上面的函数就简单了
T`2nqm*@tTa;i0    UINT  dispGetMaxColors()
u5Tx8z9tfDMt0    {
\/E/pVA ~0        return  MonitorMaxColorsArray[MonitorType];
N2LTt?7P^/c0    }
0|&t!lgws:e q0    甚至有人还可以用宏函数来节省运行时间,只要修改一下调用规则就可以了:
iC8z.FH rG$C.`0    #define  DISPGETMAXCOLORS(c)  c=MonitorMaxColorsArray[MonitorType];电子园51单片机学习网'D D;c O0V6A1i5\"['j'm
    也许当我们写成如上代码的时候,我们的每一次改进,都会让我们欣喜,我们的代码又优化了。但是可惜的是,这种没有思想的优化会在不远的将来,给我们带来麻烦。我觉得我的记忆力很不好,也许一分钟前的事情我都会想不起来,这种在将来扩充中的上窜下跳地修改会让我觉得晕眩!电子园51单片机学习网5i1l&g)e6e1~/Kv_`
    所以,在工程化的工作中,我们需要把父对象与子对象尽量隔离开来,减少关联性的修改量,这也是面向对象思想的重要意义之所在,对于这一改动,我将在下帖中阐述。
打印 | 收藏此页 |  推荐给好友 | 举报
上一篇 下一篇
 

评分:0

发表评论
查看全部回复【已有0位网友发表了看法】

单片机开发板推荐

在线客服
在线客服系统