从0开始学PHP面向对象内容之常用设计模式(适配器,桥接,装饰器)

二,结构型设计模式

上两期咱们讲了创建型设计模式 ,都有 单例模式工厂模式抽象工厂模式建造者模式原型模式 五个设计模式。

这期咱们讲结构型设计模式

1、适配器模式(Adapter)

什么是适配器模式?

适配器模式是一种结构型设计模式,用于将一个类的接口转换为另一个接口,以满足客户端的使用需求,它允许本来由于接口不兼容而不能一起工作的类可以协同工作。

适配器模式的核心概念

1、目标接口(Target) :客户端需要的接口。

2、适配者(Adaptee) :已有的类,其他接口与目标接口普不兼容

3、适配器(Adapter):将适配者接口转换为目标接口

适配器模式的类型

对象适配器 :通过组合(包含适配者对象)实现适配
类适配器:通过继承适配者实现适配(php不支持多继承,因此 类的适配器较少使用,其他语言可能会多一些)

适配器模式的结构

Client端 :客户端,使用Target 接口
Target :目标接口
Adaptee :适配者类,具有不兼容接的接口
Adapter :适配器类,实现Target 接口,并包含Adaptee的引用

使用场景

1、当你希望使用现有的类,但接口不符合需求

2、当你想复用现有的类,而无需修改它

3、需要兼容多个版本或不同的接口系统

实现

php 复制代码
<?php
// 目标接口 (Target)
interface Target {
    public function request();
}

// 适配者 (Adaptee)
class Adaptee {
    public function specificRequest() {
        return "Adaptee's specific behavior";
    }
}

// 适配器 (Adapter)
class Adapter implements Target {
    private $adaptee;

    public function __construct(Adaptee $adaptee) {
        $this->adaptee = $adaptee;
    }

    public function request() {
        // 将适配者的方法适配为目标方法
        return $this->adaptee->specificRequest();
    }
}

// 客户端代码 (Client)
function clientCode(Target $target) {
    echo $target->request();
}

// 使用适配器模式
$adaptee = new Adaptee();
$adapter = new Adapter($adaptee);
clientCode($adapter);

输出

Adaptee's specific behavior

应用案例

1、数据库适配器 :PHP 中常用的 PDO 就是一个数据库适配器,统一了对多种数据库的操作接口。

2、日志适配器 :适配不同的日志系统(如 Monolog 和其他日志库)。

3、跨平台接口:将平台 A 的 API 转换为平台 B 的 API 形式。

小结

优点

1、适配器隔离了客户端与具体类的实现,遵循开闭原则

2、提高代码的复用性,现有的类可以被重复利用。

3、增强代码的灵活性,使得类之间协作更方便

缺点

增加了系统的复杂性

对于复杂的适配逻辑,可能导致适配器代码较为繁琐

2、桥接模式(Bridge)

什么是桥接模式

桥接模式是一种结构型设计模式,它通过将抽象部分与实现部分分离,使它们可以独立变化。它的核心思想是使用组合而非继承来解决类的多维度变化问题。

桥接模式的概念

1、抽象部分(Abstraction) :定义高层的控制逻辑,依赖于实现部分(Implementor)。

2、实现部分(Implementor) :定义具体的实现接口,不与抽象部分直接耦合

3、细化抽象 :抽象部分的具体子类

4、具体实现:实现部分的具体实现

通过将这两部分分离,可以独立扩展两者,而不会互相影响

桥接模式的结构

1、Abstraction :抽象类,维护对Implementor 的引用。

2、Implementor :实现接口,为具体实现提供方法。

3、RefinedAbstraction :抽象类的扩展,实现具体的功能。

4、ConcreteImplementor:实现接口的具体类

使用场景

1、类有多个纬度的变化 ,且每个纬度都需要独立扩展

2、希望避免使用继承 来扩展类时。

3、需要再运行时切换

实现

以下是一个简单的例子:实现多种形状(Shape),支持不同的颜色(Color)

php 复制代码
<?php
// 实现接口 (Implementor)
interface Color {
    public function applyColor();
}

// 具体实现类 (ConcreteImplementor)
class Red implements Color {
    public function applyColor() {
        return "Red";
    }
}

class Blue implements Color {
    public function applyColor() {
        return "Blue";
    }
}

// 抽象类 (Abstraction)
abstract class Shape {
    protected $color;

    public function __construct(Color $color) {
        $this->color = $color;
    }

    abstract public function draw();
}

// 细化抽象类 (RefinedAbstraction)
class Circle extends Shape {
    public function draw() {
        return "Circle colored in " . $this->color->applyColor();
    }
}

class Square extends Shape {
    public function draw() {
        return "Square colored in " . $this->color->applyColor();
    }
}

// 客户端代码 (Client)
$redColor = new Red();
$blueColor = new Blue();

$redCircle = new Circle($redColor);
$blueSquare = new Square($blueColor);

echo $redCircle->draw(); // 输出: Circle colored in Red
echo $blueSquare->draw(); // 输出: Square colored in Blue

桥接模式的实现过程

1、定义实现接口 :实现部分的接口,为具体实现提供规范

2、实现具体类 :具体实现的接口,具有独立的功能

3、定义抽象类 :抽象部分的基类,包含实现接口的引用

4、实现细化类 :抽象类的具体子类,实现客户端需要的具体功能

5、组合抽象与实现:通过组合的方式,将实现部分传递给抽象部分

实际应用

1、图形库 :将图形(形状)和渲染方式分离,例如形状可以时圆形,矩形而渲染方式可以时适量渲染,栅格渲染

2、设备和控制器 :控制器(抽象部分)独立于设备(实现部分),如遥控器与电视机

3、日志系统:日志框架可以有多种日志目标(文件,数据库),日志格式和目标分离

小结

优点

1、分离抽象与实 现:两者可以独立扩展符合单一职责原则

2、动态切换实现 ;运行时可以轻松替换实现部分

3、减少子类数量 :避免以为多维度扩展导致的类爆炸
缺点
增加复杂性 :抽象与实现的分离增加了系统的复杂性
可能导致过度设计:如果维度不多或变化不频繁,使用桥接模式可能显得多余

3、 装饰器模式(Decorator)

什么是装饰器模式

装饰器模式是一种结构型设计模式,它允许动态地向对象添加新功能,而不需要修改对象地定义或使用继承,装饰器模式使用一种对象包装另一种对象地方式,为被包装对象提供额外地功能

装饰器模式地核心概念

1、组件(Component) :定义对象接口

2、具体组件(Concrete Component) :实现组件接口地类,是被装饰地对象

2、装饰器(Decorator) :实现组件接口,同时包含一个指向组件对象地引用,用户扩展组件功能

4、具体装饰器(Concrete Decorator):实现装饰器功能,向被装饰对象添加额外地功能

使用场景

1、不希望修改已有代码 但需要增加功能时

2、希望在运行时动态扩展对象功能

3、需要组合多个装饰功能,并保持功能独立

实现

以下是一个简单的例子:装饰一段文本,支持多种功能如加粗、斜体等。

php 复制代码
<?php
// 组件接口 (Component)
interface Text {
    public function render(): string;
}

// 具体组件 (ConcreteComponent)
class PlainText implements Text {
    private $text;

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

    public function render(): string {
        return $this->text;
    }
}

// 装饰器 (Decorator)
abstract class TextDecorator implements Text {
    protected $text;

    public function __construct(Text $text) {
        $this->text = $text;
    }
}

// 具体装饰器 (ConcreteDecorator)
class BoldText extends TextDecorator {
    public function render(): string {
        return "<b>" . $this->text->render() . "</b>";
    }
}

class ItalicText extends TextDecorator {
    public function render(): string {
        return "<i>" . $this->text->render() . "</i>";
    }
}

// 客户端代码 (Client)
$plainText = new PlainText("Hello, World!");

// 添加加粗功能
$boldText = new BoldText($plainText);
echo $boldText->render(); // 输出: <b>Hello, World!</b>

// 添加斜体功能
$italicText = new ItalicText($boldText);
echo $italicText->render(); // 输出: <i><b>Hello, World!</b></i>

实际应用

1、**日志系统:**装饰日志功能:将日志存储到文件、发送到远程服务器或格式化为 JSON。

2、用户界面(UI)组件 :如 Qt 和

Swing,按钮可以动态添加边框、阴影等样式。

3、数据流处理 :PHP 中的 Stream,通过包装实现加密、压缩等功能。

4、动态权限检查:为服务接口动态添加权限验证、日志记录等功能。

小结

优点

1、开闭原则 :无需修改原始对象即可扩展功能

2、高扩展性 :可以创建任意数量的装饰器类,并以灵活的方式组合

3、运动时动态性:可以动态的为对象添加或移除功能
缺点

1、增加复杂性:多层装饰器会导致系统复杂度上升,调试变得困难

2、依赖组件接口:装饰器与被装饰的对象都必须实现相同接口

总结

桥接模式适配器模式装饰器模式 对比

相关推荐
大耳朵土土垚1 小时前
【Linux】日志设计模式与实现
linux·运维·设计模式
小王子10244 小时前
设计模式Python版 组合模式
python·设计模式·组合模式
字节全栈_rJF6 小时前
概述、 BGP AS 、BGP 邻居、 BGP 更新源 、BGP TTL 、BGP路由表、 BGP 同步
网络·智能路由器·php
linwq86 小时前
设计模式学习(二)
java·学习·设计模式
恋猫de小郭7 小时前
Android Studio 正式版 10 周年回顾,承载 Androider 的峥嵘十年
android·ide·android studio
dal118网工任子仪8 小时前
92,[8] 攻防世界 web Web_php_wrong_nginx_config
开发语言·php
aaaweiaaaaaa10 小时前
php的使用及 phpstorm环境部署
android·web安全·网络安全·php·storm
工程师老罗12 小时前
Android记事本App设计开发项目实战教程2025最新版Android Studio
android
doubt。16 小时前
3.攻防世界Web_php_unserialize
网络·安全·web安全·网络安全·php·代码复审
pengyu16 小时前
系统化掌握 Dart 编程之异常处理(二):从防御到艺术的进阶之路
android·flutter·dart