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


/**
* 短信抽象类
*
* 定义算法结构
* 明确算法执行顺序
*/
abstract class Sms
{
/**
* 运营商配置
* @var string
*/
protected $_config = [];

/**
* 短信文本
* @var string
*/
protected $_text = '[xx公司]你好,你的验证码是';

/**
* 构造函数
*
* @param array $config 运营商配置
*/
final function __construct($config=[])
{
// 初始化配置
$this->initialize($config);
}

/**
* 初始化运营商配置
*
* 每个厂商的配置不一定相同,所以子类复写这个方法即可
*
* @param array $config 运营商配置
* @return void
*/
abstract function initialize($config=[]);

/**
* 生成短信文本
*
* 短信模板和厂商无关
*
* @return void
*/
function makeText()
{
$this->_text .= rand(000000, 999999);
}

/**
* 厂商发送短信方法
*
* 每个厂商复写这个方法即可
*
* @param integer $mobile 手机号
* @return void
*/
abstract function sendSms($mobile=0);

/**
* 发送短信
*
* 最终调用的方法,明确了算法顺序
*
* @param integer $mobile 手机号
* @return void
*/
final function send($mobile=0)
{
// 生成文本
$this->makeText();
// 发送短信
$this->sendSms($mobile);
}

}

/**
* 某厂商one
*/
class SmsCompanyOne extends Sms
{

/**
* 初始化运营商配置
*
* 每个厂商的配置不一定相同,所以子类复写这个方法即可
*
* @param array $config 运营商配置
* @return void
*/
function initialize($config=[])
{
// 实现具体算法
$this->_config = $config;
}

/**
* 厂商发送短信方法
*
* 每个厂商复写这个方法即可
*
* @param integer $mobile 手机号
* @return void
*/
function sendSms($mobile=0)
{
// 实现具体的短信发送方法
echo "厂商‘one’给手机号{$mobile}发送了短信:{$this->_text} \n";
}

}

/**
* 某厂商two
*/
class SmsCompanyTwo extends Sms
{

/**
* 初始化运营商配置
*
* 每个厂商的配置不一定相同,所以子类复写这个方法即可
*
* @param array $config 运营商配置
* @return void
*/
function initialize($config=[])
{
// 实现具体算法
$this->_config = $config;
}

/**
* 厂商发送短信方法
*
* 每个厂商复写这个方法即可
*
* @param integer $mobile 手机号
* @return void
*/
function sendSms($mobile=0)
{
// 实现具体的短信发送方法
echo "厂商‘two’给手机号{$mobile}发送了短信:{$this->_text} \n";
}

}


try {
// 用厂商one发短信
$one = new SmsCompanyOne([
'appkey' => 'akjlooolllnn',
]);
$one->send('13666666666');

// 用厂商two发短息
$one = new SmsCompanyTwo([
'pwd' => 'adadeooonn',
]);
$one->send('13666666666');

} catch (\Exception $e) {
echo 'error:' . $e->getMessage();
}