本文目录导读:

我来详细解释PHP中的装饰器模式与动态扩展概念,并提供实用示例。
装饰器模式(Decorator Pattern)
基本概念
装饰器模式允许向现有对象添加新功能,同时不改变其结构。
基础示例
<?php
// 接口定义
interface Coffee
{
public function cost(): float;
public function description(): string;
}
// 基础组件
class SimpleCoffee implements Coffee
{
public function cost(): float
{
return 10.0;
}
public function description(): string
{
return "简单咖啡";
}
}
// 基础装饰器
abstract class CoffeeDecorator implements Coffee
{
protected Coffee $coffee;
public function __construct(Coffee $coffee)
{
$this->coffee = $coffee;
}
abstract public function cost(): float;
abstract public function description(): string;
}
// 具体装饰器 - 牛奶
class MilkDecorator extends CoffeeDecorator
{
public function cost(): float
{
return $this->coffee->cost() + 2.5;
}
public function description(): string
{
return $this->coffee->description() . ",加牛奶";
}
}
// 具体装饰器 - 糖
class SugarDecorator extends CoffeeDecorator
{
public function cost(): float
{
return $this->coffee->cost() + 0.5;
}
public function description(): string
{
return $this->coffee->description() . ",加糖";
}
}
// 具体装饰器 - 奶油
class CreamDecorator extends CoffeeDecorator
{
public function cost(): float
{
return $this->coffee->cost() + 3.0;
}
public function description(): string
{
return $this->coffee->description() . ",加奶油";
}
}
// 使用示例
$coffee = new SimpleCoffee();
echo $coffee->description() . ":¥" . $coffee->cost() . "\n";
$coffeeWithMilk = new MilkDecorator($coffee);
echo $coffeeWithMilk->description() . ":¥" . $coffeeWithMilk->cost() . "\n";
$coffeeWithMilkAndSugar = new SugarDecorator($coffeeWithMilk);
echo $coffeeWithMilkAndSugar->description() . ":¥" . $coffeeWithMilkAndSugar->cost() . "\n";
$fullCoffee = new CreamDecorator($coffeeWithMilkAndSugar);
echo $fullCoffee->description() . ":¥" . $fullCoffee->cost() . "\n";
动态扩展实现
方法1:使用__call魔术方法
<?php
class DynamicObject
{
private array $properties = [];
private array $methods = [];
// 动态设置属性
public function __set(string $name, $value): void
{
$this->properties[$name] = $value;
}
// 动态获取属性
public function __get(string $name)
{
return $this->properties[$name] ?? null;
}
// 动态调用方法
public function __call(string $name, array $arguments)
{
if (isset($this->methods[$name])) {
return call_user_func_array($this->methods[$name], $arguments);
}
throw new \RuntimeException("方法 {$name} 不存在");
}
// 动态添加方法
public function addMethod(string $name, callable $callback): void
{
$this->methods[$name] = $callback;
}
// 检查方法是否存在
public function hasMethod(string $name): bool
{
return isset($this->methods[$name]);
}
}
// 使用示例
$obj = new DynamicObject();
$obj->name = "动态对象";
echo $obj->name . "\n"; // 输出:动态对象
// 动态添加方法
$obj->addMethod('greet', function(string $name) {
return "Hello, {$name}!";
});
$obj->addMethod('calculate', function(float $a, float $b) {
return $a + $b;
});
echo $obj->greet("张三") . "\n"; // 输出:Hello, 张三!
echo $obj->calculate(10, 20) . "\n"; // 输出:30
方法2:使用匿名类(PHP 7+)
<?php
// 基础接口
interface Logger
{
public function log(string $message): void;
}
// 基础实现
class FileLogger implements Logger
{
private string $filePath;
public function __construct(string $filePath)
{
$this->filePath = $filePath;
}
public function log(string $message): void
{
file_put_contents($this->filePath, $message . PHP_EOL, FILE_APPEND);
}
}
// 使用匿名类动态扩展
function createEnhancedLogger(Logger $baseLogger): Logger
{
return new class($baseLogger) implements Logger {
private Logger $logger;
private array $processedMessages = [];
public function __construct(Logger $logger)
{
$this->logger = $logger;
}
public function log(string $message): void
{
// 添加时间戳
$enhancedMessage = "[" . date('Y-m-d H:i:s') . "] " . $message;
// 记录处理过的消息
$this->processedMessages[] = $enhancedMessage;
// 调用原始logger
$this->logger->log($enhancedMessage);
}
public function getStatistics(): array
{
return [
'total_messages' => count($this->processedMessages),
'messages' => $this->processedMessages
];
}
};
}
// 使用示例
$fileLogger = new FileLogger('/tmp/test.log');
$enhancedLogger = createEnhancedLogger($fileLogger);
$enhancedLogger->log("用户登录");
$enhancedLogger->log("用户退出");
// 获取统计信息
$result = $enhancedLogger->getStatistics();
print_r($result);
方法3:使用Traits实现动态扩展
<?php
// 定义可复用的模块
trait Timestampable
{
private ?\DateTime $createdAt = null;
private ?\DateTime $updatedAt = null;
public function getCreatedAt(): ?\DateTime
{
return $this->createdAt;
}
public function getUpdatedAt(): ?\DateTime
{
return $this->updatedAt;
}
public function markAsCreated(): void
{
$this->createdAt = new \DateTime();
$this->updatedAt = new \DateTime();
}
public function markAsUpdated(): void
{
$this->updatedAt = new \DateTime();
}
}
trait Loggable
{
private array $logs = [];
public function logAction(string $action): void
{
$this->logs[] = [
'action' => $action,
'timestamp' => new \DateTime(),
'user' => $_SERVER['USER'] ?? 'system'
];
}
public function getLogs(): array
{
return $this->logs;
}
}
trait Validateable
{
private array $errors = [];
public function validate(array $data, array $rules): bool
{
$this->errors = [];
foreach ($rules as $field => $rule) {
if (!isset($data[$field]) && strpos($rule, 'required') !== false) {
$this->errors[$field] = "{$field} 是必填字段";
} elseif (isset($data[$field])) {
$this->validateField($field, $data[$field], $rule);
}
}
return empty($this->errors);
}
private function validateField(string $field, $value, string $rule): void
{
// 简化验证逻辑
if (strpos($rule, 'email') !== false && !filter_var($value, FILTER_VALIDATE_EMAIL)) {
$this->errors[$field] = "{$field} 必须是有效的邮箱地址";
}
if (strpos($rule, 'min:') !== false) {
preg_match('/min:(\d+)/', $rule, $matches);
if (!empty($matches) && strlen($value) < (int)$matches[1]) {
$this->errors[$field] = "{$field} 长度不能少于 {$matches[1]} 个字符";
}
}
}
public function getErrors(): array
{
return $this->errors;
}
}
// 使用Traits动态扩展类
class User
{
use Timestampable, Loggable, Validateable;
private string $username;
private string $email;
public function __construct(string $username, string $email)
{
$this->username = $username;
$this->email = $email;
$this->markAsCreated();
}
public function updateEmail(string $email): void
{
$this->email = $email;
$this->markAsUpdated();
$this->logAction('update_email');
}
public function getUsername(): string
{
return $this->username;
}
}
// 使用示例
$user = new User("张三", "zhangsan@example.com");
// 使用Trait提供的方法
echo "创建时间: " . $user->getCreatedAt()->format('Y-m-d H:i:s') . "\n";
$user->updateEmail("newemail@example.com");
echo "更新时间: " . $user->getUpdatedAt()->format('Y-m-d H:i:s') . "\n";
// 查看日志
print_r($user->getLogs());
// 验证数据
$data = ['username' => '李四', 'email' => 'invalid-email'];
$rules = ['username' => 'required|min:2', 'email' => 'required|email'];
if (!$user->validate($data, $rules)) {
print_r($user->getErrors());
}
结合装饰器和动态扩展
<?php
// 高级数据处理器示例
interface DataProcessor
{
public function process(array $data): array;
}
// 基础处理器
class BaseProcessor implements DataProcessor
{
public function process(array $data): array
{
return $data;
}
}
// 装饰器工厂 - 动态创建装饰器
class ProcessorDecoratorFactory
{
public static function create(string $type, DataProcessor $processor): DataProcessor
{
switch ($type) {
case 'filter':
return new class($processor) implements DataProcessor {
private DataProcessor $processor;
public function __construct(DataProcessor $processor)
{
$this->processor = $processor;
}
public function process(array $data): array
{
$data = $this->processor->process($data);
return array_filter($data, fn($item) => !empty($item));
}
};
case 'transform':
return new class($processor) implements DataProcessor {
private DataProcessor $processor;
public function __construct(DataProcessor $processor)
{
$this->processor = $processor;
}
public function process(array $data): array
{
$data = $this->processor->process($data);
return array_map(fn($item) => strtoupper((string)$item), $data);
}
};
case 'validate':
return new class($processor) implements DataProcessor {
private DataProcessor $processor;
public function __construct(DataProcessor $processor)
{
$this->processor = $processor;
}
public function process(array $data): array
{
$data = $this->processor->process($data);
return array_filter($data, fn($item) => is_string($item) && strlen($item) > 0);
}
};
default:
throw new \InvalidArgumentException("未知处理器类型: {$type}");
}
}
}
// 使用示例
$processor = new BaseProcessor();
// 动态添加处理层
$processor = ProcessorDecoratorFactory::create('filter', $processor);
$processor = ProcessorDecoratorFactory::create('validate', $processor);
$processor = ProcessorDecoratorFactory::create('transform', $processor);
$data = ['', 'hello', 'world', null, 'PHP', ' '];
$result = $processor->process($data);
print_r($result);
// 输出: [2] => WORLD, [3] => PHP
性能优化建议
<?php
// 1. 缓存装饰器实例
class DecoratorCache
{
private static array $cache = [];
public static function get(DataProcessor $processor, string $decorator): ?DataProcessor
{
$key = spl_object_id($processor) . '_' . $decorator;
return self::$cache[$key] ?? null;
}
public static function set(DataProcessor $processor, string $decorator, DataProcessor $decorated): void
{
$key = spl_object_id($processor) . '_' . $decorator;
self::$cache[$key] = $decorated;
}
}
// 2. 延迟初始化
class LazyDecorator
{
private ?DataProcessor $processor = null;
private array $decorators = [];
public function addDecorator(string $decorator): void
{
$this->decorators[] = $decorator;
}
public function getProcessor(): DataProcessor
{
if ($this->processor === null) {
$this->processor = new BaseProcessor();
foreach ($this->decorators as $decorator) {
$this->processor = ProcessorDecoratorFactory::create($decorator, $this->processor);
}
}
return $this->processor;
}
}
实际应用场景
- 日志系统:动态添加日志级别、格式化、输出方式
- 缓存系统:添加多级缓存、压缩、序列化
- API中间件:认证、限流、日志记录
- 数据验证:链式验证规则
- ORM系统:动态添加查询条件、结果处理
- 事件系统:动态注册和移除事件处理器
装饰器模式配合动态扩展技术,可以让PHP项目具有极高的灵活性和可扩展性,特别适合需要频繁变更业务逻辑的应用场景。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播