面向对象裸程序的例子≡显示器控制程序[连载五]
发布: 2009-11-26 17:18 | 作者: 来自网络 | 查看: 36次
继续上面帖子讨论的问题。前面我们提到,为了使用dispShowAChar()、dispShowALine()、dispMainThread()这三个函数,我们又引出五个新的函数来,这些新的函数最主要的目标,就是要实现调用者与被调用者之间数据的传递。
对于程序设计来讲,数据传递与程序逻辑有着同样重要的地位,前者经常在最后会形成一种协议,后者则经常表现为各种算法。
在裸程序中,我们的思想应该主要是表现为一种灵魂,而不能如C++那样,去追求语法的完美,所以对于参数的传递,我们不能去追求语法上的完美,而是不拘一格用传递。除了函数可以传递数据外,直接调用值也是一种很快捷的方式,但是调用不能随便说调就调,而是也要学习C++上语法的习惯,尽量不能让一些专用的变量名称,出现在与专用变量无关的程序体中。例如,我们的设计中规定,我们这套裸系统对显示器最多支持65536色,那么我们就会用一个16位的无符号整数来保存这个指标。为了简化以后的说明,我们先定义两个数据类型:
typedef unsigned int UINT;
typedef unsigned char UCH;
如果我们用函数来传递这项数据,我们可以用如下的方式:
#define Monitor01_MaxColors 0xFFFF
对于颜色调用函数则定义如下:
UINT dispGetMaxColors()
{
return Monitor01_MaxColors;
}
很显然,如果另一个显示器是个单色显示器,则颜色调用函数只需要改为下列形式就可以了:
#define Monitor02_MaxColors 0x0001
UINT dispGetMaxColors()
{
return Monitor02_MaxColors;
}
前面已经有朋友在帖子里提到过了,用数组,这可以解决很多问题。说得一点没错!上面的例子我们忽略了一个问题,那就是同一个函数名要去做很多不同函数所做的事情,而我们却没有在函数体内使用switch(),这显然是不对的。要真正实现不同显示器的共同属性MaxColors的传递,我们必须要添加switch()以区分不同的显示器类型。那么这里我们就需要引入一个新的父对象属性以指代它的第几号儿子:
UCH MonitorType = 0; // 显示器类型,最多支持256种显示器
并在初始化的时候,为该属性初始化为0,以作为缺省类型显示器的代号。以下命名我们就说一个约定,以让代码更具有规范的模样:父对象的接口函数用小写的disp打头,变量用Monitor打头,宏数据用Monitor开头并且内部至少有一个下划线,宏函数则用全大写字母组成。那么不用数组的情况下,上面的代码将会变成如下形式:
#define Monitor_00 0
#define Monitor_01 1
#define Monitor_02 2
UINT dispGetMaxColors()
{ // 以下用多出口,但这并不会破坏什么,为节约代码,完全可以使用
switch(MonitorType)
{
case Monitor_01: return Monitor01_MaxColors;
case Monitor_02: return Monitor02_MaxColors;
}
return Monitor00_MaxColors; // 缺省则返回默认显示器
}
这样的形式很显然是太冗长了,尽管非常结构化,但是一般在优化程序的时候我们还是可能会废弃它的,所以这里就提到了数组的使用。既然是数组,那么它自然不能属于某一个子对象,而是应该在父对象中定义的,尽管这样做我们每次在添加新显示器的时候我们比如在父对象中添加难以理解的新的数据,但是为了节省代码,我们还是能忍受这样的痛苦。如果改用数组,则上面的代码将改变为如下形式:
#define Max_Monitor_Types 3 ***
#define Monitor00_MaxColors 1
UINT code MonitorMaxColorsArray[Max_Monitor_Types] =
{ Monitor00_MaxColors, // 缺省为单色
Monitor01_MaxColors,
Monitor02_MaxColors,
}; ***
打***的语句将是未来扩充时不断需要修改的句子。那么上面的函数就简单了
UINT dispGetMaxColors()
{
return MonitorMaxColorsArray[MonitorType];
}
甚至有人还可以用宏函数来节省运行时间,只要修改一下调用规则就可以了:
#define DISPGETMAXCOLORS(c) c=MonitorMaxColorsArray[MonitorType];
也许当我们写成如上代码的时候,我们的每一次改进,都会让我们欣喜,我们的代码又优化了。但是可惜的是,这种没有思想的优化会在不远的将来,给我们带来麻烦。我觉得我的记忆力很不好,也许一分钟前的事情我都会想不起来,这种在将来扩充中的上窜下跳地修改会让我觉得晕眩!
所以,在工程化的工作中,我们需要把父对象与子对象尽量隔离开来,减少关联性的修改量,这也是面向对象思想的重要意义之所在,对于这一改动,我将在下帖中阐述。
对于程序设计来讲,数据传递与程序逻辑有着同样重要的地位,前者经常在最后会形成一种协议,后者则经常表现为各种算法。
在裸程序中,我们的思想应该主要是表现为一种灵魂,而不能如C++那样,去追求语法的完美,所以对于参数的传递,我们不能去追求语法上的完美,而是不拘一格用传递。除了函数可以传递数据外,直接调用值也是一种很快捷的方式,但是调用不能随便说调就调,而是也要学习C++上语法的习惯,尽量不能让一些专用的变量名称,出现在与专用变量无关的程序体中。例如,我们的设计中规定,我们这套裸系统对显示器最多支持65536色,那么我们就会用一个16位的无符号整数来保存这个指标。为了简化以后的说明,我们先定义两个数据类型:
typedef unsigned int UINT;
typedef unsigned char UCH;
如果我们用函数来传递这项数据,我们可以用如下的方式:
#define Monitor01_MaxColors 0xFFFF
对于颜色调用函数则定义如下:
UINT dispGetMaxColors()
{
return Monitor01_MaxColors;
}
很显然,如果另一个显示器是个单色显示器,则颜色调用函数只需要改为下列形式就可以了:
#define Monitor02_MaxColors 0x0001
UINT dispGetMaxColors()
{
return Monitor02_MaxColors;
}
前面已经有朋友在帖子里提到过了,用数组,这可以解决很多问题。说得一点没错!上面的例子我们忽略了一个问题,那就是同一个函数名要去做很多不同函数所做的事情,而我们却没有在函数体内使用switch(),这显然是不对的。要真正实现不同显示器的共同属性MaxColors的传递,我们必须要添加switch()以区分不同的显示器类型。那么这里我们就需要引入一个新的父对象属性以指代它的第几号儿子:
UCH MonitorType = 0; // 显示器类型,最多支持256种显示器
并在初始化的时候,为该属性初始化为0,以作为缺省类型显示器的代号。以下命名我们就说一个约定,以让代码更具有规范的模样:父对象的接口函数用小写的disp打头,变量用Monitor打头,宏数据用Monitor开头并且内部至少有一个下划线,宏函数则用全大写字母组成。那么不用数组的情况下,上面的代码将会变成如下形式:
#define Monitor_00 0
#define Monitor_01 1
#define Monitor_02 2
UINT dispGetMaxColors()
{ // 以下用多出口,但这并不会破坏什么,为节约代码,完全可以使用
switch(MonitorType)
{
case Monitor_01: return Monitor01_MaxColors;
case Monitor_02: return Monitor02_MaxColors;
}
return Monitor00_MaxColors; // 缺省则返回默认显示器
}
这样的形式很显然是太冗长了,尽管非常结构化,但是一般在优化程序的时候我们还是可能会废弃它的,所以这里就提到了数组的使用。既然是数组,那么它自然不能属于某一个子对象,而是应该在父对象中定义的,尽管这样做我们每次在添加新显示器的时候我们比如在父对象中添加难以理解的新的数据,但是为了节省代码,我们还是能忍受这样的痛苦。如果改用数组,则上面的代码将改变为如下形式:
#define Max_Monitor_Types 3 ***
#define Monitor00_MaxColors 1
UINT code MonitorMaxColorsArray[Max_Monitor_Types] =
{ Monitor00_MaxColors, // 缺省为单色
Monitor01_MaxColors,
Monitor02_MaxColors,
}; ***
打***的语句将是未来扩充时不断需要修改的句子。那么上面的函数就简单了
UINT dispGetMaxColors()
{
return MonitorMaxColorsArray[MonitorType];
}
甚至有人还可以用宏函数来节省运行时间,只要修改一下调用规则就可以了:
#define DISPGETMAXCOLORS(c) c=MonitorMaxColorsArray[MonitorType];
也许当我们写成如上代码的时候,我们的每一次改进,都会让我们欣喜,我们的代码又优化了。但是可惜的是,这种没有思想的优化会在不远的将来,给我们带来麻烦。我觉得我的记忆力很不好,也许一分钟前的事情我都会想不起来,这种在将来扩充中的上窜下跳地修改会让我觉得晕眩!
所以,在工程化的工作中,我们需要把父对象与子对象尽量隔离开来,减少关联性的修改量,这也是面向对象思想的重要意义之所在,对于这一改动,我将在下帖中阐述。






