PHP设计模式之中介者模式

中介者设计模式用于开发一个对象,这个对象能够在类似对象相互之间不直接交互的情况下传送或调解对这些对象的集合的修改。
比如:比如租房,房东并不需要直接和租房者沟通,而通过房租中介把自己的信息传达给所有想租房的租房者。

以卖房为例

demo1.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
<?php
header('Content-Type:text/html; charset=utf-8');

class Student{
private $name;

public function __construct($name){
$this->name = $name;
}

public function buy(){
return '学生'.$this->name.'买了一套房!';
}
}

class Teacher{
private $name;

public function __construct($name){
$this->name = $name;
}

public function buy(){
return '老师'.$this->name.'买了一套房!';
}
}

$student = new Student('suse');
echo $student->buy();

echo '<br />';

$teacher = new Teacher('tom');
echo $teacher->buy();

抽取Student和Teacher的公共信息至Buyyer

demo2.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
<?php
header('Content-Type:text/html; charset=utf-8');

abstract class Buyer{
protected $name;

public function __construct($name){
$this->name = $name;
}

abstract public function buy();
}

class Student extends Buyer{
public function buy(){
return '学生'.$this->name.'买了一套房!';
}
}

class Teacher extends Buyer{
public function buy(){
return '老师'.$this->name.'买了一套房!';
}
}

$student = new Student('suse');
echo $student->buy();

echo '<br />';

$teacher = new Teacher('tom');
echo $teacher->buy();

学生和老师买房,房东卖房

demo3.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
<?php
header('Content-Type:text/html; charset=utf-8');

abstract class Buyer{
protected $name;

public function __construct($name){
$this->name = $name;
}

abstract public function buy();
}

class Student extends Buyer{
public function buy(){
return '学生'.$this->name.'买了一套房!';
}
}

class Teacher extends Buyer{
public function buy(){
return '老师'.$this->name.'买了一套房!';
}
}

class Landlord{
private $name;
private $address;

public function __construct($name, $address){
$this->name = $name;
$this->address = $address;
}

public function sell(){
return $this->name.'在'.$this->address.'卖掉了一套房!';
}
}

$student = new Student('suse');
echo $student->buy();

echo '<br />';

$landlord = new Landlord('包租婆', '功夫村');
echo $landlord->sell();

学生和老师在房东处买房

租房系统第一版:租房者和房东各自包含对方引用

demo4.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
<?php
header('Content-Type:text/html; charset=utf-8');

abstract class Buyer{
protected $name;

public function __construct($name){
$this->name = $name;
}

public function getName(){
return $this->name;
}

abstract public function buy(Landlord $landlord);
}

class Student extends Buyer{
public function buy(Landlord $landlord){
return '学生'.$this->name.'买了房东'.$landlord->getName()
.'的'.$landlord->getAddress().'一套房!';
}
}

class Teacher extends Buyer{
public function buy(Landlord $landlord){
return '老师'.$this->name.'买了房东'.$landlord->getName()
.'的'.$landlord->getAddress().'一套房!';
}
}

class Landlord{
private $name;
private $address;

public function __construct($name, $address){
$this->name = $name;
$this->address = $address;
}

public function getName(){
return $this->name;
}

public function getAddress(){
return $this->address;
}

public function sell(Buyer $buyer){
return $this->name.'在'.$this->address.'卖掉了一套房!购房者:'.$buyer->getName();
}
}


$student = new Student('suse');
$landlord = new Landlord('包租婆', '功夫村');
echo $student->buy($landlord);

echo '<br />';

echo $landlord->sell($student);

此版本:房东和租房者直接进行交流,各自包含了对方的引用,会让整个系统变得复杂而不够清晰,如果这时再加入银行贷款业务,那么银行类包含租房者的引用,租房者也要包含银行的引用。这个时候,如果采用中介者模式,可以一定程度消除这种复杂性。
举个例子:各种食品工厂,生活用品公司,不会和消费者直接进行沟通,而是把所有的产品放到超市,消费者直接去超市购物即可。而此时的超市,就是一个中介者。

租房系统第二版:使用中介者模式,消除租房者和房东之间的互相关联

学生和老师在中介者处买房,房东在中介者处卖房

demo5.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
<?php
header('Content-Type:text/html; charset=utf-8');

abstract class Buyer{
protected $name;
protected $mediator;

public function __construct($name, $mediator){
$this->name = $name;
$this->mediator = $mediator;
}

public function getName(){
return $this->name;
}

abstract public function buy();
}

class Student extends Buyer{
public function buy(){
return $this->mediator->buy();
}
}

class Teacher extends Buyer{
public function buy(){
return $this->mediator->buy();
}
}

class Landlord{
private $name;
private $address;
private $mediator;

public function __construct($name, $address, $mediator){
$this->name = $name;
$this->address = $address;
$this->mediator = $mediator;
}

public function getName(){
return $this->name;
}

public function getAddress(){
return $this->address;
}

public function sell(){
return $this->mediator->sell();
}
}

class Mediator{
private $objs = [];

public function addObj($obj){
$this->objs[] = $obj;
}

public function buy(){
foreach($this->objs as $obj){
if($obj instanceof Buyer){
if($obj instanceof Student) $tmp = '学生';
if($obj instanceof Teacher) $tmp = '老师';
$buyer = $obj;
}
if($obj instanceof Landlord){
$landlord = $obj;
}
}
return $tmp.$buyer->getName().'买了房东'.$landlord->getName()
.'一套在'.$landlord->getAddress().'的房!';
}

public function sell(){
foreach($this->objs as $obj){
if($obj instanceof Buyer){
if($obj instanceof Student) $tmp = '学生';
if($obj instanceof Teacher) $tmp = '老师';
$buyer = $obj;
}
if($obj instanceof Landlord){
$landlord = $obj;
}
}
return '房东'.$landlord->getName().'卖了一套'.$landlord->getAddress()
.'房!购房者:'.$tmp.$buyer->getName();
}
}

此版本最直观的感觉,就是消除了租房者和房东之间的互相关联,让各自保持独立,所有的工作让中介者完成,而这带来的巨大好处就是灵活性和可扩展性,我们不但可以租房 ,租房者还是租车,租其他各种各样的可扩展的东西