中介者模式

中介者模式用于开发一个对象,这个对象能够在类似对象相互之间不直接相互的情况下传送或者调解对这些对象的集合的修改。一般处理具有类似属性,需要保持同步的非耦合对象时,最佳的做法就是中介者模式。PHP中不是特别常用的设计模式。

设计场景

我们有一个CD类和一个MP3类,两个类的结构相似。

我们需要在CD类更新的时候,同步更新MP3类。

传统的做法就是在CD类中实例化MP3类,然后去 样的MP4类,那么就没法处理了。

中介者模式很好的处理了这种情况,通过中介者类,CD类中只要调用中介者这个类,就能同步更新这些数据。

我们的phpwind论坛中,之前有用到过这个设计模式。

代码设计

 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
<?php
 
class CD
{
    public $band = '';
    public $title = '';
    protected $_mediator;
 
    public function __construct(MusicContainerMediator $mediator = null)
    {
        $this->_mediator = $mediator;
    }
 
    public function save()
    {
        //具体实现待定
        var_dump($this);
    }
 
    public function changeBandName($bandname)
    {
        if (!is_null($this->_mediator)) {
            $this->_mediator->change($this, array("band" => $bandname));
        }
        $this->band = $bandname;
        $this->save();
    }
}
 
//MP3Archive类
class MP3Archive
{
    public $band = '';
    public $title = '';
    protected $_mediator;
 
    public function __construct(MusicContainerMediator $mediator = null)
    {
        $this->_mediator = $mediator;
    }
 
    public function save()
    {
        //具体实现待定
        var_dump($this);
    }
 
    public function changeBandName($bandname)
    {
        if (!is_null($this->_mediator)) {
            $this->_mediator->change($this, array("band" => $bandname));
        }
        $this->band = $bandname;
        $this->save();
    }
 
}
 
//中介者类
class MusicContainerMediator
{
    protected $_containers = array();
 
    public function __construct()
    {
        $this->_containers[] = "CD";
        $this->_containers[] = "MP3Archive";
    }
 
    public function change($originalObject, $newValue)
    {
        $title = $originalObject->title;
        $band = $originalObject->band;
        foreach ($this->_containers as $container) {
            if (!($originalObject instanceof $container)) {
                $object = new $container;
                $object->title = $title;
                $object->band = $band;
                foreach ($newValue as $key => $val) {
                    $object->$key = $val;
                }
                $object->save();
            }
        }
    }
}
 
//测试实例
$titleFromDB = "Waste of a Rib";
$bandFromDB = "Never Again";
$mediator = new MusicContainerMediator();
$cd = new CD($mediator);
$cd->title = $titleFromDB;
$cd->band = $bandFromDB;
var_dump($cd);
$cd->changeBandName("Maybe Once More");