当前位置: 首页 > news >正文

PHP设计模式装饰器与代理模式

PHP设计模式装饰器与代理模式

装饰器模式和代理模式在结构上有点相似,但目的完全不同。装饰器动态添加功能,代理控制访问。今天用代码说明两者的区别。

装饰器模式的核心是层层包装,每个装饰器添加一点功能。

```php
interface Notification
{
public function send(string $message): void;
}

class BasicNotification implements Notification
{
public function send(string $message): void
{
echo "发送消息: $message\n";
}
}

abstract class NotificationDecorator implements Notification
{
protected Notification $notification;

public function __construct(Notification $notification)
{
$this->notification = $notification;
}
}

class EmailDecorator extends NotificationDecorator
{
private string $email;

public function __construct(Notification $notification, string $email)
{
parent::__construct($notification);
$this->email = $email;
}

public function send(string $message): void
{
$this->notification->send($message);
echo "发送邮件至 {$this->email}: $message\n";
}
}

class SmsDecorator extends NotificationDecorator
{
private string $phone;

public function __construct(Notification $notification, string $phone)
{
parent::__construct($notification);
$this->phone = $phone;
}

public function send(string $message): void
{
$this->notification->send($message);
echo "发送短信至 {$this->phone}: $message\n";
}
}

class LogDecorator extends NotificationDecorator
{
public function send(string $message): void
{
echo "[日志] 开始发送\n";
$this->notification->send($message);
echo "[日志] 发送完成\n";
}
}

$notification = new BasicNotification();
$notification = new EmailDecorator($notification, 'user@example.com');
$notification = new SmsDecorator($notification, '13800138000');
$notification = new LogDecorator($notification);

$notification->send('系统更新通知');
?>
>

代理模式在需要控制对象访问时使用。

```php
interface Image
{
public function display(): void;
}

class RealImage implements Image
{
private string $filename;

public function __construct(string $filename)
{
$this->filename = $filename;
$this->loadFromDisk();
}

private function loadFromDisk(): void
{
echo "从磁盘加载图片: {$this->filename}\n";
}

public function display(): void
{
echo "显示图片: {$this->filename}\n";
}
}

class ImageProxy implements Image
{
private ?RealImage $realImage = null;
private int $accessCount = 0;

public function __construct(private string $filename) {}

public function display(): void
{
$this->accessCount++;
echo "第{$this->accessCount}次访问\n";

if ($this->realImage === null) {
$this->realImage = new RealImage($this->filename);
}

$this->realImage->display();
}
}

$image = new ImageProxy('photo.jpg');
$image->display();
$image->display();
echo "访问次数: {$image->getAccessCount()}\n";
?>
>

保护代理控制访问权限。

```php
interface Document
{
public function getContent(): string;
}

class SecureDocument implements Document
{
private string $content;

public function __construct(string $content)
{
$this->content = $content;
}

public function getContent(): string
{
return $this->content;
}
}

class DocumentProxy implements Document
{
private ?SecureDocument $document = null;
private array $allowedRoles;

public function __construct(string $content, array $allowedRoles)
{
$this->document = new SecureDocument($content);
$this->allowedRoles = $allowedRoles;
}

public function getContent(): string
{
$role = $_SESSION['role'] ?? 'guest';
if (!in_array($role, $this->allowedRoles)) {
throw new RuntimeException("权限不足");
}
return $this->document->getContent();
}
}
?>

装饰器和代理的主要区别是用途不同。装饰器用于增强功能,代理用于控制访问。装饰器接收被装饰对象作为参数,代理则自己创建或引用目标对象。理解了这两种模式的区别,在实际项目中就能根据需求选择合适的方案。

http://www.cnnetsun.cn/news/2805072.html

相关文章:

  • Abaqus六面体网格划分实战:一个带耳板和圆孔底座的‘扫掠’优化全记录
  • 谷歌发布 Gemma 4 QAT模型:1GB内存运行大模型,端侧AI再进一步
  • Wireshark Statistics模块实战:5分钟看懂网络流量构成,排查问题快人一步
  • SRS 4.0 源码阅读笔记(一):从 State Threads 协程模型看高并发流媒体服务的设计哲学
  • 定价数据清洗:打破清洁幻觉,用EDA保全决策证据链
  • 终极指南:如何搭建游戏王大师决斗完整离线版并深度自定义
  • QGIS切片+Cesium加载:解决瓦片错位、空白或跨域问题的实战排查指南
  • 【IF-SAFE-06】安全IO - 功能安全的硬件保障
  • 从实验室到社交媒体:Nature和Science的论文,普通人该怎么读才能不掉队?
  • Agent Runtime 正在 commoditization:从操作系统时刻看基础设施归零
  • Java 23 种设计模式:从踩坑到精通 | 原型模式 —— 克隆对象,深拷贝与浅拷贝的坑你踩过吗?
  • 30天无限循环:JetBrains IDE试用期重置终极指南
  • 点云标注避坑指南:用CloudCompare保存带语义标签的PLY文件,为什么选ASCII格式?
  • 别再死记硬背了!用Anki记忆库+Notion模板,科学攻克国科大英语Unit1核心句型与行文结构
  • 别再只会用默认Key了!手把手教你用ysoserial探测并利用Shiro 1.2.4反序列化漏洞
  • 交直流混联系统优化|基于显式拓扑变量可靠性评估的双Q交直流混合配电网优化规划研究(Python代码实现)
  • 从智能灯泡到传感器网络:实战解析蓝牙Mesh、WiFi AP/STA、ZigBee 3.0在智能家居中的真实配置与避坑
  • STM32F411/F401 Keil裸机工程模板:带LED闪烁、串口基础驱动和一键清理功能
  • SQL中CASE WHEN的实战心法:从数据分层到业务规则固化
  • XUnity.AutoTranslator:5分钟搞定Unity游戏多语言翻译的终极指南
  • Win/Mac双平台实测:手把手解决Operator Mono字体在VSCode中不生效的常见问题
  • 告别乱码!手把手教你用LabVIEW 2023报表工具包完美读取带中文的Excel表格
  • 深入DPDK L3fwd源码:看一个三层转发示例如何管理路由与端口
  • 百度网盘高速下载终极方案:告别限速的智能解析工具
  • 三分钟快速上手:Dell G15开源散热控制神器tcc-g15完整指南
  • 效率提升秘籍:用快马生成ubuntu自动化部署脚本,十分钟搞定服务器环境配置
  • 从‘压控’原理到电路设计:搞懂MOS管G、S、D,让你的开关电源效率翻倍
  • VC++ MFC二维码识别工具:调用ZBar实现摄像头/图片扫码功能
  • 别再只会conda clean了!遇到InvalidArchiveError,试试这个更治本的修复思路
  • 【非IT人AI营销实战指南】:3步开通CSDN AI数字营销,零代码搞定获客闭环?