分类目录归档:PHP

PHP源码,PHP扩展,PHP程序

PHP设计模式笔记:使用PHP实现门面模式

PHP设计模式笔记:使用PHP实现门面模式

【意图】
为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层次的接口,使得子系统更加容易使用【GOF95】
外部与子系统的通信是通过一个门面(Facade)对象进行。

【门面模式结构图】

门面模式

门面模式

【门面模式中主要角色】
门面(Facade)角色:
此角色将被客户端调用
知道哪些子系统负责处理请求
将用户的请求指派给适当的子系统

子系统(subsystem)角色:
实现子系统的功能
处理由Facade对象指派的任务
没有Facade的相关信息,可以被客户端直接调用
可以同时有一个或多个子系统,每个子系统都不是一个单独的类,而一个类的集合。每个子系统都可以被客户端直接调用,或者被门面角色调用。子系统并知道门面模式的存在,对于子系统而言,门面仅仅是另一个客户端。

【门面模式的优点】
1、它对客户屏蔽了子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便
2、实现了子系统与客户之间的松耦合关系
3、如果应用需要,它并不限制它们使用子系统类。因此可以在系统易用性与能用性之间加以选择

【门面模式适用场景】
1、为一些复杂的子系统提供一组接口
2、提高子系统的独立性
3、在层次化结构中,可以使用门面模式定义系统的每一层的接口

【门面模式与其它模式】
抽象工厂模式(abstract factory模式):Abstract Factory模式可以与Facade模式一起使用以提供一个接口,这一接口可用来以一种子系统独立的方式创建子系统对象。Abstract Factory模式也可以代替Facade模式隐藏那些与平台相关的类
调停者模式:Mediator模式与Facade模式的相似之处是,它抽象了一些已有类的功能。然而,Mediator目的是对同事之间的任意通讯进行抽象,通常集中不属于任何单个对象的功能。Mediator的同事对象知道中介者并与它通信,而不是直接与其他同类对象通信。相对而言,Facade模式仅对子系统对象的接口进行抽象,从而使它们更容易使用;它并定义不功能,子系统也不知道facade的存在
单例模式(singleton模式):一般来说,仅需要一个Facade对象,因此Facade对象通常属于Singleton对象。

【门面模式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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
 
<?php
/**
 * 门面模式 2010-06-12 sz
 * 《Java与模式》上门面模式示例的PHP版本
 * @author phppan.p#gmail.com  http://www.phppan.com
 * 哥学社成员(http://www.blog-brother.com/)
 * @package design pattern
 */
 
class Camera {
 
    /**
     * 打开录像机
     */
    public function turnOn() {
        echo 'Turning on the camera.<br />';
    }
 
    /**
     * 关闭录像机
     */
    public function turnOff() {
        echo 'Turning off the camera.<br />';
    }
 
    /**
     * 转到录像机
     * @param <type> $degrees
     */
    public function rotate($degrees) {
        echo 'rotating the camera by ', $degrees, ' degrees.<br />';
    }
}
 
class Light {
 
    /**
     * 开灯
     */
    public function turnOn() {
        echo 'Turning on the light.<br />';
    }
 
    /**
     * 关灯
     */
    public function turnOff() {
        echo 'Turning off the light.<br />';
    }
 
    /**
     * 换灯泡
     */
    public function changeBulb() {
        echo 'changing the light-bulb.<br />';
    }
}
 
class Sensor {
 
    /**
     * 启动感应器
     */
    public function activate() {
        echo 'Activating the sensor.<br />';
    }
 
    /**
     * 关闭感应器
     */
    public function deactivate() {
        echo 'Deactivating the sensor.<br />';
    }
 
    /**
     * 触发感应器
     */
    public function trigger() {
        echo 'The sensor has been trigged.<br />';
    }
}
 
class Alarm {
 
    /**
     * 启动警报器
     */
    public function activate() {
        echo 'Activating the alarm.<br />';
    }
 
    /**
     * 关闭警报器
     */
    public function deactivate() {
        echo 'Deactivating the alarm.<br />';
    }
 
    /**
     * 拉响警报器
     */
    public function ring() {
        echo 'Ring the alarm.<br />';
    }
 
    /**
     * 停掉警报器
     */
    public function stopRing() {
        echo 'Stop the alarm.<br />';
    }
}
 
/**
 * 门面类
 */
class SecurityFacade {
 
    /* 录像机 */
    private $_camera1, $_camera2;
 
    /* 灯 */
    private $_light1, $_light2, $_light3;
 
    /* 感应器 */
    private $_sensor;
 
    /* 警报器 */
    private $_alarm;
 
    public function __construct() {
        $this->_camera1 = new Camera();
        $this->_camera2 = new Camera();
 
        $this->_light1 = new Light();
        $this->_light2 = new Light();
        $this->_light3 = new Light();
 
        $this->_sensor = new Sensor();
        $this->_alarm = new Alarm();
    }
 
    public function activate() {
        $this->_camera1->turnOn();
        $this->_camera2->turnOn();
 
        $this->_light1->turnOn();
        $this->_light2->turnOn();
        $this->_light3->turnOn();
 
        $this->_sensor->activate();
        $this->_alarm->activate();
    }
 
    public  function deactivate() {
        $this->_camera1->turnOff();
        $this->_camera2->turnOff();
 
        $this->_light1->turnOff();
        $this->_light2->turnOff();
        $this->_light3->turnOff();
 
        $this->_sensor->deactivate();
        $this->_alarm->deactivate();
    }
}
 
 
/**
 * 客户端
 */
class Client {
 
    private static $_security;
     /**
     * Main program.
     */
    public static function main() {
        self::$_security = new SecurityFacade();
        self::$_security->activate();
    }
}
 
Client::main();
?>

PHP设计模式笔记:使用PHP实现单例模式

PHP设计模式笔记:使用PHP实现单例模式

【意图】
保证一个类仅有一个实例,并且提供一个访问它的全局访问点【GOF95】
单例模式有三个特点:
1、一个类只有一个实例
2、它必须自行创建这个实例
3、必须自行向整个系统提供这个实例

【单例模式结构图】

单例模式

单例模式

【单例模式中主要角色】
Singleton 定义一个Instance操作,允许客户访问它的唯一实例。Instance是一个类方法。负责创建它的唯一的实例。

【单例模式的优点】
1、对唯一实例的受控访问
2、缩小命名空间 单例模式是对全局变量的一种改进。它避免了那些存储唯一实例的全局变量污染命名空间
3、允许对操作和表示的精华 单例类可以有子类。而且用这个扩展类的实例来配置一个应用是很容易的。你可以用你所需要的类的实例在运行时刻配置应用。
4、允许可变数目的实例(多例模式)
5、比类操作更灵活

【单例模式适用场景】
1、当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
2、当这个唯一实例应该是通过子类化可扩展的。并且用户应该无需更改代码就能使用一个扩展的实例时。

【单例模式与其它模式】
工厂方法模式(factory method模式):单例模式使用工厂模式来提供自己的实例。
抽象工厂模式(abstract factory模式):抽象工厂模式可以使用单例模式,将具体工厂类设计成单例类。
建造者模式(Builder模式):建造模式可以将具体建造类设计成单例模式。
……

【单例模式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
<?php
/**
 * 单例模式 2010-06-06 sz
 * @author phppan.p#gmail.com  http://www.phppan.com
 * 哥学社成员(http://www.blog-brother.com/)
 * @package design pattern
 */
 
/**
 * 懒汉式单例类
 */
class Singleton {
 
    /**
     * 静态成品变量 保存全局实例
     */
    private static  $_instance = NULL;
 
    /**
     * 私有化默认构造方法,保证外界无法直接实例化
     */
    private function __construct() {
    }
 
    /**
     * 静态工厂方法,返还此类的唯一实例
     */
    public static function getInstance() {
        if (is_null(self::$_instance)) {
            self::$_instance = new Singleton();
        }
 
        return self::$_instance;
    }
 
    /**
     * 防止用户克隆实例
     */
    public function __clone(){
        die('Clone is not allowed.' . E_USER_ERROR);
    }
 
    /**
     * 测试用方法
     */
    public function test() {
        echo 'Singleton Test!';
    }
 
}
 
/**
 * 客户端
 */
class Client {
 
     /**
     * Main program.
     */
    public static function main() {
        $instance = Singleton::getInstance();
        $instance->test();
    }
}
 
Client::main();
?>

PHP中不支持饿汉式的单例模式
因为PHP不支持在类定义时给类的成员变量赋予非基本类型的值。如表达式,new操作等等

PHP设计模式笔记:使用PHP实现桥梁模式

PHP设计模式笔记:使用PHP实现桥梁模式

【意图】
将抽象部分与它的实现部分分享,使它们都可以独立的变化【GOF95】

【桥梁模式结构图】

桥梁模式

桥梁模式

【桥梁模式中主要角色】
抽象化(Abstraction)角色:定义抽象类的接口并保存一个对实现化对象的引用。
修正抽象化(Refined Abstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
实现化(Implementor)角色:定义实现类的接口,不给出具体的实现。此接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以完全不同。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
具体实现化(Concrete Implementor)角色:实现实现化角色接口并定义它的具体实现。

【桥梁模式的优点】
1、分离接口及其实现部分
将Abstraction与Implementor分享有助于降低对实现部分编译时刻的依赖性
接口与实现分享有助于分层,从而产生更好的结构化系统

2、提高可扩充性

3、实现细节对客户透明。

【桥梁模式适用场景】
1、如果一个系统需要在构件的抽象化和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。
2、设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。
3、一个构件有多于一个的抽象化角色和实现化角色,并且系统需要它们之间进行动态的耦合。
4、虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。

【桥梁模式与其它模式】
抽象工厂模式(abstract factory模式):抽象工厂模式可以用来创建和配置一个特定的桥梁模式。
适配器模式(adapter模式):适配器模式用来帮助无关的类协同工作。它通常是在系统设计完成之后才会被使用。然而,桥梁模式是在系统开始时就被使用,它使得抽象接口和实现部分可以独立进行改变。
状态模式(state模式):桥梁模式描述两个等级结构之间的关系,状态模式则是描述一个对象与状态对象之间的关系。状态模式是桥梁模式的一个退化的特殊情况。

【桥梁模式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
<?php
/**
 * 桥梁模式 2010-06-06 sz
 * @author phppan.p#gmail.com  http://www.phppan.com
 * 哥学社成员(http://www.blog-brother.com/)
 * @package design pattern
 */
 
/**
 * 抽象化角色
 * 抽象化给出的定义,并保存一个对实现化对象的引用。
 */
abstract class Abstraction {
 
    /* 对实现化对象的引用 */
    protected $imp;
 
    /**
     * 某操作方法
     */
    public function operation() {
        $this->imp->operationImp();
    }
}
 
/**
 * 修正抽象化角色
 * 扩展抽象化角色,改变和修正父类对抽象化的定义。
 */
class RefinedAbstraction extends Abstraction {
 
     public function __construct(Implementor $imp) {
        $this->imp = $imp;
    }
 
    /**
     * 操作方法在修正抽象化角色中的实现
     */
    public function operation() {
        echo 'RefinedAbstraction operation  ';
        $this->imp->operationImp();
    }
}
 
/**
 * 实现化角色
 * 给出实现化角色的接口,但不给出具体的实现。
 */
abstract class Implementor {
 
    /**
     * 操作方法的实现化声明
     */
    abstract public function operationImp();
}
 
/**
 * 具体化角色A
 * 给出实现化角色接口的具体实现
 */
class ConcreteImplementorA extends Implementor {
 
    /**
     * 操作方法的实现化实现
     */
    public function operationImp() {
        echo 'Concrete implementor A operation <br />';
    }
}
 
/**
 * 具体化角色B
 * 给出实现化角色接口的具体实现
 */
class ConcreteImplementorB extends Implementor {
 
    /**
     * 操作方法的实现化实现
     */
    public function operationImp() {
        echo 'Concrete implementor B operation <br />';
    }
}
 
/**
 * 客户端
 */
class Client {
 
     /**
     * Main program.
     */
    public static function main() {
        $abstraction = new RefinedAbstraction(new ConcreteImplementorA());
        $abstraction->operation();
 
        $abstraction = new RefinedAbstraction(new ConcreteImplementorB());
        $abstraction->operation();
    }
}
 
Client::main();
?>

在写上面的代码时,就构造方法是否可以放在抽象化角色中纠结了许久!