<?php
require_once('Display.php');
require_once('StringDisplay.php');
require_once('Border.php');
require_once('SideBorder.php');
require_once('FullBorder.php');
/**
* php装饰器设计模式的客户端示例,目的:显示打印字符的装饰功能。会在浏览器输出字符串,被层层包裹
*
* 本设计模式的示例改自《设计模式 - Java语言中的应用》结城 浩著 page 156 - 163
*
* 读者机器的条件:php5,某个服务器如apache,
* 将几个程序放到服务器文档根目录下,
* 访问http://127.0.0.1/Main.php即可看到效果
*/
class TestDecorator
{
public static function main()
{
//打印“Hello,world”,没有任何装饰
$b1 = new StringDisplay('Hello, world.');
//把装饰字符'#'加在b1的左右两边
$b2 = new SideBorder($b1, '#');
//把b2加上装饰外框
$b3 = new FullBorder($b2);
//b4在核心的外面加上了多重外框
$b4 =
new SideBorder(
new FullBorder(
new FullBorder(
new SideBorder(
new FullBorder(
new StringDisplay('Hello, world.')
), '*'
)
)
), '/'
);
$b1->show();
$b2->show();
$b3->show();
$b4->show();
}
}
TestDecorator::main();
?>
Display类
<?php
/**
* 位于最顶层,表示了整个设计模式示例的功能:打印字符串
*/
abstract class Display
{
public abstract function getColumns(); //取得横向的字数,把责任委托给子类,所以抽象,下同
//观察子类可知,只要有一个类使用到了,
//需要所有的类都要有这个方法!
public abstract function getRows(); //取得纵向的行数,把责任委托给子类
public abstract function getRowText($row);//取得第row行的字符串
public function show() //因为这个方法的实现是固定的,所以写这里
{
for ($i = 0; $i < $this->getRows(); $i++) {
echo $this->getRowText($i) . "<br />";
}
}
}
?>
StringDidplay类
<?php
/**
* 注意此类一定被包裹在核心,和别的类不同,虽然都是继承Display类
*
*/
class StringDisplay extends Display
{
private $string; //最里面的,一定会被打印出的字符串
public function __construct($string) //需要在外部指定
{
$this->string = $string;
}
public function getColumns() //注意!,仅被某类调用,却写到每个类中!!
{
return strlen($this->string);
}
public function getRows() //核心只打印一行
{
return 1;
}
public function getRowText($row) //仅在row为0时才返回
{
if ($row == 0) {
return $this->string;
} else {
return null;
}
}
}
?>