PHP设计模式笔记:使用PHP实现装饰模式

PHP设计模式笔记:使用PHP实现装饰模式

【意图】
动态的给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活【GOF95】
装饰模式是以对客户透明的方式动态地给一个对象附加上更多的职责。这也就是说,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。

【装饰模式结构图】

装饰模式

装饰模式

【装饰模式中主要角色】
抽象构件(Component)角色:定义一个对象接口,以规范准备接收附加职责的对象,从而可以给这些对象动态地添加职责。
具体构件(Concrete Component)角色:定义一个将要接收附加职责的类。
装饰(Decorator)角色:持有一个指向Component对象的指针,并定义一个与Component接口一致的接口。
具体装饰(Concrete Decorator)角色:负责给构件对象增加附加的职责。

【装饰模式的优缺点】
装饰模式的优点:
1、比静态继承更灵活;
2、避免在层次结构高层的类有太多的特征
装饰模式的缺点:
1、使用装饰模式会产生比使用继承关系更多的对象。并且这些对象看上去都很想像,从而使得查错变得困难。

【装饰模式适用场景】
1、在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
2、处理那些可以撤消的职责,即需要动态的给一个对象添加功能并且这些功能是可以动态的撤消的。
3、当不能彩生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

【装饰模式与其它模式】

【装饰模式PHP示例】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
 
 
<?php
/**
 * 装饰模式 2010-06-03 sz
 * @author phppan.p#gmail.com
 * http://www.phppan.com 哥学社成员(http://www.blog-brother.com/)
 * @package design pattern
 */
 
/**
 * 抽象构件角色
 */
interface Component {
    /**
     * 示例方法
     */
    public function operation();
}
 
/**
 * 装饰角色
 */
abstract class Decorator implements Component{
 
    protected  $_component;
 
    public function __construct(Component $component) {
        $this->_component = $component;
    }
 
    public function operation() {
        $this->_component->operation();
    }
}
 
/**
 * 具体装饰类A
 */
class ConcreteDecoratorA extends Decorator {
    public function __construct(Component $component) {
        parent::__construct($component);
 
    }
 
    public function operation() {
        parent::operation();    //  调用装饰类的操作
        $this->addedOperationA();   //  新增加的操作
    }
 
    /**
     * 新增加的操作A,即装饰上的功能
     */
    public function addedOperationA() {
        echo 'Add Operation A <br />';
    }
}
 
/**
 * 具体装饰类B
 */
class ConcreteDecoratorB extends Decorator {
    public function __construct(Component $component) {
        parent::__construct($component);
 
    }
 
    public function operation() {
        parent::operation();
        $this->addedOperationB();
    }
 
    /**
     * 新增加的操作B,即装饰上的功能
     */
    public function addedOperationB() {
        echo 'Add Operation B <br />';
    }
}
 
/**
 * 具体构件
 */
class ConcreteComponent implements Component{
 
    public function operation() {
        echo 'Concrete Component operation <br />';
    }
 
}
 
/**
 * 客户端
 */
class Client {
 
     /**
     * Main program.
     */
    public static function main() {
        $component = new ConcreteComponent();
        $decoratorA = new ConcreteDecoratorA($component);
        $decoratorB = new ConcreteDecoratorB($decoratorA);
 
        $decoratorA->operation();
        $decoratorB->operation();
    }
 
}
 
Client::main();
?>

从以上示例可以看出:
1、装饰类中有一个属性$_component,其数据类型是Component;
2、装饰类实现了Component接口;
3、接口的实现是委派给父类,但并不是单纯的委派,还有功能的增强;
4、具体装饰类实现了抽象装饰类的operation方法。

PHP设计模式笔记:使用PHP实现装饰模式》上有6条评论

  1. Pingback引用通告: PHP设计模式笔记:使用PHP实现适配器模式 | PHP源码阅读,PHP设计模式,PHP学习笔记-胖子的空间

  2. Pingback引用通告: PHP设计模式笔记:使用PHP实现合成模式 | PHP源码阅读,PHP设计模式,PHP学习笔记-胖子的空间

  3. 吴书波

    public function __construct(Component $component) {
    $this->_component = $component;
    }
    我是一个php爱好者,最近想了解设计模式,看到你有设计模式的分析,就投入的看了,但是看到这里有些不明白,这样的用法,有劳说说这样的用法。

    回复
  4. 吴书波

    具体构件(Concrete Component)角色:定义一个将要接收附加职责的类。
    这个类 没有看明白是什么意思。对于装饰模式,类的用法中最主要注意那几点。能指出下吗?真心没有看明白这个设计模式。

    回复

吴书波进行回复 取消回复

电子邮件地址不会被公开。 必填项已用*标注


*

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>