设计模式(三):观察者模式、适配器模式

0

常用的几个设计模式基本已经学完了。

1 观察者模式

将客户元素(观察者)从一个中心类(主体)中分离出来,当主体知道时间发生时,观察者需要被通知到。

也叫 发布-订阅模式

实现

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
// demo
// 主体接口
interface Subject {
public function attach(Observer $observer); // 添加观察者
public function detach(Observer $observer); // 删除观察者
public function notify(); // 状态变更通知回调
}
class TestSubject implements Subject {
private $_observers;
function __construct () {
$this->_observers = array();
}
public function attach(Observer $observer) {
return array_push($this->_observers, $observer);
}
public function detach(Observer $observer) {
$index = array_search($observer, $this->_observers);
if ($index === FALSE || ! array_key_exists($index, $this->_observers)) {
return FALSE;
}
unset($this->_observers[$index]);
return TRUE;
}
public function notify() {
if (!is_array($this->_observers)) {
return FALSE;
}
foreach ($this->_observers as $observer) {
$observer->update();
}
return TRUE;
}
}
// 观察者接口
interface Observer {
function update();
}
class TestObserver implements Observer{
private $_name; // 观察者名称
public function __construct($name) {
$this->_name = $name;
}
// 告诉观察者需要干啥
function update() {
echo "Observer $this->_name has notified.\n";
}
}
//实例化类:
$subject = new Subject();
// 添加第一个观察者
$observer1 = new Observer('Martin');
$subject->attach($observer1);
echo PHP_EOL.'The First notify:'.PHP_EOL;
$subject->notifyObservers();
// 添加第二个观察者
$observer2 = new Observer('phppan');
$subject->attach($observer2);
echo PHP_EOL.'The Second notify:'.PHP_EOL;
$subject->notifyObservers();
// 删除第一个观察者
$subject->detach($observer1);
echo "\nThe Third notify:\n";
$subject->notifyObservers();

2 适配器模式

适配器模式将一个类的接口转换成另一个接口,暴露新增加的接口,但是不改变原有接口。

实现

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
// demo
// 接口类
interface ITarget
{
function operation1();
function operation2();
}
interface IAdaptee
{
function operation1();
}
class Adaptee implements IAdaptee
{
public function operation1()
{
echo "原方法";
}
}
class Adapter implements ITarget
{
private $adaptee;
public function __construct(Adaptee $adaptee)
{
$this->adaptee = $adaptee;
}
public function operation1()
{
return $this->adaptee->operation1();
}
public function operation2()
{
echo "适配方法";
}
}
$adapter = new Adapter(new Adaptee(null));
$adapter->operation1();//原方法
$adapter->operation2();//适配方法

适配器模式与装饰模式都是为原类进行包装,但不同的是装饰模式是在原类的基础上对接口进行添加行为。而适配器模式是将原类包装后对外表现出新的接口,从而不需要改变原来类的代码。