代理模式(Proxy)为其他对象提供一种代理以控制对这个对象的访问。使用代理模式创建代理对象,让代理对象控制目标对象的访问(目标对象可以是远程的对象、创建开销大的对象或需要安全控制的对象),并且可以在不改变目标对象的情况下添加一些额外的功能。
在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务。
代理模式在很多情况下都非常有用,特别是你想强行控制一个对象的时候,比如延迟加载、监视状态变更的方法等等。
与类似接口的区别:
- 适配器模式 —— 适配器模式为它所适配的对象提供了一个不同的接口,而代理提供了与它的实体相同的接口。
- 装饰器模式 —— 两者目的不同:装饰器为对象添加一个或多个功能,而代理则控制对对象的访问。
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
|
namespace DesignPatterns\Structural\Proxy;
class Record {
protected $data;
public function __construct($data = null) { $this->data = (array) $data; }
public function __set($name, $value) { $this->data[(string) $name] = $value; }
public function __get($name) { if (array_key_exists($name, $this->data)) { return $this->data[(string) $name]; } else { return null; } } }
namespace DesignPatterns\Structural\Proxy;
class RecordProxy extends Record {
protected $isDirty = false;
protected $isInitialized = false;
public function __construct($data) { parent::__construct($data);
if (null !== $data) { $this->isInitialized = true; $this->isDirty = true; } }
public function __set($name, $value) { $this->isDirty = true; parent::__set($name, $value); } }
namespace DesignPatterns\Structural\Proxy\Tests;
use DesignPatterns\Structural\Proxy\Record; use DesignPatterns\Structural\Proxy\RecordProxy;
class ProxyTest extends \PHPUnit_Framework_TestCase { public function testSetAttribute(){ $data = []; $proxy = new RecordProxy($data); $proxy->xyz = false; $this->assertTrue($proxy->xyz===false); } }
|