PHP 委托设计模式详解:从硬编码到动态委派

小石头
小石头
发布时间:2026-10-13| 4人浏览过
原创

在 PHP 开发中,当核心类需要根据不同参数执行差异巨大的功能时,直接编写大量判断语句会导致耦合度高、难以维护。委托设计模式通过将具体任务的执行“委托”给专门的辅助对象来解决这一问题。

什么是委托设计模式?

委托(Delegation)是一种对象行为型设计模式。它的核心理念是:当一个类需要调用其他类的功能来完成任务时,不直接实现这些功能,而是创建一个辅助类,并将具体的操作指令传递给该辅助类的实例来完成。外部调用者并不感知底层具体是由哪个辅助对象在执行,从而实现了业务逻辑与具体实现的解耦。

未改进前的痛点:硬编码判断

假设我们需要构建一个简单的音乐播放器类 Cd,支持 MP3 和 MP4 两种格式。在未使用设计模式的初始阶段,我们往往会在类内部直接添加多个播放方法,并在调用处通过 if/else 进行类型判断。

缺点:

  1. 违反开闭原则:每增加一种新格式(如 FLAC),都需要修改 Cd 类的源码。
  2. 耦合度高:调用方必须知道具体的类名和方法名逻辑。
  3. 职责混乱:Cd 类既负责管理歌曲信息,又负责复杂的格式调度。

第1步:分析原始代码结构

在原始的 cd 类中,playMp3 和 playMp4 被分散在各个方法中。客户端代码必须显式判断 $type 的值来决定调用哪一个方法,这种写法随着功能增加会变得极其臃肿。

<?php 
class cd { 
    protected $cdInfo = array(); 
    public function addSong($song) { 
        $this->cdInfo[$song] = $song; 
    } 
    public function playMp3($song) { 
        return $this->cdInfo[$song] . '.mp3'; 
    } 
    public function playMp4($song) { 
        return $this->cdInfo[$song] . '.mp4'; 
    } 
} 
$oldCd = new cd;
$oldCd->addSong("1");
// ... 后续调用需依赖外部 if-else 判断类型

使用委托模式重构

为了解决上述问题,我们引入委托模式。核心思路是:定义一个统一的操作接口,让不同的格式处理类实现该接口,然后由核心类负责根据参数创建正确的处理对象并触发操作。

第2步:定义标准接口

首先,创建一个名为 Delegate 的接口,规定所有播放处理器都必须具备 playList 方法,确保行为的一致性。

namespace Tools;
interface Delegate {
    public function playList($list, $song);
}

第3步:实现具体的处理类

接下来,编写 Mp3 和 Mp4 类,分别处理对应的音频格式逻辑。它们都实现了 Delegate 接口。

class mp3 implements Delegate {
    public function playList($list, $song) {
        return $list[$song] . '.mp3';
    }
}

class mp4 implements Delegate {
    public function playList($list, $song) {
        return $list[$song] . '.mp4';
    }
}

第4步:重构核心委托类

最后,修改核心的 cdDelegate 类。它不再包含具体的播放逻辑,而是接收一个类型参数(如 'mp3'),利用 PHP 的动态特性自动实例化对应的处理类,并将任务委托给它。

class cdDelegate {
    protected $cdInfo = array();

    public function addSong($song) {
        $this->cdInfo[$song] = $song;
    }

    public function play($type, $song) {
        // 动态构建命名空间类名
        $name = '\Tools\\' . ucfirst($type);
        // 实例化处理对象
        $obj = new $name();
        // 委托执行
        return $obj->playList($this->cdInfo, $song);
    }
}

第5步:测试调用结果

在使用端,只需传递类型参数即可,无需关心背后的类是如何工作的。如果未来增加 MP4 以外的格式,只需新增实现 Delegate 的类,无需修改现有代码。

$newCd = new cdDelegate();
$newCd->addSong("1");
$newCd->addSong("2");
$newCd->addSong("3");

// 调用示例:传递参数自动识别处理方式
echo $newCd->play('mp3', '1');

总结与优势

通过上述重构,我们成功应用了 PHP 委托设计模式。其主要优势在于:

  • 降低耦合:核心类只负责路由和实例化,不参与具体业务逻辑。
  • 易于扩展:新增功能只需新增类,符合“对扩展开放,对修改关闭”的原则。
  • 职责清晰:每个类只关注自己的特定任务。

以上就是 PHP 常用设计模式中委托设计模式的详细内容,更多关于 PHP 面向对象编程的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。