门面模式(facade pattern)

门面模式(Facade)或 外观模式,定义了一个高层接口,这个接口使得子系统更加容易使用:引入门面角色之后,用户只需要直接与门面角色交互,用户与子系统之间的复杂关系由门面角色来实现,从而降低了系统的耦合度。Laravel 中门面模式的使用也很广泛,基本上每个服务容器中注册的服务提供者类都对应一个门面类。(接口封装场景)

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
// OsInterface.php

namespace DesignPatterns\Structural\Facade;

/**
* OsInterface接口
*/
interface OsInterface
{
/**
* halt the OS
*/
public function halt();
}


// BiosInterface.php

namespace DesignPatterns\Structural\Facade;

/**
* BiosInterface接口
*/
interface BiosInterface
{
/**
* execute the BIOS
*/
public function execute();

/**
* wait for halt
*/
public function waitForKeyPress();

/**
* launches the OS
*
* @param OsInterface $os
*/
public function launch(OsInterface $os);

/**
* power down BIOS
*/
public function powerDown();
}


//实现

namespace DesignPatterns\Structural\Facade;

/**
* 门面类
*/
class Facade
{
/**
* @var OsInterface
*/
protected $os;

/**
* @var BiosInterface
*/
protected $bios;

/**
* This is the perfect time to use a dependency injection container
* to create an instance of this class
*
* @param BiosInterface $bios
* @param OsInterface $os
*/
public function __construct(BiosInterface $bios, OsInterface $os)
{
$this->bios = $bios;
$this->os = $os;
}

/**
* turn on the system
*/
public function turnOn()
{
$this->bios->execute();
$this->bios->waitForKeyPress();
$this->bios->launch($this->os);
}

/**
* turn off the system
*/
public function turnOff()
{
$this->os->halt();
$this->bios->powerDown();
}
}

// 测试

namespace DesignPatterns\Structural\Facade\Tests;

use DesignPatterns\Structural\Facade\Facade as Computer;
use DesignPatterns\Structural\Facade\OsInterface;

/**
* FacadeTest用于测试门面模式
*/
class FacadeTest extends \PHPUnit_Framework_TestCase
{

public function getComputer()
{
$bios = $this->getMockBuilder('DesignPatterns\Structural\Facade\BiosInterface')
->setMethods(array('launch', 'execute', 'waitForKeyPress'))
->disableAutoload()
->getMock();
$os = $this->getMockBuilder('DesignPatterns\Structural\Facade\OsInterface')
->setMethods(array('getName'))
->disableAutoload()
->getMock();
$bios->expects($this->once())
->method('launch')
->with($os);
$os->expects($this->once())
->method('getName')
->will($this->returnValue('Linux'));

$facade = new Computer($bios, $os);
return array(array($facade, $os));
}

/**
* @dataProvider getComputer
*/
public function testComputerOn(Computer $facade, OsInterface $os)
{
// interface is simpler :
$facade->turnOn();
// but I can access to lower component
$this->assertEquals('Linux', $os->getName());
}
}
分享即是成长