如果你曾经用Perl开发过应用程序,那你可能用过很多程序模块。而且你还可能天天用到这些程序包的面向对象接口。但是,如果你像那些普通的Perl程序员一样,在开发自己的代码时都不试着使用面向对象技术。那么,这篇文章可以帮助你成为一位习惯面向对象编程的Perl开发者。
OOP速成
面向对象编程(OOP)的基本思想非常简单,说不定你可能已在有限场合下用过这种技术了。所谓对象不过是数据的集合,而这些数据又千丝万缕地联系在一起。不妨考虑下面的例子:假设某个哈希散列装载的是说明球类特性的数据,这样哈希散列的键(key)就可能牵扯到球的颜色、直径以及制造材料等。而OOP的方法(method)只是处理每个球类数据的哈希散列子程序,这种子程序在操作每个球有关数据时会采用相应的定义字段。
什么是哈希散列?
小型的哈希散列基本上不会占用什么内存,对系统的性能不会有大的影响,你完全可以放心地用它们把对象数据归拢到一起来。如果你不知道Per语言中的l哈希数组(也叫作联合数组),那你可没好好利用Perl。普通的数组结构按照数据的位置命名单个条目;而在哈希数组里,你能给条目命名(叫作键:key)。其实不妨把哈希散列想象为一个小数据库。给出一个名字就可以通过它查出一条记录。Perl编程时在命令行上运行“perldoc
perldata”可以查阅Perl数据类型和结构的有关文档。
OOP不仅仅只把你的数据和子程序组织为互相关联的集合,它还保证了对象及其方法实际连接的编译和运行(runtime)时。那样,你就不必直接调用哈希数组的ball_volume值了。OOP语言还进一步的提供了莫大的好处,OOP语言简化了编程句法而且为声明复杂的、对象-对象关系提供了大量的其它特性。
在最简单的情况下,每个对象都会告诉Perl它是什么种类的对象,这样,只有知道如何安全地操作该对象的子程序才会被调用。开发人员则只需使用方法的名字即可。如果你调用book对象的volume值,它会告诉你目前该数值该图书数据中的位置而不会告诉你它真正占用了多少体积空间。
习惯 #1 :使用哈希散列
请把相关的数据通过小哈希散列收集起来。以前你可能创建过诸如$red、$green以及$blue之类的一整套变量。但不久你就认识到你需要2或3个集合把这些变量修改为$a_red、$b_red、$c_red来区别不同对象的属性,对绿色(green)和蓝色(blue)变量也同样如此。所以请把这9个变量修改为% a_color、% b_color和%c_color的3个哈希散列,而把r、g和b选作参数。
在CPAN内,几乎每一个模块都封装成了哈希散列。把成组关联的数据包含在哈希散列内是一种优秀的面向对象编程技术。这样做的话你声明的变量就少多了,数据也组织得更为合理。同时还提高了可靠性,因为诸如$boy{height}之类的变量实际上自身就包含了明显的含义。清单A即是一例。
习惯 #2 :使用子程序
下一个好习惯是使用子程序来围绕那些数据集合组织你的代码。尽量地把哈希散列上成块代码分组到子程序里。保证你传递的是集合而非单个的值。调用invert_new ( \%color )显然比调用invert_old (\$reda , \$greena , \$bluea );更合理。至少你不需要记得参数的顺序。
子程序把代码组织得更有逻辑了;程序宛如从子程序文件的头顶略过而底下的工作全然不知。可以把所有的变量都传递给子程序,重用代码就轻松多了,新的程序使用不同的全局变量,而其中某些全局变量还用于其他完全不同的用途。至少小型的子程序在调试的时候也方便多了,在这种情况下,所有你需要了解的代码刚好占一屏(参看程序清单B)。看,这有多方便!
习惯 #3 :重用
第3个良好的OOP习惯是把子程序收集起来放进一个单独的文件供以后再次使用他们。你还应该精制它们使之能用于一般用途。此外还应该在多个脚本中使用这些子程序而且对它们不断地进行调试。现在你不妨把采用某个特定哈希散列的所有的子程序都组合进一个文件,这就算走出了重用代码的第1步。
采取以上的做法只需把子程序放进某个文件,再使用的时候采用“require”关键词即可。已经不用的子程序就别这么做了;那纯粹是浪费时间。保证它们能工作就行了。清单C是一个比较不错的例子。
习惯 #4 :保护哈希散列
保护你的哈希散列。不要直接创建哈希,最好是对用来创建哈希的数据进行再次检查之后添加一个返回哈希散列索引的子程序。然后,再添加一些微小的子程序返回哈希散列中的各个值以便安全地修改它们。这些代码示例如清单D所示。
这样处理小子程序,可以让你在改变规则的时候可以更容易找出错误所在。所以,不要在程序中编写那些修改哈希散列的代码,你应该把这些代码移到函数库中去。
益处
以上这些建议归根结底就是一句话:哈希散列把数据关联了起来,编写采用整个哈希散列的子程序,把联系某一哈希散列的子程序收集到一个简单的库内,保护你的哈希散列库。这些小技巧几乎没有增加什么工作量但却具有极好的组织性。但这些工作在你创建面向对象的模块时占了90%以上的比重。
如果你保证哈希索引首先发送给了每个子程序。而且你只通过库函数同哈希散列内部打交道,那么你基本上只需要为你的模块起个名字即可。这样就让 Perl 知道它应该把你的哈希散列当作一个对象。你的代码库要变成模块甚至很可能不需要20行代码。