代理,指的就是一个角色代表另一个角色采取行动,就像现实生活中,微软或联想不会直接把自己的系统或者电脑卖给客户,而是通过代理来完成它的销售业务。而客户,也不用为了买个Office或笔记本而到处去找联想工厂,或者微软公司,它只要找到厂商的销售代理就可以了。
代理模式,就是给某一对象提供代理对象,并由代理对象控制具体对象的引用。
代理模式涉及的角色:
- 抽象主题角色,声明了代理主题和真实主题的公共接口,使任何需要真实主题的地方能用代理主题替代
- 代理主题角色,含有真实主题的引用,从而可以在任何时候操作真实主题,代理主题通过提供和真实主题相同的接口,使它们可以随时代替真实主题。代理主题通过持有真实主题的引用,不但可以控制真实主题的创建和删除,还可以在真实主题被调用前进行拦截,或在调用后进行某些操作。
- 真实代理对象,定义了代理角色所代表的具体对象
/**
*Proxy 代理模式
*/
/**
*抽象主题(接口)
*/
interface Proxy
{
public function request();
public function display();
}
/**
*真实主题
*/
class RealSubject
{
public function request()
{
echo 'RealSubject request<br/>';
}
public function display()
{
echo 'RealSubject display<br/>';
}
}
/**
*代理主题
*/
class ProxySubject
{
private $_subject = null;
public function __construct()
{
$this->_subject = new RealSubject();
}
public function request()
{
$this->_subject->request();
}
public function display()
{
$this->_subject->display();
}
}
//使用
$objProxy = new ProxySubject();
$objProxy->request();
$objProxy->display();
代理模式的工作方式:
首先,因为代理主题和真实主题都实现了共同的接口,这使得我们在不改变原来接口的情况下,只要用真实主题对象的地方,都可以用代理主题来代替。其次,代理主题在客户端和真实主题间起了一个中介作用,利用这个中介平台,我们可以在把客户请求传递给真实主题之前做一些必要的语出里。
有一个很常见的代理模式的使用例子就是大幅图片的浏览控制。在我们常见的网站上浏览图片的信息时,不知道你有没有注意到,图片位置放置的是经过缩小的,当有人要仔细查看这个图片时,可以通过点击图片来激活一个链接,在一个新的网页中打开要看的图片。这样对于提高浏览速度是很有好处的,因为不是每个人都要去仔细看图片上的信息。这种情况就可以用代理模式来全面实现。
我们在浏览器中访问网页时调用的不是真实的装载图片的方法,而是在代理对象中的方法,在这个对象中,先用一个线程向浏览器装载一个缩小版的图片,而在后再使用另一个线程来调用真实的装载大图片的方法将图片加载到本地,当你要浏览这个图片时,将其在新的网页中显示出来。当然,如果在你想浏览的时候图片还没有加载成功,就再启动一个线程来提示信息,知道加载完成。
代理模式能够协调调用者和被调用者,能够在一定程度上降低系统的耦合度。