为其他对象提供一种代理以控制对这个对象的访问.
使用场合:
1.远程代理:为一个对象在不同的地址空间提供局部代表,隐藏对象存在于不同地址空间的事实.
2.虚拟代理:根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象.
3.安全代理:用来控制真实对象访问时的权限.
4.智能指引:当调用真实对象时,代理处理另外一些事.
UML:

示例代码:
interface AbstractSubject
{
public function connect();
}
class RealSubject implements AbstractSubject
{
public function connect()
{
echo 'link to db';
}
}
class ProxySubject implements AbstractSubject
{
protected $real;
public function __construct()
{
if (is_null($this->real)) {
$this->real = new RealSubject();
}
}
public function connect()
{
$this->real->connect();
}
}
$proxy = new ProxySubject();
$proxy->connect();
示例代码:
abstract class MySQL
{
protected $link;
protected function __construct()
{
$this->connect();
}
public function getAll($table)
{
echo get_called_class() . PHP_EOL;
$res = $this->link->query("SELECT * FROM {$table}");
$data = array();
foreach ($res as $row) {
$data[] = $row;
}
return $data;
}
public function close()
{
$this->link = null;
}
abstract public static function getInstance();
}
class ReadMySQL extends MySQL
{
protected static $instance;
public static function getInstance()
{
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
public function connect()
{
if (is_null($this->link)) {
$this->link = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'root');
}
}
}
class WriteMySQL extends MySQL
{
protected static $instance;
public static function getInstance()
{
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
public function connect()
{
if (is_null($this->link)) {
$this->link = new PDO('mysql:host=192.168.2.10;dbname=test', 'root', 'root');
}
}
}
class ProxyMysql
{
private $reader;
private $writer;
public function __construct()
{
$this->reader = ReadMySQL::getInstance();
$this->writer = WriteMySQL::getInstance();
}
public function getAll($table)
{
if (rand(1,2) === 1) {
return $this->reader->getAll($table);
} else {
return $this->writer->getAll($table);
}
}
}
$test = new ProxyMysql();
var_dump($test->getAll('test'));
var_dump($test->getAll('test'));
var_dump($test->getAll('test'));
var_dump($test->getAll('test'));
我们用ProxyMysql代理了ReaderMysql和WriterMysql,简单的随机判断从两台服务器读取数据.