PHP面向对象 - 设计模式(单例,简单工厂,工厂方法)

张开发
2026/4/30 19:21:47 15 分钟阅读

分享文章

PHP面向对象 - 设计模式(单例,简单工厂,工厂方法)
设计模式‌Design Pattern是面向对象软件开发中针对常见问题所提出的‌可重用解决方案‌。它们并非具体代码或库而是经过实践验证的‌设计模板‌用于提升代码的‌可维护性、可扩展性、可复用性和灵活性‌。设计模式的核心分类为3大类创建型模式、结构型模式、行为型模式今天先学习创建型模式中3中常用的模式一、单例模式核心概念确保一个类在整个应用生命周期中只有一个实例并提供一个全局访问点来获取这个实例。实现要点关键 3 步私有化构造函数防止外部用new关键字创建实例私有化克隆 / 反序列化方法防止通过clone或unserialize复制实例提供静态获取方法getInstance()内部判断实例是否存在不存在则创建?phpclassDatabase{// 保存唯一实例的静态属性privatestatic?self$instancenull;// 数据库连接资源private$connection;// 1. 私有化构造函数禁止外部newprivatefunction__construct(){$this-connectionnewPDO(mysql:hostlocalhost;dbnameshop_db,root,password);}// 2. 私有化克隆方法禁止克隆privatefunction__clone(){}// 3. 私有化反序列化方法禁止反序列化publicfunction__wakeup(){thrownewException(Cannot unserialize singleton);}// 全局访问点获取唯一实例publicstaticfunctiongetInstance():self{if(self::$instancenull){self::$instancenewself();}returnself::$instance;}// 获取数据库连接业务方法publicfunctiongetConnection(){return$this-connection;}}// 使用示例$db1Database::getInstance();$db2Database::getInstance();var_dump($db1$db2);// 输出bool(true)证明是同一个实例适用场景类的创建成本高、需要全局统一状态、单次请求内只需要一个实例的场景注意PHP 是请求级生命周期单例仅在单次请求内唯一不是跨请求的开发高频场景数据库 / Redis 连接类系统配置类配置只加载一次全局共用同一个实例避免重复读取文件 / 数据库日志记录类整个系统写日志共用一个实例避免重复打开 / 关闭日志文件二、简单工厂模式核心概念定义一个工厂类根据传入的参数不同返回不同的具体类实例这些类通常实现同一个接口或继承同一个父类实现要点关键 3 步定义共同接口 / 抽象类规范所有具体类的行为比如支付接口都有 pay() 方法实现具体类每个具体类实现接口的方法比如支付宝支付、微信支付创建工厂类提供静态方法根据参数返回对应的具体类实例?php// 1. 定义共同接口支付接口interfacePayment{publicfunctionpay(float$amount):string;}// 2. 实现具体类支付宝支付classAlipayimplementsPayment{publicfunctionpay(float$amount):string{return使用支付宝支付了{$amount}元;}}// 2. 实现具体类微信支付classWechatPayimplementsPayment{publicfunctionpay(float$amount):string{return使用微信支付了{$amount}元;}}// 3. 创建工厂类支付工厂classPaymentFactory{publicstaticfunctioncreatePayment(string$type):Payment{switch($type){casealipay:returnnewAlipay();casewechat:returnnewWechatPay();default:thrownewException(不支持的支付方式);}}}// 使用示例$paymentPaymentFactory::createPayment(alipay);echo$payment-pay(99.9);// 输出使用支付宝支付了 99.9 元适用场景有多个功能类似的类、需要根据参数创建实例且类型固定、不会频繁新增的场景开发高频场景固定的短信发送阿里云 / 腾讯云短信服务商不会频繁换图片 / 文件存储本地 / 阿里云 OSS / 腾讯 COS固定的几个存储方式数据导出Excel/PDF固定的导出格式支付方式固定的小商城仅微信 / 支付宝不会频繁新增支付渠道三、工厂方法模式核心概念定义一个工厂接口让具体工厂类去实现这个接口每个具体工厂负责创建一种具体产品。实现要点关键 3 步抽象产品定义产品的共同接口如 Payment 支付接口具体产品实现抽象产品接口的类如 Alipay、WechatPay抽象工厂定义创建产品的接口方法如 PaymentFactory 接口含 createPayment() 方法具体工厂实现抽象工厂接口负责创建某一种具体产品如 AlipayFactory 创建 AlipayWechatPayFactory 创建 WechatPay?php// 1. 抽象产品支付接口interfacePayment{publicfunctionpay(float$amount):string;}// 2. 具体产品支付宝支付classAlipayimplementsPayment{publicfunctionpay(float$amount):string{return使用支付宝支付了{$amount}元;}}// 2. 具体产品微信支付classWechatPayimplementsPayment{publicfunctionpay(float$amount):string{return使用微信支付了{$amount}元;}}// 3. 抽象工厂支付工厂接口interfacePaymentFactory{publicfunctioncreatePayment():Payment;}// 4. 具体工厂支付宝工厂只创建支付宝支付实例classAlipayFactoryimplementsPaymentFactory{publicfunctioncreatePayment():Payment{returnnewAlipay();}}// 4. 具体工厂微信支付工厂只创建微信支付实例classWechatPayFactoryimplementsPaymentFactory{publicfunctioncreatePayment():Payment{returnnewWechatPay();}}// 使用示例// 要使用支付宝就用支付宝工厂$alipayFactorynewAlipayFactory();$alipay$alipayFactory-createPayment();echo$alipay-pay(99.9);// 输出使用支付宝支付了 99.9 元// 要使用微信支付就用微信支付工厂$wechatFactorynewWechatPayFactory();$wechat$wechatFactory-createPayment();echo$wechat-pay(199.9);// 输出使用微信支付了 199.9 元适用场景业务类型会频繁新增、每个类型的逻辑复杂需要满足「开闭原则」新增功能不改原有代码的场景开发高频场景电商多支付渠道经常新增银联 / 数字人民币 / 境外支付等渠道新增时只加新类不改原有代码物流对接频繁新增快递公司每个快递的接口逻辑不同用工厂方法隔离营销活动模块满减 / 折扣 / 拼团 / 秒杀经常上新活动类型每个活动的计算逻辑独立总结这三种模式从保证全局唯一实例的资源优化到单工厂收拢创建逻辑的轻量解耦再到多工厂实现灵活扩展的进阶设计刚好覆盖了我们日常开发中从基础工具到复杂业务的绝大多数场景。还是那句话设计模式的核心是解决问题而非炫技式的硬套也不要为了设计而设计。希望大家都能在合适的场景用对设计模式写出更优雅、更易维护的 PHP 代码。

更多文章