php教程:php设计模式介绍之策略模式(4)
现在,构造函数增加了第二个可选的参数用来确定第一个参数的数据类型是数字类型还是字符串。这个类的最终形式变为请看下面代码,包括了一个‘serialize’ 用来存储数据、对象等复杂数据的存储类型。
class VarCache {
var $_name;
var $_type;
function VarCache($name, $type=’serialize’) {
$this->_name = ‘cache/’.$name;
$this->_type = $type;
}
function isValid() {
return file_exists($this->_name.’.php’);
}
function get() {
if ($this->isValid()) {
include $this->_name.’.php’;
return $cached_content;
}
}
function _getTemplate() {
$template = ‘<?php $cached_content = ‘;
switch ($this->_type) {
case ‘string’:
$template .= “‘%s’;”;
break;
case ‘serialize’:
$template .= “unserialize(stripslashes(‘%s’));”;
break;
case ‘numeric’:
$template .= ‘%s;’;
break;
default:
trigger_error(‘invalid cache type’);
}
return $template;
}
function set($value) {
$file_handle = fopen($this->_name.’.php’, ‘w’);
switch ($this->_type) {
case ‘string’:
$content = sprintf($this->_getTemplate()
,str_replace(“‘“,”\\’”,$value));
break;
case ‘serialize’:
$content = sprintf($this->_getTemplate()
,addslashes(serialize($value)));
break;
case ‘numeric’:
$content = sprintf($this->_getTemplate()
,(float)$value);
break;
default:
trigger_error(‘invalid cache type’);
}
fwrite($file_handle, $content);
The Strategy Pattern 131
fclose($file_handle);
}
}
请注意_getTemplate()和set() 函数中的case判断语句。它们都是基于同一个$_type 实例参数的。get() 函数中却没有受到$_type的影响,所以看起来因为存储的数据类型的变化只影响到数据的存储过程。同时,多重的case条件判断也是一个提示,这个地方如果使用了策略的设计模式会更好。
样本代码
从一个多重的switch 条件判断改变到策略模式是一个条件分解实例的经典例子。整个测试的环境没有变化;只是VarCache类的内部改变了。
首先我们把你想要封装在一个独立的类的各种情况分隔出来。就前面的例子来说,你有三种变化的情况需要进行考虑:‘string’, ‘numeric’, 和第三个‘serialize’。前面的例子中还在对象实例化的时候选择了数据输出的格式。基于这个运算法则,你需要创建一个API来封装它。