装饰器模式,可以动态地添加修改类的功能。

一个类提供了一项功能,如果要修改并添加额外的功能,传统的编程模式需要写一个子类继承它,并重新实现类的方法。使用装饰器模式,仅需要在运行时添加一个装饰器对象即可实现,可以实现最大的灵活性。

DrawDecorator.php
<?php
namespace Baobab;
/**
* Interface DrawDecorator
* @package Baobab
* 装饰器接口,定义两个方法,渲染画布之前和之后可添加额外的能力
*/
interface DrawDecorator{
function beforeDraw();
function afterDraw();
}
Canvas.php
<?php
namespace Baobab;

/**
*Canvas类,绘制图形
**/
class Canvas
{
public $data;
protected $decorators = array(); //Decorator
function init($width = 20, $height = 10)
{
$data = array();
for($i = 0; $i < $height; $i++)
{
for($j = 0; $j < $width; $j++)
{
$data[$i][$j] = '*';
}
}
$this->data = $data;
} function addDecorator(DrawDecorator $decorator){
$this->decorators[] = $decorator;
} function beforeDraw(){
foreach($this->decorators as $decorator){
$decorator->beforeDraw();
}
} function afterDraw(){
$decorators = array_reverse($this->decorators);
foreach($decorators as $decorator){
$decorator->afterDraw();
}
}
function draw()
{
$this->beforeDraw();
foreach($this->data as $line)
{
foreach($line as $char)
{
echo $char;
}
echo "<br />\n";
}
$this->afterDraw();
} function rect($a1, $a2, $b1, $b2)
{
foreach($this->data as $k1 => $line)
{
if ($k1 < $a1 or $k1 > $a2) continue;
foreach($line as $k2 => $char)
{
if ($k2 < $b1 or $k2 > $b2) continue;
$this->data[$k1][$k2] = '&nbsp;';
}
}
}
}
ColorDrawDecorator.php
<?php
namespace Baobab;
/**
*修改图形颜色的装饰器
*/
class ColorDrawDecorator implements \Baobab\DrawDecorator{
protected $color;
function __construct($color = 'black'){
$this->color = $color;
} function beforeDraw(){
echo "<div style='color: {$this->color};'>";
}
function afterDraw(){
echo "</div>";
}
}
SizeDrawDecorator.php
<?php
namespace Baobab;
/**
*修改图形大小的装饰器
*/ class SizeDrawDecorator implements \Baobab\DrawDecorator{
protected $size;
function __construct($size = '12px'){
$this->size = $size;
} function beforeDraw()
{
echo "<div style='font-size: {$this->size};'>";
}
function afterDraw()
{
echo "</div>";
}
}

index.php

$canvas = new Baobab\Canvas();
$canvas->init();
$canvas->rect(3, 6,4,12); $canvas->addDecorator(new \Baobab\ColorDrawDecorator('blue'));
$canvas->addDecorator(new \Baobab\SizeDrawDecorator('10px'));
......
//可添加其他更多装饰器
$canvas->draw();

最新文章

  1. zookeeper能做什么?
  2. viewport ——视区概念,为 自适应网页设计
  3. RCNN 和SPPnet的对比
  4. 关于ZIP大文件压缩
  5. 网络(一),libevent客户端部分
  6. php基础知识总结
  7. C#实现对mongoDB的简单增删查改
  8. Cocos2dx 3.1.1 学习笔记整理(3):逐帧动画
  9. ch3-form(get/post) $.ajax(get/post)
  10. RabbitMQ之发布订阅
  11. ffmpeg相关函数整理
  12. c/c++ 继承与多态 容器与继承3
  13. 关于eclipse从svn导入项目
  14. 2019 年 SpreadJS产品路线图(Roadmap)
  15. 1458 Common Subsequence
  16. CentOS7.5下安装Mycat连接MySQL8.0
  17. nginx windown命令
  18. Mybatis系列(三):Mybatis实现关联表查询
  19. c# List 所有操作方法例子
  20. 小论“Boolean参数作为入参”的函数

热门文章

  1. 如何在程序中给word文档加上标和下标
  2. TSQL查询45道题
  3. SQL Server在哪里存放DMV的数据?
  4. 淘宝购物车页面 智能搜索框Ajax异步加载数据
  5. iOS学习笔记——AutoLayout的约束
  6. 把cookie以json形式返回,用js来set cookie.(解决手机浏览器未知情况下获取不到cookie)
  7. form表单提交数据
  8. Lind.DDD~实体属性变更追踪器的实现
  9. ImFire即时通讯系统构建(前言)
  10. javascript的列表切换