接着问题来了,在上一节中我们只是存储了字符串到mylog.txt.那么我们现在想以html或者xml的形式分别存储在mylog.html和mylog.xml中要怎么办呢。
首先在temp中建立mylog.html和mylog.xml
首先我们要先规定一个接口,规定一个方法format(),用于生成string、xml、html形式的log信息。
interface iFormatter {
public function format();
}
有了这个接口我们就可以生成具体的实现类,每一个实现类都要实现format()方法。
每一种策略的具体表现形式……
class Formatter_String implements iFormatter {
public function format($message) {
return $message.PHP_EOL;
}
}
class Formatter_XML implements iFormatter {
public function format($message) {
$timestamp = time();
// heredoc string syntax
$xml = <<<XML_EOL
<message>
<time>$timestamp</time>
<text>$message</text>
</message>
XML_EOL;
return $xml.PHP_EOL;
}
}
class Formatter_HTML implements iFormatter {
public function format($message) {
$timestamp = time();
// heredoc string syntax
$html = <<<HTML_EOL
<p>
<b>Timestamp:</b> $timestamp
<br />
<b>Message:</b> $message
</p>
HTML_EOL;
return $html.PHP_EOL;
}
}
现在可以写一个测试类,去测试每一种格式化信息的输出。不过这样测试类与具体的实现有了一种耦合的关系。这不是编程所希望的--高内聚,低耦合。
让我们来定义一个上下文的类,让它与客户端代码进行交互。也是上节中我们的logger类
代码如下表示(这里也是策略模式实现的地方,要仔细看哦。):
class Logger{
protected $formatter;
private $file = null;
protected function __constructfo($formatter, $file) {
if($formatter instanceof iFormatter)//这里也显示了我们要定义一个接口的必要性。
{
$this->formatter = $formatter;
$this->file = $file;
}
else
{
trigger_error('Invalid Formatter!', E_USER_ERROR);
}
}
public function write($message) {
$formatted_message = $this->formatter->format($message);
file_put_contents($this->file, $formatted_message, FILE_APPEND);
}
}
要仔细阅读以上代码。其实并不难有不懂的可以留言。
下面我们就可以来测试一下:
$logger = new Logger_File(new Formatter_XML(), './tmp/mylog.xml');
$logger->write('I am an XML formatted log message!');
OK,到这里我们通过策略模式去实现了格式化不同的形式存储在了本地,下一节我们要继续用策略模式去把所有格式化的信息既可以存储在本地有可以存储在数据库里。。
未完待续……(有不明白的地方请留言……)