Home > Article > Backend Development > PHP Design Pattern Decorator Pattern_PHP Tutorial
1. Decorator mode (Decorator), which can dynamically add and modify the function of a class
2. A class provides a function. If you want to modify and add additional functions, in the traditional programming mode, you need to write a subclass to inherit it and reimplement the class method
3. Using the decorator mode, you only need to add a decorator object at runtime, which can achieve maximum flexibility.
Next, let’s give an example of using PHP to implement the function of a small drawing board (drawing graphics of specified colors)
<code class="language-php" hljs=""> <!--?php class Canvas { //保存点阵的一个数组 public $data; //初始化点阵 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 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 ] = ' '; } } } //开始执行画图 function draw () { foreach ($this->data as $line) { foreach ($line as $char) { echo $char; } echo ; } } }</code>
<code class="language-php" hljs="">$canvas = new Canvas(); $canvas->init(40, 20); $canvas->rect(4,15,9,30); $canvas->draw();</code>
<code class="language-php" hljs="">**************************************** **************************************** **************************************** **************************************** **************************************** ********* ********* ********* ********* ********* ********* ********* ********* ********* ********* ********* ********* ********* ********* ********* ********* ********* ********* ********* ********* **************************************** **************************************** **************************************** **************************************** ****************************************</code>
What if I want to add the color I want to this graphic?
<code class="language-php" hljs=""> //开始执行画图 function draw () { echo </code>
; foreach ($this->data as $line) { foreach ($line as $char) { echo $char; } echo<code class="language-php" hljs="">; foreach ($this->data as $line) { foreach ($line as $char) { echo $char; } echo<br>
; } echo
; } echo ; }
1. It is hard-coded like this. If I don’t want to add color that day, but I want to make it bold or italic, then I need to modify the code, or I want to add a title on it. . . Waiting for the demand, let's use the decorator mode to modify the above code to decouple the above code!
<code class="language-php" hljs="">//画图装饰器 interface DrawDecorator { //画之前的操作 function beforeDraw(); //画之后的操作 function afterDraw(); }</code>
<code class="language-php" hljs="">class ColorDrawDecorator implements DrawDecorator { //颜色属性 protected $color; //初始化颜色 function __construct($color = 'red') { $this->color = $color; } //画之前的操作 function beforeDraw() { echo </code>
; } //画之后的操作 function afterDraw() { echo
; } }
<code class="language-php" hljs=""> class Canvas { //保存点阵的一个数组 public $data; //保存装饰器对象 protected $decorators = array(); //初始化点阵 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 ; } $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] = ' '; } } } }</code>
<code class="language-php" hljs="">$canvas = new Canvas(); //注入装饰器对象 $canvas->addDecorator(new ColorDrawDecorator('green')); $canvas->init(40, 20); $canvas->rect(4,15,9,30); $canvas->draw();</code>
Output a green rectangle
Similarly, if you also want to use bolding, italics, set custom titles, etc., just create a specific decorator and inject it into the canvas.
1. The decorator is to add some of your customized operations before performing a specific operation
2. The implementation of decorators is like a hook mechanism, such as the hook mechanism in drupal
3. The decorator mechanism can also be implemented usingcall_user_func
orcall_user_func_array
. You can refer to Drupal’s hook implementation for this, which is also pretty good! I won’t introduce it here because it is not within the design pattern. I will write about it later when I have time.