代理模式(Proxy)
模式目的
为昂贵或者无法复制的资源提供接口。
代码示例
创建一个抽象类Image。 创建一个继承Image的RealImage类。 创建一个继承Image的ProxyImage类。
- Image接口
abstract class Image
{
private $fileName;
public function __construct($fileName)
{
$this->fileName = $fileName;
}
abstract public function display();
}
- 真实获取Image的类
class RealImage implements Image
{
public function __construct($fileName)
{
parent::__construct($fileName);
$this->loadFromDisk($this->fileName);
}
public function display()
{
echo "Displaying:$this->fileName";
}
private function loadFromDisk($fileName)
{
echo "Loading:$fileName";
}
}
- 代理访问Image
class ProxyImage implements Image
{
private $realImage;
public function display()
{
if (is_null($this->realImage)) {
$this->realImage = new RealImage($this->fileName);
}
$this->realImage->display();
}
}
- 演示(Demo)
// 使用代理Image来访问图片
$proxyImage = new ProxyImage('1.jpg');
// 图像需要从磁盘加载
$proxyImage->display();
// 图像无需再次从磁盘加载
$proxyImage->display();
角色
- 主题(Subject) - 抽象类
- 真实主题(RealSubject) - 继承了Subject
- 代理(Proxy) - 继承了Subject
模式类型
结构型模式
JS使用代理模式实现图片懒加载
实现步骤
- 先展示一张占位图片(placeholder.png)
- 异步加载真实图片
- 真实图片加载完毕替换掉占位图片
代码
// 真实image
function RealImage() {
this.imgNode = document.createElement('img')
document.body.appendChild(this.imgNode)
}
RealImage.prototype.setSrc = function(src) {
this.imgNode.src = src
}
// 代理image
function ProxyImage() {
this.realImage = new RealImage()
// 设置占位图
this.realImage.setSrc('placeholder.png')
}
ProxyImage.prototype.setSrc = function(src) {
const img = new Image()
img.src = src
img.onload = () => {
this.realImage.setSrc(src)
}
}
const proxyImage = new ProxyImage()
proxyImage.setSrc('pic.png')