创建工厂来简化对象的创建过程
让我们为Color类增加一个工厂,使得建立新的实例更简单。增加一个可以命名颜色的方法,这样就可以不记颜色数值,只需要记住自己喜欢的颜色名字。
工厂对象或函数不一定都要被命名为 “工厂”。 当你读代码时,工厂是显而易见的。 相反的,它的名字最好取得有意义,这样可以反映出它解决了什么问题。
在这个代码例子中, 我要叫它CrayonBox颜色工厂。静态的方法CrayonBox::getColor()引入命名颜色的字符串后,返回一个带有相应颜色属性的Color类。
下面的例子就可以测试这一点:
function TestGetColor() { $this->assertIsA($o =& CrayonBox::getColor(‘red’), ‘Color’); $this->assertEqual(‘#FF0000’, $o->getRgb()); $this->assertIsA($o =& CrayonBox::getColor(‘LIME’), ‘Color’); $this->assertEqual(‘#00FF00’, $o->getRgb()); }
通过这个测试,我们发现每个返回的对象都是一个实例化的Color类,getRgb() 方法也返回了正确的结果。第一种情况是以“red”都是小写测试,第二种情况是以“LIME”都是大写测试,这样可以测试代码的通用性。
保险起见, 我们再对其进行另外的测试,探究那些不合法的边界情况。TestBadColor() 方法的作用是:用一个不存在的颜色名字引发一个包含这个颜色名字的php错误,并返回黑色。
function TestBadColor() { $this->assertIsA($o =& CrayonBox::getColor(‘Lemon’), ‘Color’); $this->assertErrorPattern(‘/lemon/i’); // got black instead $this->assertEqual(‘#000000’, $o->getRgb()); }
以下是一个可以满足测试的CrayonBox类:
class CrayonBox { /** * Return valid colors as color name => array(red, green, blue) * * Note the array is returned from function call * because we want to have getColor able to be called statically * so we can’t have instance variables to store the array * @return array */ function colorList() { return array( ‘black’ => array(0, 0, 0) ,’green’ => array(0, 128, 0) // the rest of the colors ... ,’aqua’ => array(0, 255, 255) ); } /** * Factory method to return a Color * @param string $color_name the name of the desired color * @return Color */ function &getColor($color_name) { $color_name = strtolower($color_name); if (array_key_exists($color_name, $colors = CrayonBox::colorList())) { $color = $colors[$color_name]; return new Color($color[0], $color[1], $color[2]); } trigger_error(“No color ‘$color_name’ available”); // default to black return new Color; }
这显然地是一个非常简单的工厂, 它确实制造了单一化的对象(使用了颜色名字,而不是RGB数值) ,它展示了在新的对象被调用之前,是如何建立一个内部对象的。
出处:
责任编辑:bluehearts
上一页 php设计模式介绍之工厂模式 [4] 下一页 php设计模式介绍之工厂模式 [6]
◎进入论坛网络编程版块参加讨论
|