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

PHP设计模式工厂模式详解

PHP设计模式工厂模式详解

工厂模式是设计模式中最常用的创建型模式之一。它把对象创建的逻辑封装起来,客户端不需要知道具体的创建过程。今天从简单工厂到抽象工厂一步步说清楚。

简单工厂是最基础的形式。用一个工厂类根据参数创建不同的对象。

```php
interface Logger
{
public function log(string $message): void;
}

class FileLogger implements Logger
{
public function __construct(private string $path) {}

public function log(string $message): void
{
file_put_contents($this->path, $message . "\n", FILE_APPEND);
}
}

class DatabaseLogger implements Logger
{
public function __construct(private PDO $pdo) {}

public function log(string $message): void
{
$stmt = $this->pdo->prepare(
"INSERT INTO logs (message, created_at) VALUES (?, NOW())"
);
$stmt->execute([$message]);
}
}

class EchoLogger implements Logger
{
public function log(string $message): void
{
echo "[" . date('Y-m-d H:i:s') . "] $message\n";
}
}

// 简单工厂
class LoggerFactory
{
public static function create(string $type): Logger
{
return match ($type) {
'file' => new FileLogger('/var/log/app.log'),
'database' => new DatabaseLogger(
new PDO('mysql:host=localhost;dbname=test', 'root', '')
),
'echo' => new EchoLogger(),
default => throw new InvalidArgumentException("不支持的日志类型: $type"),
};
}
}

// 使用
$logger = LoggerFactory::create('file');
$logger->log('用户登录成功');
$logger->log('订单创建成功');

$logger2 = LoggerFactory::create('echo');
$logger2->log('这行会显示在控制台');
?>
```

工厂方法模式把工厂本身也抽象化,每个产品对应一个工厂子类。这样新增产品不需要修改工厂类,符合开闭原则。

```php
// 工厂方法模式
interface LoggerFactoryInterface
{
public function createLogger(): Logger;
}

class FileLoggerFactory implements LoggerFactoryInterface
{
public function __construct(private string $path) {}

public function createLogger(): Logger
{
return new FileLogger($this->path);
}
}

class DatabaseLoggerFactory implements LoggerFactoryInterface
{
public function __construct(private PDO $pdo) {}

public function createLogger(): Logger
{
return new DatabaseLogger($this->pdo);
}
}

class EchoLoggerFactory implements LoggerFactoryInterface
{
public function createLogger(): Logger
{
return new EchoLogger();
}
}

// 使用工厂方法
$factory = new FileLoggerFactory('/var/log/app.log');
$logger = $factory->createLogger();
$logger->log('使用工厂方法创建的日志');
?>
```

抽象工厂模式用于创建一系列相关的产品。比如跨平台UI组件,Windows和Mac各有不同的实现。

```php
// 抽象产品
interface Button
{
public function render(): string;
public function click(): void;
}

interface Checkbox
{
public function render(): string;
public function toggle(): void;
}

interface TextField
{
public function render(): string;
public function setValue(string $value): void;
}

// Windows产品族
class WindowsButton implements Button
{
public function render(): string
{
return "确定";
}

public function click(): void
{
echo "Windows按钮被点击\n";
}
}

class WindowsCheckbox implements Checkbox
{
public function render(): string
{
return "";
}

public function toggle(): void
{
echo "Windows复选框切换\n";
}
}

// Mac产品族
class MacButton implements Button
{
public function render(): string
{
return "确定";
}

public function click(): void
{
echo "Mac按钮被点击\n";
}
}

class MacCheckbox implements Checkbox
{
public function render(): string
{
return "";
}

public function toggle(): void
{
echo "Mac复选框切换\n";
}
}

// 抽象工厂
interface UIFactory
{
public function createButton(): Button;
public function createCheckbox(): Checkbox;
public function createTextField(): TextField;
}

// Windows工厂
class WindowsUIFactory implements UIFactory
{
public function createButton(): Button
{
return new WindowsButton();
}

public function createCheckbox(): Checkbox
{
return new WindowsCheckbox();
}

public function createTextField(): TextField
{
return new class implements TextField {
private string $value = '';
public function render(): string { return ""; }
public function setValue(string $value): void { $this->value = $value; }
};
}
}

// Mac工厂
class MacUIFactory implements UIFactory
{
public function createButton(): Button
{
return new MacButton();
}

public function createCheckbox(): Checkbox
{
return new MacCheckbox();
}

public function createTextField(): TextField
{
return new class implements TextField {
private string $value = '';
public function render(): string { return ""; }
public function setValue(string $value): void { $this->value = $value; }
};
}
}

// 应用
class Application
{
private UIFactory $factory;

public function __construct(string $platform)
{
$this->factory = match ($platform) {
'windows' => new WindowsUIFactory(),
'mac' => new MacUIFactory(),
default => throw new InvalidArgumentException("不支持的平台: $platform"),
};
}

public function renderUI(): void
{
$button = $this->factory->createButton();
$checkbox = $this->factory->createCheckbox();
$textField = $this->factory->createTextField();

echo $button->render() . "\n";
echo $checkbox->render() . "\n";
echo $textField->render() . "\n";
}
}

$app = new Application('windows');
$app->renderUI();

$app2 = new Application('mac');
$app2->renderUI();
?>
```

实际项目中工厂模式最常见的用途是创建数据库连接、缓存实例或支付网关。把这些对象的创建集中管理,切换实现的时候只需要改工厂,不用改业务代码。

```php
// 支付网关工厂
interface PaymentGateway
{
public function charge(float $amount, array $params): array;
public function refund(string $transactionId): array;
}

class StripeGateway implements PaymentGateway
{
public function charge(float $amount, array $params): array
{
return ['id' => 'ch_' . uniqid(), 'amount' => $amount, 'status' => 'succeeded'];
}

public function refund(string $transactionId): array
{
return ['id' => 'rf_' . uniqid(), 'status' => 'succeeded'];
}
}

class PayPalGateway implements PaymentGateway
{
public function charge(float $amount, array $params): array
{
return ['id' => 'PAY-' . uniqid(), 'amount' => $amount, 'state' => 'approved'];
}

public function refund(string $transactionId): array
{
return ['refund_id' => 'REF-' . uniqid(), 'state' => 'completed'];
}
}

class PaymentGatewayFactory
{
private static array $configs = [];

public static function configure(string $name, string $class, array $config = []): void
{
self::$configs[$name] = ['class' => $class, 'config' => $config];
}

public static function create(string $name): PaymentGateway
{
if (!isset(self::$configs[$name])) {
throw new InvalidArgumentException("未配置的支付网关: $name");
}

$config = self::$configs[$name];
$class = $config['class'];

return new $class($config['config']);
}
}

// 配置
PaymentGatewayFactory::configure('default', StripeGateway::class);
PaymentGatewayFactory::configure('paypal', PayPalGateway::class);

// 使用
$gateway = PaymentGatewayFactory::create('default');
$result = $gateway->charge(99.99, ['currency' => 'usd']);
print_r($result);
?>
```

工厂模式和依赖注入容器配合使用效果更好。容器负责管理对象的生命周期,工厂负责创建复杂对象。用好了工厂模式,代码的扩展性和可维护性会提升很多。

http://www.jsqmd.com/news/948290/

相关文章:

  • 【职场】你公司挂在墙上的使命愿景价值观,本质是一套人事物的操控系统
  • 5分钟快速上手Janus-Pro-1B:从零开始部署你的首个多模态AI应用
  • 3分钟掌握JetBrains IDE无限试用:开源重置工具终极指南
  • TinyLlama-1.1B-Chat-v0.1安全部署指南:保护AI对话系统的5个关键步骤
  • 避坑指南:Verilog写BMP图片时多出0D字节?详解二进制与文本模式区别
  • 2026年郑州地坪漆厂家全景横评:环保耐磨定制方案选购指南 - 优质企业观察收录
  • C#写的推箱子游戏源码,带关卡编辑器、操作回放和本地存档
  • 如何用EPubBuilder在线编辑器5分钟打造专业电子书
  • 微信小程序班级管理全套资源:含学生签到、作业提交、通知发布与后台管理源码
  • MusicFree插件终极指南:5分钟打造你的全能音乐播放器
  • 基于Python+Django的轻量化私有云盘系统:从零搭建安全可控的文件存储与共享平台
  • Gemma 4-31B编程能力实战:10个代码生成与调试示例
  • 新手避坑指南:用ArcGIS和SWAT2012做水文模拟,我在石羊河流域踩过的那些‘雷’
  • FunClip终极指南:3步掌握本地AI视频剪辑神器
  • 2026年江苏钢结构厂家:徐州门式钢结构/钢结构天桥/钢结构栈桥,钢板下料/钢板切割/预埋件钢板有实力的企业 - 品牌企业推荐师(官方)
  • 3分钟掌握微信小程序二维码生成:weapp-qrcode完全指南
  • 易语言乐玩插件实战:用《剑侠情缘》多开,手把手教你搞定多线程后台绑定(附源码)
  • 免费在线使用的去水印软件推荐|分场景梳理图片视频多类免费去水印实用工具
  • F28335毫秒级定时器驱动工程:LED闪烁、数码管倒计时、按键响应与蜂鸣反馈一体化示例
  • MATLAB小波图像拼接教学包:带GUI操作界面、多组实测图像与完整可运行代码
  • 洛雪音乐助手:三大音乐平台一键聚合,打造你的专属音乐库
  • 伺服电机力矩控制实现精确运动
  • VdhCoApp终极指南:如何在Mac OS Sonoma 14.2.1上完美安装与配置Video DownloadHelper伴侣应用
  • PHP设计模式策略与适配器实战
  • 手机靓号平台哪家正规?4项资质标准对照 - 资讯快报
  • 3分钟掌握洛雪音乐助手:跨平台音乐聚合播放的终极指南 [特殊字符]
  • 从一道CTF题看PHP Session反序列化:手把手教你复现HarekazeCTF2019的Easy Notes
  • 气井井口压力已知时快速推算井底流压的MATLAB工具集
  • 3个现代Anki模板主题:如何让记忆卡片变得美观又高效
  • GLM-5.1办公语义理解器:让AI真正读懂任务意图与组织规则