WebjxCom提示:在面向对象
编程中,最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的
。但是在一些情况下,new操作符直接生成对象会带来一些问题
。举例来说,许多类型对象的创造需要一系列的步骤:你可能需要计算或取得对象的初始设置;选择生成哪个子对象
例子:增加一些颜色
让我们更深入工厂模式吧。继续如前
,先建立一个能为本章节的其它部分持续举例说明的简单类。这是一个输出十六进制的HTMLRGBColor类
,包括了R,G,和B三个属性(在构造对象的时候引入)和getRgb()方法,getRgb()的作用是返回一个十六进制颜色的字符串。
和以前一样,我们按照测试驱动开发(TDD)的方法:写一个测试,再写一段代码满足该测试,如果需要,反复下去。
下面是一个非常简单的起始测试:
functionTestInstantiate(){
$this->assertIsA($color=newColor,‘Color’);
$this->assertTrue(method_exists($color,‘getRgb’));
}
为了满足这个测试,你可以设计这样一个类。测试看起来有点像伪代码:
classColor{
functiongetRgb(){}
}
(这个Color类也许看起来像处于娃娃阶段,但是TDD是一个反复的过程。代码非常少,当需要的时候:你开始有了新的想法或者想精确的执行代码时,可以增加的。)
接下来,当颜色对象被建立时,getRgb()方法应该返回以红色,绿色,和蓝色的十六进制字符串。用一个测试说明一下:
functionTestGetRgbWhite(){
$white=&newColor(255,255,255);
$this->assertEqual(‘#FFFFFF’,$white->getRgb());
}
每个TDD,你写最简单的可行的代码来满足测试,并不需要满足人的审美观或者代码的正确执行。
下面是最简单的,能够通过测试的代码:
classColor{
functiongetRgb(){return‘#FFFFFF’;}
}
这个Color类不是令人十分满意,但是它确实表现了逐渐增加的过程。
下一步,让我们增加一个额外的测试使这个Color类的的确确地执行并返回正确的信息:
functionTestGetRgbRed(){
$red=&newColor(255,0,0);
$this->assertEqual(‘#FF0000’,$red->getRgb());
}
这个Color类必须改变什么呢?首先必须把红色,绿色,和蓝色的值储存在三个变量里,然后在调用一个方法把十进制数转化为十六进制数。按照这个要求执行的代码可以写作:
classColor{
var$r=0;
var$g=0;
var$b=0;
functionColor($red=0,$green=0,$blue=0)
{
$this->r=$red;
$this->g=$green;
$this->b=$blue;
}
functiongetRgb(){
returnsprintf(‘#%02X%02X%02X’,$this->r,$this->g,$this->b);
}
}
这个构造非常简单:先收集红色,绿色,和蓝色的数值,然后储存在变量中,getRgb()方法使用sprintf()函数将十进制数转换成十六进制数。
为了对代码充满更多的信心,你可以用较多的数值来测试它。这一个测试可以用以下代码实现:
functionTestGetRgbRandom(){
$color=&newColor(rand(0,255),rand(0,255),rand(0,255));
$this->assertWantedPattern(
‘/^#[0-9A-F]{6}$/’,
$color->getRgb());
$color2=&newColor($t=rand(0,255),$t,$t);
$this->assertWantedPattern(
‘/^#([0-9A-F]{2})11$/’,
$color2->getRgb());
}
注:assertWantedPattern
assertWantedPattern()作用是:使它的第二个叁数匹配第一个参数,第一个参数是正则表达式。如果匹配,这个测试就通过;否则不通过。
由于assertWantedPattern()具有进行正确的正则表达式匹配的功能,所以常被用作测试。