课程名称:大话PHP设计模式
课程章节:代理模式
课程讲师:Rango
课程内容:
为什么要使用代理模式
试想如下场景,我们需要加载一个图片,而这个图片保存在硬盘中,或者在云存储中,我们希望第一次获取图片的时候就从硬盘中把图片读取下来,第二次获取图片的时候就不用再从硬盘中重新读取图片了,代理模式正式解决的这样的问题
代码
该实例中的
Imooc\Loader.php
文件为框架加载文件,不是策略模式中的文件
-
代码目录结构
-
Imooc/Image.php
<?php
namespace Imooc;
// 定义一个图片类的接口
interface Image
{
public function display();
}
- Imooc/Loader.php
<?php
namespace Imooc;
class Loader
{
static public function autoload($class) {
require BASEDIR . '/' . str_replace('\\', '/', $class) . '.php';
}
}
- Imooc/ProxyImage.php
<?php
namespace Imooc;
// 这个是代理的图片类,在业务中实际使用的是这个类,而不是RealImage类
class ProxyImage implements Image
{
private $realImage;
private $fileName;
public function __construct($fileName) {
$this->fileName = $fileName;
}
public function display()
{
if(is_null($this->realImage)) {
$this->realImage = new RealImage($this->fileName);
}
$this->realImage->display();
}
}
- Imooc/RealImage.php
<?php
namespace Imooc;
// 这个是真实显示图片的类,从硬盘中加载图片
class RealImage implements Image
{
private $fileName;
private $fileData;
public function __construct($fileName) {
$this->fileName = $fileName;
$this->loadFromDisk();
}
public function display()
{
echo "Displaying ImageData ($this->fileData)" . PHP_EOL;
}
// 从硬盘加载文件
private function loadFromDisk() {
echo "Load Image ({$this->fileName}) From Disk……" . PHP_EOL;
$this->fileData = sprintf('模拟图片数据:%s', random_int(10, 1000));
}
}
- index.php
<?php
define('BASEDIR', __DIR__);
include BASEDIR . '/Imooc/Loader.php';
spl_autoload_register('\\Imooc\\Loader::autoload');
$image = new \Imooc\ProxyImage('image.jpg');
// 加载图片数据(这是从硬盘中读取到的)
$image->display();
// 这次就不会从硬盘中读取了
$image->display();
/** 输出:
Load Image (image.jpg) From Disk……
Displaying ImageData (模拟图片数据:192)
Displaying ImageData (模拟图片数据:192)
*/
ProxyImage就是一个代理类,它代理了真实的RealImage类,它们都遵循Image接口,ProxyImage不关心RealImage类的具体实现,它不负责具体的业务
课程收获
再次感受到了设计模式之间的大同小异,目前感觉有部分设计模式的代码实现差别并不大,但设计模式最重要的是思想,所以代码实现也应该是看个人的能力而言,这一点还需要整合多个设计模式进行比较,这是以后的事情了