🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[toc] ## 举个例子 **代收快递** * 周四下单, 周末双休, 你以为周末快递能到, 所以选了家里的地址 * 结果周五快递就到了, 但是你在上班 * 你让宅在家里的邻居帮你代收 ## 代码示例 ```php <?php // 接收包裹 class ReceiveParcel { private $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } public function receive($parcelContent) { } } // Tony接收 class TonyReception extends ReceiveParcel { private $phoneNum; public function __construct($name, $phoneNum) { parent::__construct($name); $this->phoneNum = $phoneNum; } public function getPhoneNum() { return $this->phoneNum; } public function receive($parcelContent) { echo "货物主人:{$this->getName()}, 手机号:{$this->getPhoneNum()} "; echo "收到一个包裹, 包裹内容: {$parcelContent}" . PHP_EOL; } } // Wendy接收 class WendyReception extends ReceiveParcel { private $receiver; public function __construct($name, $receiver) { parent::__construct($name); $this->receiver = $receiver; } public function receive($parcelContent) { echo "我是" . $this->receiver->getName() . "的朋友, 我来帮他代收快递!" . PHP_EOL; if ($this->receiver) { $this->receiver->receive($parcelContent); } echo "代收人:" . $this->getName(); } } $tony = new TonyReception("Tony", "18512345678"); $wendy = new WendyReception("Wendy", $tony); $wendy->receive("雪地靴"); ``` ``` D:\soft\php72\php.exe D:\project\php_dp\index.php 我是Tony的朋友, 我来帮他代收快递! 货物主人:Tony, 手机号:18512345678 收到一个包裹, 包裹内容: 雪地靴 代收人:Wendy Process finished with exit code 0 ``` ## 代码说明 > 包裹实际上是 Tony 的,但是 Wendy 代替 Tony 的身份帮忙接收了包裹,Wendy 需要使用 Tony 的身份并获得快递员的验证(Tony 手机号)才能成功接收包裹。 ## 什么是代理模式? 1. 给某一个对象提供一个代理,并由代理对象控制对原对象的引用。 1. 一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用。 1. 如上面的示例中,Tony 因为不在家,所以不能亲自接收包裹,但他可以叫 Wendy 来代他接收,这里 Wendy 就是代理,她代理了 Tony 的身份去接收快递。 ![](https://box.kancloud.cn/c787295bebfd570071d155b6edbbf1ed_509x321.png) ## 设计要点 1. **主题(Subject)**:定义“操作/活动/任务”的接口类。 1. **真实主题(RealSubject)**:真正完成“操作/活动/任务”的具体类。 1. **代理主题(ProxySubject)**:代替真实主题完成“操作/活动/任务”的代理类 ## 优缺点 **代理模式的优点** 1. 代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。 1. 可以灵活地隐藏被代理对象的部分功能和服务,也增加额外的功能和服务。 **代理模式的缺点** 1. 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 1. 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。 ## 应用场景 1. 不想或者不能直接引用一个对象时 如在移动端加载网页信息时,因为下载真实大图比较耗费流量和性能,可以用一个小图代替进行渲染(用一个代理对象去下载小图),在真正点击图片时,才去下载大图,显示大图效果。还有 HTML 中的占位符,其实也是代理的思想。 1. 想对一个对象的功能进行加强时 如在字体(Font)渲染时,对粗体(BoldFont)进行渲染时,可使用字体 Font 对象进行代理,只要在对 Font 进行渲染后,进行一步加粗的操作即可。