php23种设计模式 代码示例

PHP常用函数大全及示例代码 本文将介绍一些常用的PHP函数,并提供相应的示例代码,帮助读者更好地理解和运用这些函数。implode()函数用于将数组中的元素组合起来,形成一个字符串,并使用指定的分隔符进行连接。strpos()函数用于在字符串中查找指定字符串首次出现的位置,并返回该位置的索引值。substr()函数用于提取字符串的子串,可以根据指定的起始位置和长度来截取字符串。explode()函数用于将字符串按照指定的分隔符进行分割,并返回一个数组。strlen()函数用于获取字符串的长度,即字符串中字符的个数。 阅读详情

创建型模式

单例模式

一种常用的软件设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。
以下是使用 PHP 编写的单例模式示例代码:

<?php

class Singleton
{
    // 私有静态变量,保存类的唯一实例
    private static $instance = null;

    // 私有构造函数,防止外部通过 new 创建实例
    private function __construct() {
        // 构造方法的代码
    }

    // 公共静态方法,提供获取类实例的访问点
    public static function getInstance() {
        if (self::$instance == null) {
            // 如果实例不存在,则创建一个实例并将其存储在静态变量中
            self::$instance = new Singleton();
        }

        // 返回类的唯一实例
        return self::$instance;
    }

    // 禁止克隆实例
    private function __clone() {
        // 克隆方法的代码
    }

    // 禁止反序列化实例
    private function __wakeup() {
        // 反序列化方法的代码
    }

    // 这里可以添加其他的方法和属性
}

// 使用示例
$singleton1 = Singleton::getInstance();
$singleton2 = Singleton::getInstance();

// 由于单例模式的特性,$singleton1 和 $singleton2 是同一个实例
var_dump($singleton1 === $singleton2); // 输出:bool(true)

?>

在这个示例中,`Singleton` 类使用了几个关键技术来实现单例模式:

- **私有静态变量**:`$instance` 用于保存类的唯一实例。
- **私有构造函数**:防止外部通过 `new` 关键字创建类的实例。
- **公共静态方法 `getInstance`**:提供全局访问点来获取类实例。如果实例不存在,
则创建一个实例;如果已存在,则直接返回该实例。
- **私有方法 `__clone` 和 `__wakeup`**:禁止通过克隆和反序列化的方式创建新的实例。

使用单例模式可以确保在整个应用程序中,类的对象只有一个,这在需要全局状态或资源时非常有用。
 

工厂方法模式

是一种创建型设计模式,它定义了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类中进行。

以下是使用 PHP 编写的工厂方法模式示例代码:

php

<?php

// 产品接口
interface Product {
    public function doSomething();
}

// 实现产品接口的具体产品类
class ConcreteProductA implements Product {
    public function doSomething() {
        echo "ConcreteProductA do something.\n";
    }
}

class ConcreteProductB implements Product {
    public function doSomething() {
        echo "ConcreteProductB do something.\n";
    }
}

// 工厂接口
interface Factory {
    public function createProduct();
}

// 实现工厂接口的具体工厂类
class ConcreteFactoryA implements Factory {
    public function createProduct() {
        return new ConcreteProductA();
    }
}

class ConcreteFactoryB implements Factory {
    public function createProduct() {
        return new ConcreteProductB();
    }
}

// 客户端代码
$factoryA = new ConcreteFactoryA();
$productA = $factoryA->createProduct();
$productA->doSomething();

$factoryB = new ConcreteFactoryB();
$productB = $factoryB->createProduct();
$productB->doSomething();

?>

在这个示例中:

  • Product 是一个产品接口,定义了所有产品必须实现的方法 doSomething。
  • ConcreteProductA 和 ConcreteProductB 是实现了 Product 接口的具体产品类。
  • Factory 是一个工厂接口,定义了工厂必须实现的方法 createProduct。
  • ConcreteFactoryA 和 ConcreteFactoryB 是实现了 Factory 接口的具体工厂类,分别负责创建 ConcreteProductA 和 ConcreteProductB 的实例。
  • 客户端代码通过创建具体的工厂实例,并调用 createProduct 方法来获取产品实例,然后调用产品实例的 doSomething 方法。

工厂方法模式的好处是:

  • 封装性:客户端不需要知道具体的产品是如何创建的,只需要知道如何使用。
  • 扩展性:当需要添加新的产品时,只需要添加相应的具体产品类和具体工厂类,无需修改现有代码。
  • 解耦:将产品的创建和使用分离,降低了类之间的耦合度。

抽象工厂模式

是一种创建型设计模式,它提供了一种创建一系列相关或依赖对象的接口,而无需指定它们具体的类。这种模式通常用于当需要生成多个系列对象时,并且希望这些对象的创建独立于客户端。

以下是使用 PHP 编写的抽象工厂模式示例代码:

php

<?php

// 抽象产品 A
interface ProductA {
    public function doSomething();
}

// 抽象产品 B
interface ProductB {
    public function doSomething();
}

// 具体产品 A1
class ConcreteProductA1 implements ProductA {
    public function doSomething() {
        echo "ConcreteProductA1 does something.\n";
    }
}

// 具体产品 B1
class ConcreteProductB1 implements ProductB {
    public function doSomething() {
        echo "ConcreteProductB1 does something.\n";
    }
}

// 抽象工厂
interface AbstractFactory {
    public function createProductA();
    public function createProductB();
}

// 具体工厂 1
class ConcreteFactory1 implements AbstractFactory {
    public function createProductA() {
        return new ConcreteProductA1();
    }

    public function createProductB() {
        return new ConcreteProductB1();
    }
}

// 客户端代码
$factory = new ConcreteFactory1();
$productA = $factory->createProductA();
$productB = $factory->createProductB();

$productA->doSomething();
$productB->doSomething();

?>

在这个示例中:

  • ProductA 和 ProductB 是两个抽象产品接口,定义了各自的方法 doSomething。
  • ConcreteProductA1 和 ConcreteProductB1 是实现了各自抽象产品接口的具体产品类。
  • AbstractFactory 是一个抽象工厂接口,定义了创建所有抽象产品的方法 createProductA 和 createProductB。
  • ConcreteFactory1 是实现了 AbstractFactory 接口的具体工厂类,负责创建 ConcreteProductA1 和 ConcreteProductB1 的实例。
  • 客户端代码通过创建具体工厂的实例,然后调用工厂的 createProductA 和 createProductB 方法来获取具体产品实例,最后调用产品实例的 doSomething 方法。

抽象工厂模式的好处是:

  • 隔离复杂对象的创建和使用:客户端不需要知道具体对象的创建细节,只需要通过工厂接口与具体对象交互。
  • 易于扩展:增加一个新的产品系列时,只需要添加相应的具体产品类和具体工厂类,无需修改现有代码。
  • 保证产品的一致性:由于具体工厂负责创建一系列相关联或依赖的产品,可以确保客户端使用的产品是协调一致的。

抽象工厂模式适用于对象创建的逻辑复杂且具有多个产品系列时,需要将对象创建的逻辑集中管理,同时保持客户端代码的简洁性和可维护性。

原型模式

是一种创建型设计模式,它允许你复制一个现有的对象,而不是通过实例化类来创建新对象。这种模式特别适用于创建复杂对象或需要大量资源的对象时,因为它可以避免昂贵的构造过程。

以下是使用 PHP 编写的原型模式示例代码:

php

<?php

// 定义一个可克隆的类
class Prototype {
    private $data;

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

    public function getData() {
        return $this->data;
    }

    public function setData($data) {
        $this->data = $data;
    }

    // 实现 __clone 方法,用于克隆对象
    public function __clone() {
        // 可以在这里添加一些克隆时需要执行的代码
    }
}

// 客户端代码
$original = new Prototype("原始对象的数据");

// 克隆对象
$cloned = clone $original;

// 修改克隆对象的数据
$cloned->setData("克隆对象的新数据");

// 显示原始对象和克隆对象的数据
echo "原始对象数据: " . $original->getData() . "\n";
echo "克隆对象数据: " . $cloned->getData() . "\n";

在这个示例中:

  • Prototype 类是一个可克隆的类,它包含一个私有属性 $data 和相应的 getter 和 setter 方法。
  • Prototype 类实现了 __clone 方法,这个方法在对象被克隆时会被调用。你可以在这里添加一些克隆时需要执行的代码,比如初始化资源或重置状态。
  • 客户端代码首先创建了一个 Prototype 类的实例 $original。
  • 使用 clone 关键字克隆 $original 对象,创建了一个新的实例 $cloned。
  • 修改克隆对象 $cloned 的数据,显示原始对象和克隆对象的数据。

原型模式的优点包括:

  • 简化对象创建过程:通过克隆现有的对象,可以避免复杂的构造过程。
  • 提高性能:对于创建复杂对象或需要大量资源的对象,克隆可以显著提高性能。
  • 灵活性:可以轻松地修改克隆对象的属性,而不影响原始对象。

原型模式通常用于以下场景:

  • 创建新对象的成本较高,或者需要复制的对象初始化很复杂。
  • 需要复制的对象是可变对象,即对象的状态可以改变。
  • 需要复制的对象是图形或复杂结构的对象,如树形结构。

建造者模式

(Builder Pattern)是一种创建型设计模式,用于构建一个复杂对象,同时允许用户只通过指定复杂对象的类型和内容就能构建它们,隐藏了内部的构建细节。

以下是使用 PHP 编写的建造者模式示例代码:

php

<?php

// 产品类
class Product {
    private $parts = [];

    public function addPart($part) {
        $this->parts[] = $part;
    }

    public function listParts() {
        echo "Product parts: \n";
        foreach ($this->parts as $part) {
            echo "- " . $part . "\n";
        }
    }
}

// 建造者接口
interface Builder {
    public function addPart1();
    public function addPart2();
    public function addPart3();
    public function getResult();
}

// 具体建造者
class ConcreteBuilder implements Builder {
    private $product;

    public function __construct() {
        $this->product = new Product();
    }

    public function addPart1() {
        $this->product->addPart("Part 1");
    }

    public function addPart2() {
        $this->product->addPart("Part 2");
    }

    public function addPart3() {
        $this->product->addPart("Part 3");
    }

    public function getResult() {
        return $this->product;
    }
}

// 导演类
class Director {
    private $builder;

    public function setBuilder(Builder $builder) {
        $this->builder = $builder;
    }

    public function construct() {
        $this->builder->addPart1();
        $this->builder->addPart2();
        $this->builder->addPart3();
    }

    public function getFinalProduct() {
        return $this->builder->getResult();
    }
}

// 客户端代码
$builder = new ConcreteBuilder();
$director = new Director();
$director->setBuilder($builder);
$director->construct();

$product = $director->getFinalProduct();
$product->listParts();

在这个示例中:

  • Product 类是最终要构建的复杂对象。
  • Builder 接口定义了用于创建产品的方法。
  • ConcreteBuilder 类实现了 Builder 接口,具体实现了构建步骤。
  • Director 类负责使用 Builder 接口来构建产品,它定义了构建过程的步骤。
  • 客户端代码创建了 ConcreteBuilder 的实例,将其设置给 Director,然后调用 Director 的 construct 方法来构建产品。最后,它从 Director 获取最终的产品并展示其组成部分。

建造者模式的优点包括:

  • 封装性:创建复杂对象的代码和使用这些对象的代码是分离的。
  • 灵活性:可以独立地改变产品的创建过程,同时不影响使用这些产品的对象。
  • 可扩展性:添加新的产品创建步骤或创建新的具体建造者类不会影响其他代码。

建造者模式适用于创建复杂对象,且这些对象的创建过程和表示状态是分离的场景。

结构型设计模式

适配器模式

(Adapter Pattern)是一种结构型设计模式,它允许不兼容的接口之间的交互。适配器模式通常用于让现有的类与另一个类兼容,而不是修改现有类源代码。

以下是使用 PHP 编写的适配器模式示例代码:

php
<?php

// 目标接口,定义客户端使用的特定领域相关的接口
interface Target {
    public function request();
}

// 客户端代码,依赖于目标接口
class Client {
    public function doSomethingWithTarget(Target $target) {
        $target->request();
    }
}

// 适配者类,有一个不兼容的接口
class Adaptee {
    public function specificRequest() {
        echo "Doing something specific.\n";
    }
}

// 适配器类,将适配者类转换为目标接口
class Adapter implements Target {
    private $adaptee;

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

    public function request() {
        $this->adaptee->specificRequest();
    }
}

// 客户端使用适配器模式的示例
$adaptee = new Adaptee();
$adapter = new Adapter($adaptee);
$client = new Client();

// 客户端通过适配器使用不兼容的适配者类
$client->doSomethingWithTarget($adapter);

在这个示例中:

  • Target 接口定义了客户端使用的特定领域相关的接口。
  • Client 类是使用 Target 接口的客户端代码。
  • Adaptee 类有一个不兼容的接口,即 specificRequest 方法。
  • Adapter 类实现了 Target 接口,并通过构造函数接受一个 Adaptee 实例。它将 Adaptee 的 specificRequest 方法映射到 Target 接口的 request 方法。

适配器模式的优点包括:

  • 兼容性:允许不兼容的接口之间进行交互。
  • 灵活性:可以轻松地添加更多适配器来支持其他不兼容的类。
  • 解耦:客户端代码不需要知道适配者类的细节。

适配器模式通常用于以下场景:

  • 一个已有的类需要与另一个类协同工作,但是接口不兼容。
  • 需要复用一些现有的类,但是不想修改它们的源代码。
  • 需要统一多个类的接口,使其可以一起工作。

适配器模式有两种变体:对象适配器和类适配器。上面的示例是一个对象适配器,它使用组合的方式将适配者包装在适配器中。类适配器则使用多重继承(如果语言支持的话)来实现。

桥接模式

(Bridge Pattern)是一种结构型设计模式,用于将抽象部分与其实现部分分离,使它们可以独立地变化。这种模式创建了抽象和实现两个层次,允许在运行时动态地将抽象部分与不同的实现部分绑定在一起。

以下是使用 PHP 编写的桥接模式示例代码:

php

<?php

// 抽象类
abstract class Abstraction {
    protected $implementation;

    // 在构造函数中接收实现部分
    public function __construct(Implementation $implementation) {
        $this->implementation = $implementation;
    }

    // 声明一个方法,允许使用实现部分的方法
    abstract public function operation();
}

// 扩展抽象类的具体类
class RefinedAbstraction extends Abstraction {
    public function operation() {
        echo "RefinedAbstraction: " . $this->implementation->operation() . "\n";
    }
}

// 实现接口
interface Implementation {
    public function operation();
}

// 实现接口的具体类
class ConcreteImplementationA implements Implementation {
    public function operation() {
        return "Implementation A";
    }
}

class ConcreteImplementationB implements Implementation {
    public function operation() {
        return "Implementation B";
    }
}

// 客户端代码
$implementationA = new ConcreteImplementationA();
$implementationB = new ConcreteImplementationB();

$abstraction = new RefinedAbstraction($implementationA);
$abstraction->operation(); // 使用实现 A

$abstraction = new RefinedAbstraction($implementationB);
$abstraction->operation(); // 切换到实现 B

在这个示例中:

  • Abstraction 是一个抽象类,它包含一个对 Implementation 接口的引用,并定义了一个 operation 方法。
  • RefinedAbstraction 是 Abstraction 的具体实现,它实现了 operation 方法,并调用实现部分的 operation 方法。
  • Implementation 是一个实现接口,定义了所有实现类必须实现的 operation 方法。
  • ConcreteImplementationA 和 ConcreteImplementationB 是实现了 Implementation 接口的具体类。
  • 客户端代码创建了实现部分的实例,并将它们传递给 RefinedAbstraction 的实例。然后调用 operation 方法,以展示桥接模式的动态绑定特性。

桥接模式的优点包括:

  • 解耦抽象和实现:允许抽象和实现独立地变化。
  • 扩展性:可以容易地添加新的实现类,而不需要修改抽象类或客户端代码。
  • 复用性:相同的实现可以在不同的抽象类中使用。

桥接模式适用于以下场景:

  • 需要将一个类的功能划分为多个独立变化的部分,且希望它们可以独立地进行扩展。
  • 需要复用现有的类,但它们不完全符合需求。
  • 需要通过动态绑定的方式,将一个抽象与多个实现部分进行组合。

组合模式

(Composite Pattern)是一种结构型设计模式,用于将对象组合成树形结构以表示“部分-整体”的层次结构。这种模式使得用户对单个对象和组合对象的使用具有一致性。

以下是使用 PHP 编写的组合模式示例代码:

php

<?php

// 组件接口,定义了所有对象的一致操作方式
interface Component {
    public function operation();
}

// 叶节点,实现组件接口
class Leaf implements Component {
    private $data;

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

    public function operation() {
        echo "Leaf: " . $this->data . "\n";
    }
}

// 组合节点,也实现组件接口
class Composite implements Component {
    private $children = [];

    public function add(Component $child) {
        $this->children[] = $child;
    }

    public function remove(Component $child) {
        $this->children = array_filter($this->children, function ($c) use ($child) {
            return $c !== $child;
        });
    }

    public function operation() {
        echo "Composite\n";
        foreach ($this->children as $child) {
            $child->operation();
        }
    }
}

// 客户端代码
$leaf1 = new Leaf("Leaf 1");
$leaf2 = new Leaf("Leaf 2");
$composite1 = new Composite();
$composite2 = new Composite();

$composite1->add($leaf1);
$composite1->add($leaf2);
$composite2->add($composite1);

// 客户端使用组合结构
$composite2->operation();

在这个示例中:

  • Component 是一个接口,定义了组合中所有对象的一致操作方式 operation。
  • Leaf 是一个叶节点类,实现了 Component 接口。叶节点没有子节点,只包含一些数据。
  • Composite 是一个组合节点类,也实现了 Component 接口。它可以包含子节点,这些子节点可以是叶节点或其他组合节点。
  • Composite 类提供了 add 和 remove 方法来管理子节点。
  • 客户端代码创建了一些叶节点和组合节点,将叶节点添加到组合节点中,并调用组合节点的 operation 方法来展示组合模式的层次结构。

组合模式的优点包括:

  • 透明性:用户不需要知道组合结构内部是叶节点还是组合节点,可以一致地对待它们。
  • 灵活性:可以灵活地添加叶节点和组合节点,构建复杂的树形结构。
  • 扩展性:可以容易地扩展组合结构,添加新的叶节点和组合节点类型。

组合模式通常用于以下场景:

  • 需要表示对象的“部分-整体”层次结构。
  • 希望用户对单个对象和组合对象的使用具有一致性。
  • 需要能够自由地添加叶节点和组合节点,构建复杂的树形结构。

外观模式

(Facade Pattern)是一种结构型设计模式,它提供了一个统一的高层接口,用于访问子系统中的一群接口。外观模式定义了一个一致的高层接口,让子系统更容易使用。

以下是使用 PHP 编写的外观模式示例代码:

php

<?php

// 子系统类
class SubsystemOne {
    public function operation1() {
        echo "SubsystemOne: Operation 1\n";
    }
}

class SubsystemTwo {
    public function operation2() {
        echo "SubsystemTwo: Operation 2\n";
    }
}

class SubsystemThree {
    public function operation3() {
        echo "SubsystemThree: Operation 3\n";
    }
}

// 外观类
class Facade {
    private $subsystemOne;
    private $subsystemTwo;
    private $subsystemThree;

    public function __construct() {
        $this->subsystemOne = new SubsystemOne();
        $this->subsystemTwo = new SubsystemTwo();
        $this->subsystemThree = new SubsystemThree();
    }

    public function operation() {
        echo "Facade: Starting operation.\n";
        $this->subsystemOne->operation1();
        $this->subsystemTwo->operation2();
        $this->subsystemThree->operation3();
        echo "Facade: Finishing operation.\n";
    }
}

// 客户端代码
$facade = new Facade();
$facade->operation();

在这个示例中:

  • SubsystemOne、SubsystemTwo 和 SubsystemThree 是子系统类,每个类都有自己的操作。
  • Facade 类是外观类,它提供了一个方法 operation,该方法协调子系统中的多个操作。
  • 外观类的构造函数中创建了所有子系统类的实例,以便在 operation 方法中使用。
  • 客户端代码通过外观类的 operation 方法来访问子系统的操作,而不需要直接与子系统类交互。

外观模式的优点包括:

  • 简化接口:为客户端提供了一个简化的接口,隐藏了子系统的复杂性。
  • 解耦:客户端与子系统之间通过外观类进行通信,降低了耦合度。
  • 易于扩展:添加新的子系统或修改现有子系统的操作,通常不需要修改客户端代码。

外观模式通常用于以下场景:

  • 子系统非常复杂或具有多个依赖关系。
  • 需要提供一个客户端友好的接口来访问复杂的子系统。
  • 希望减少客户端与复杂子系统之间的依赖关系。

代理模式

(Proxy Pattern)是一种结构型设计模式,它为另一个对象提供一个代替或占位符,以控制对它的访问。代理可以在不改变对象的代码的情况下,为对象添加额外的功能操作。

以下是使用 PHP 编写的代理模式示例代码:

php

<?php

// 真实主题接口
interface Subject {
    public function doSomething();
}

// 真实主题实现
class RealSubject implements Subject {
    public function doSomething() {
        echo "RealSubject is doing something.\n";
    }
}

// 代理类,也实现主题接口
class Proxy implements Subject {
    private $realSubject;

    public function __construct() {
        $this->realSubject = null;
    }

    public function doSomething() {
        if ($this->realSubject === null) {
            $this->realSubject = new RealSubject();
        }
        // 代理可以在此处添加额外的操作
        echo "Proxy: Before real subject do something.\n";
        $this->realSubject->doSomething();
        echo "Proxy: After real subject do something.\n";
    }
}

// 客户端代码
$proxy = new Proxy();
$proxy->doSomething(); // 通过代理访问真实主题

在这个示例中:

  • Subject 是一个接口,定义了代理和真实主题共有的操作。
  • RealSubject 是实现了 Subject 接口的真实主题类。
  • Proxy 是代理类,也实现了 Subject 接口。它包含对 RealSubject 的引用,并在调用真实主题的方法前后可以添加额外的操作。
  • 客户端代码通过 Proxy 类来访问 RealSubject 类的方法。

代理模式的优点包括:

  • 控制访问:可以在不修改真实主题的情况下,通过代理类控制对真实主题的访问。
  • 增加额外操作:可以在代理类中添加额外的逻辑,如访问前的检查、访问后的清理等。
  • 提高安全性:可以控制对真实主题的访问权限。

代理模式通常用于以下场景:

  • 需要为真实的对象提供一个间接层。
  • 需要控制对真实对象的访问,或者在访问时执行额外的操作。
  • 需要实现访问控制或延迟初始化。

代理模式有几种变体,如远程代理、虚拟代理、保护代理和智能引用等,每种变体都适用于不同的场景和需求。

享元模式

(Flyweight Pattern)主要用于减少创建对象的数量,通过共享来高效地管理对象。以下是使用 PHP 编写的享元模式示例代码:

php

<?php

// 享元接口
interface Flyweight {
    public function operation($extrinsicState);
}

// 具体享元类
class ConcreteFlyweight implements Flyweight {
    private $intrinsicState; // 内部状态,通常由对象所拥有

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

    public function operation($extrinsicState) {
        // 操作通常涉及内部状态和外部状态
        echo "ConcreteFlyweight with intrinsic state {$this->intrinsicState} and extrinsic state $extrinsicState\n";
    }
}

// 享元工厂,用于创建和管理享元对象
class FlyweightFactory {
    private $flyweights = [];

    public function getFlyweight($intrinsicState) {
        if (!isset($this->flyweights[$intrinsicState])) {
            $this->flyweights[$intrinsicState] = new ConcreteFlyweight($intrinsicState);
        }
        return $this->flyweights[$intrinsicState];
    }
}

// 客户端代码
$factory = new FlyweightFactory();

// 获取享元对象,执行操作
$flyweightX = $factory->getFlyweight("intrinsicStateX");
$flyweightY = $factory->getFlyweight("intrinsicStateY");

$flyweightX->operation("extrinsicStateA");
$flyweightY->operation("extrinsicStateB");

在这个示例中:

  • Flyweight 是一个接口,定义了享元对象的操作。
  • ConcreteFlyweight 是一个具体享元类,实现了 Flyweight 接口。它具有内部状态(固有状态),这是每个对象唯一的部分。
  • FlyweightFactory 是享元工厂类,负责创建和管理享元对象。它使用一个数组来存储已经创建的享元实例,确保每个内部状态只创建一个实例。
  • 客户端代码通过享元工厂来获取享元对象,并执行操作。

享元模式的关键点在于区分内部状态和外部状态:

  • 内部状态:存储在享元对象内部,通常由享元对象所拥有,是对象所固有的。
  • 外部状态:通常由客户端提供,通常在享元对象的操作中使用,但是并不存储在享元对象内部。

享元模式适用于对象数量很多,但对象的内部状态可以外部化,并且可以通过传参来改变的场景。这种模式可以显著减少内存消耗,提高程序性能。

装饰模式

(Decorator Pattern)是一种结构型设计模式,允许用户在不改变对象自身的基础上,向一个对象添加新的功能。这种模式通过创建一个包装对象,也就是装饰者,来包裹实际对象。装饰者持有实际对象的实例,并定义一个与实际对象相同的接口。

以下是使用 PHP 编写的装饰模式示例代码:

php

<?php

// 抽象组件
interface Component {
    public function operation();
}

// 具体组件
class ConcreteComponent implements Component {
    public function operation() {
        echo "ConcreteComponent operation\n";
    }
}

// 抽象装饰者,也实现组件接口
abstract class Decorator implements Component {
    protected $component;

    public function __construct(Component $component) {
        $this->component = $component;
    }

    public function operation() {
        $this->component->operation();
    }
}

// 具体装饰者 A
class ConcreteDecoratorA extends Decorator {
    public function operation() {
        parent::operation();
        echo "ConcreteDecoratorA added behavior\n";
    }
}

// 具体装饰者 B
class ConcreteDecoratorB extends Decorator {
    public function operation() {
        parent::operation();
        echo "ConcreteDecoratorB added behavior\n";
    }
}

// 客户端代码
$simple = new ConcreteComponent();
$simple->operation(); // 使用简单组件

$decoratedA = new ConcreteDecoratorA($simple);
$decoratedA->operation(); // 使用装饰后的组件 A

$decoratedAB = new ConcreteDecoratorB($decoratedA);
$decoratedAB->operation(); // 使用装饰后的组件 A 和 B

在这个示例中:

  • Component 是一个接口,定义了可以动态添加职责的对象类型。
  • ConcreteComponent 是一个具体组件,实现了 Component 接口。
  • Decorator 是一个抽象装饰者,也实现了 Component 接口。它持有一个 Component 类型的成员,这样就可以装饰任何 Component 类型的对象。
  • ConcreteDecoratorA 和 ConcreteDecoratorB 是具体装饰者类,它们继承自 Decorator 类,并在 operation 方法中添加了额外的行为。
  • 客户端代码演示了如何使用简单组件和装饰后的组件。

装饰模式的优点包括:

  • 动态添加职责:可以在运行时添加或修改对象的行为,而不需要修改对象的代码。
  • 单一职责:每个装饰者只关注添加一个职责,符合单一职责原则。
  • 开闭原则:系统应该对扩展开放,对修改封闭。装饰模式允许扩展新的行为,而不需要修改现有代码。

装饰模式通常用于以下场景:

  • 需要动态地给一个对象添加额外的职责。
  • 通过继承机制扩展系统功能时,面临类数量急剧增加的问题。
  • 需要通过一种无须修改对象自身的情况下,动态地给对象添加职责。

行为设计模式

解释器模式

(Interpreter Pattern)是一种行为型设计模式,用于定义一个语言的文法表示,并构建一个解释器,这个解释器可以用来解释这个语言中的句子。这种模式通常用于解析简单的语言或表达式。

以下是使用 PHP 编写的解释器模式示例代码:

php

<?php

// 抽象表达式
abstract class Expression {
    abstract public function interpret(Context $context);
}

// 终结符表达式
class TerminalExpression extends Expression {
    private $data;

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

    public function interpret(Context $context) {
        return $this->data;
    }
}

// 非终结符表达式
class NonTerminalExpression extends Expression {
    private $subExpressions = [];

    public function addExpression(Expression $expression) {
        $this->subExpressions[] = $expression;
    }

    public function interpret(Context $context) {
        $result = '';
        foreach ($this->subExpressions as $exp) {
            $result .= $exp->interpret($context);
        }
        return $result;
    }
}

// 上下文
class Context {
    // 上下文相关的数据
}

// 客户端代码
$terminal = new TerminalExpression('Hello, ');
$nonTerminal = new NonTerminalExpression();
$nonTerminal->addExpression($terminal);
$nonTerminal->addExpression(new TerminalExpression('World!'));

// 创建上下文
$context = new Context();

// 解释表达式
echo $nonTerminal->interpret($context); // 输出: Hello, World!

在这个示例中:

  • Expression 是一个抽象表达式类,定义了解释操作的接口 interpret。
  • TerminalExpression 是终结符表达式类,实现了 Expression 接口。终结符表达式是文法中的最小单位,通常对应于具体的值或操作。
  • NonTerminalExpression 是非终结符表达式类,也实现了 Expression 接口。非终结符可以包含其他终结符或非终结符表达式。
  • Context 是上下文类,包含解释过程中需要的任何全局或环境信息。
  • 客户端代码创建了终结符和非终结符表达式,并将终结符添加到非终结符中。然后创建一个上下文,并调用非终结符的 interpret 方法来解释整个表达式。

解释器模式的优点包括:

  • 易于扩展:可以轻松地添加新的行为或文法规则,而不需要修改现有的代码。
  • 分离文法和解释器:将文法的定义与解释器的实现分离,使得文法更容易修改和扩展。

解释器模式通常用于以下场景:

  • 需要解释一个简单的语言或表达式。
  • 需要在运行时从简单的语言或表达式中动态生成代码。
  • 需要将一个简单的语言或表达式作为配置或脚本使用。

请注意,解释器模式可能会导致难以维护的复杂系统,特别是当文法非常复杂时。因此,它更适用于简单的文法规则。

解释器模式常用于以下场景:

  1. 脚本语言解析:在需要实现简单脚本语言解析的场景,例如在游戏开发中解析游戏AI行为脚本。

  2. 配置文件解析:当应用程序需要解析配置文件,而这些配置文件具有某种特定格式或语言时。

  3. 领域特定语言(DSL):在需要定义和解析特定领域语言的场景,比如数据库查询语言、网络配置语言等。

  4. 正则表达式匹配:虽然通常使用正则表达式库来处理,但解释器模式可以用来构建复杂的正则表达式解析器。

  5. 语法分析:在编译器和解释器的实现中,用于语法分析阶段,将源代码转换为抽象语法树(AST)。

  6. 报表语言:在需要解析和执行报表查询语言的场景,例如财务或数据分析软件。

  7. 命令行界面(CLI):构建命令行工具时,用于解析和执行用户输入的命令。

  8. 状态机解析:用于解析和执行基于状态机的输入,例如某些协议的通信语言。

  9. 文本分析:在文本分析工具中,用于解析文本数据并提取特定格式的信息。

  10. 自定义规则引擎:在需要根据自定义规则集进行决策或操作的场景,例如安全策略评估。

解释器模式通过将语言或表达式的每个语法规则表示为一个类,使得扩展新规则变得容易。然而,这种模式可能会导致系统难以理解和维护,特别是当语法规则非常复杂或数量众多时。因此,它更适合用在语法规则相对简单和固定的场景中。

模板方法模式

(Template Method Pattern)是一种行为型设计模式,用于在方法中定义一个算法的骨架,将一些步骤的执行延迟到子类中。这种模式让子类在不改变算法结构的情况下,重新定义算法的某些特定步骤。

以下是使用 PHP 编写的模板方法模式示例代码:

php
<?php

// 抽象类,定义了模板方法
abstract class AbstractClass {
    // 模板方法,定义算法的骨架
    final public function templateMethod() {
        $this->baseOperation1();
        $this->baseOperation2();
        $this->concreteOperation();
        $this->baseOperation3();
    }

    // 基本操作1,由子类实现
    abstract protected function baseOperation1();

    // 基本操作2,由子类实现
    abstract protected function baseOperation2();

    // 钩子方法,可以在子类中重写
    protected function baseOperation3() {
        echo "AbstractClass baseOperation3\n";
    }

    // 具体操作,由子类实现
    abstract protected function concreteOperation();
}

// 具体类1
class ConcreteClass1 extends AbstractClass {
    protected function baseOperation1() {
        echo "ConcreteClass1 baseOperation1\n";
    }

    protected function baseOperation2() {
        echo "ConcreteClass1 baseOperation2\n";
    }

    protected function concreteOperation() {
        echo "ConcreteClass1 concreteOperation\n";
    }

    public function baseOperation3() {
        // 重写钩子方法
        echo "ConcreteClass1 baseOperation3\n";
    }
}

// 具体类2
class ConcreteClass2 extends AbstractClass {
    protected function baseOperation1() {
        echo "ConcreteClass2 baseOperation1\n";
    }

    protected function baseOperation2() {
        echo "ConcreteClass2 baseOperation2\n";
    }

    protected function concreteOperation() {
        echo "ConcreteClass2 concreteOperation\n";
    }
}

// 客户端代码
$concreteClass1 = new ConcreteClass1();
$concreteClass1->templateMethod();

$concreteClass2 = new ConcreteClass2();
$concreteClass2->templateMethod();

在这个示例中:

  • AbstractClass 是一个抽象类,定义了 templateMethod 模板方法,该方法按照固定顺序调用基本操作和具体操作。
  • baseOperation1、baseOperation2 和 concreteOperation 是抽象方法,必须在子类中实现。
  • baseOperation3 是一个钩子方法,提供了一个默认实现,但可以在子类中重写。
  • ConcreteClass1 和 ConcreteClass2 是具体类,继承自 AbstractClass 并实现了所有抽象方法。
  • 客户端代码创建了具体类的实例,并调用了 templateMethod 方法来执行算法。

模板方法模式的优点包括:

  • 封装不变部分:模板方法封装了算法的不变部分,而将可变部分留给子类实现。
  • 扩展性:子类可以扩展或修改算法的特定步骤,而不需要改变算法的结构。
  • 代码复用:减少代码重复,提高代码复用性。

模板方法模式通常用于以下场景:

  • 需要在多个类中共享相同的算法,但希望在某些步骤中允许不同行为。
  • 需要通过子类来扩展或修改算法的特定步骤,但不希望影响其他步骤。
  • 需要在保证算法结构不变的同时,提供灵活性和可扩展性。

PHP模板类代码示例 通过以上步骤,我们成功地创建了一个简单的PHP模板类,并使用它来渲染模板文件。当然,这只是一个简单的示例,实际应用中可能需要更复杂的模板类来满足不同的需求。总结起来,PHP模板类可以帮助我们更好地组织和管理模板文件,提高代码的可读性和可维护性。通过创建一个模板类,并使用它来渲染模板文件,我们可以将业务逻辑与界面展示分离,使代码更加清晰和易于开发。模板类可以帮助我们更好地组织和管理模板文件,提高代码的可读性和可维护性。首先,我们需要创建一个名为Template的PHP类,该类将包含模板相关的方法和属性。 阅读详情

相关推荐

MATLAB绘图中文乱码终极解决方案:从方框到清晰显示的全面指南

本文提供了MATLAB绘图中文乱码的全面解决方案。针对中文显示为方框的问题,从单次绘图的临时字体设置,到通过修改默认配置实现一劳永逸,再到系统级字体排查与Java环境配置,给出了详细的步骤指南。文章还涵盖了字体名称指定、图像导出防丢失以及跨平台协作等高级技巧,帮助用户彻底解决中文乱码困扰。

weixin_29093017的博客 613

编写PHP代码

php初级学习

Anpetixa的博客 3895

【训练】Qwen2.5VL 多机多卡 Grounding Box定位

之前的相关文章:【深度学习】LLaMA-Factory微调sft Qwen2-VL进行印章识别使用LLaMA-Factory微调sft Qwen2-VL-7B-Instruct构建最新的LLaMA-Factory镜像。

q742971636的博客 2583

php基础编程

PHP是什么?PHP能干什么?开发网站输出一个属于自己的第一个PHP程序标识 [告诉你]代码echo[指令] 输出。

L0g1c的博客 2434

上下文理解的AI增强方案:AI应用架构师的架构洞察

本文将从AI应用架构师的视角,深入探讨“上下文理解”的技术本质、核心挑战,以及一套可落地的上下文增强架构方案。我们会拆解上下文理解的底层需求,分析架构设计中的关键决策,并通过具体案例展示如何构建一个能“记住过去、理解现在、预测未来”的AI系统。三个维度:上下文的内容范围(短期/中期/长期)、数据类型(文本/结构化/多模态)、技术挑战(窗口限制/信息过载/跨会话一致性);三种架构模式:分层上下文存储(热/冷数据分离)、上下文路由(按需筛选)、动态压缩(适配模型窗口);四个关键组件。

欢迎来到我的优快云空间!这里聚焦AI大模型应用实战,分享前沿技术、实战案例与开发经验。 219

Unity必学:Protobuf-net预编译实战

本文深入解析Unity项目使用Protobuf-net Precompile的必要性。作为高效跨平台序列化方案,Protobuf-net解决了Unity工程在网络同步、存档系统中的性能瓶颈,特别是针对iOS等AOT平台的兼容问题。通过预编译模式,将运行时反射转为静态代码生成,显著提升移动端性能表现,支持协议平滑升级,已成为大厂项目的标配方案。文章从原理、实践到多平台适配,全面展示了这一"序列化发动机"如何支撑现代Unity项目的数据传输需求。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 495

简单的php编程代码大全

使用function关键字来定义一个新的函数。php深色版本2 return "你好," . $name . "!3 }

2401_86781857的博客 1440

OpenClaw 2026.3.13 踩坑实录:飞书HTTP协议降级Bug与多版本回归问题汇总

摘要:OpenClaw v2026.3.13存在多个严重回归问题,包括飞书API调用协议意外降级为HTTP导致连接失败(#46100)、本地Gateway诊断矛盾(#45504)及设备配对CLI命令失效等。该版本发布流程本身也存在异常,被迫以v2026.3.13-1标签重新发布。建议飞书用户回退至v2026.3.8稳定版,其他用户谨慎升级。本文详细记录了各Bug现象、影响范围及临时解决方案,并梳理了飞书通道的"多版本回归史",指出其根源在于架构变迁和测试覆盖不足。最后提供了包含配置备份、

Maynor的博客 869

23种设计模式PHP代码示例

23种设计模式PHP示例代码

小马过河R的博客 1127

[Dify实战] 品牌舆情速览:多渠道抓取、聚类情绪、生成日报-带绑定资源

摘要: 品牌舆情监测面临多渠道信息分散、手工处理效率低的痛点。Dify舆情速览助手通过自动化流程(数据抓取→情绪聚类→日报生成)帮助快速识别热点与风险。方案核心包括: 结构化处理:按情绪(正/中/负)聚类,分级标注风险事件; 日报输出:含热点摘要、趋势分析及处置建议(动作+团队+时间窗口); 质量控制:数据去噪、黑名单过滤,结合人工复核确保合规性。 落地需明确数据源分级(如权威媒体优先)、设置情绪阈值,并建立"发现-响应-复盘"闭环机制,提升舆情应对效率。 (字数:150)

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 297

YOLOv8改进,YOLOv8主干网络替换为ShuffleNetV2

ShuffleNet V2的设计原则:1.减少内存访问成本:通过优化数据传输路径,减少内存访问延迟,提高整体运算速度。2.考虑平台特性:针对不同硬件平台的特性进行优化设计,确保在目标平台上的高效运行。3.结构简洁高效:采用简洁而高效的模块设计,降低计算复杂度,同时保持或提升模型的预测准确性。下图,以四种不同计算复杂度水平下的准确性(在ImageNet验证集上的分类),速度和FLOPs的测量结果。(a, c) 为GPU结果,批量大小为8。(b, d) 为ARM结果,批量大小为1。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 1564

awesome-php设计模式库:23种设计模式PHP实现详解

想要快速掌握PHP设计模式?awesome-php设计模式库为你提供了完整的解决方案!🎯 这个精心策划的资源集合包含了23种经典设计模式的PHP实现,是每个PHP开发者必备的学习宝库。 ## 什么是设计模式? 设计模式是软件开发中经过验证的、可重用的解决方案,它们解决了在特定上下文中反复出现的问题。通过使用设计模式,你可以编写出更加**可维护、可扩展和可重用**的代码。 ## 设计模式分类

gitblog_00697的博客 515

YOLOv12改进前必看 - YAML模型配置文件详细解读(再也不用担心通道数不匹配) 附网络结构图

YOLOv12的模型配置文件在中,里面包含yolov12的以及的不同大小的模型,本文将详细介绍一下YOLOv12模型文件中各参数的含义。

Limiiiing的博客 3275

PHP 23种设计模式

学习PHP,对设计模式永远是逃不掉的:今天把php23种设计模式及其demo好好整理如下: 记录PHP关于23种设计模式的简单Demo。 Demo地址:https://segmentfault.com/a/1190000007797208 设计模式分为:创建型模式, 结构型模式,行为型模式等23种设计模式。 一、五种创建型模式如下: 工厂方法模式factory_metho

u012835679的专栏 2991

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

DesignPatternsPHP - PHP设计模式库

DesignPatternsPHP - PHP设计模式库 【免费下载链接】DesignPatternsPHP Sample code for several design patterns in PHP 8.x 项目地址: https://gitcode.com/...

gitblog_00019的博客 255

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

PHP 中最全的设计模式(23种)

PhpDesignPatterns 【PHP 中的设计模式】一、 Introduction【介绍】 设计模式:提供了一种广泛的可重用的方式来解决我们日常编程中常常遇见的问题。设计模式并不一定就是一个类库或者第三方框架,它们更多的表现为一种思想并且广泛地应用在系统中。它们也表现为一种模式或者模板,可以在多个不同的场景下用于解决问题。设计模式可以用于加速开发,并且将很多大的想法或者设计以一种简单地方

ITYangs的博客 7436

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

常用的设计模式和23种设计模式

一、策略模式 策略模式:对象的行为模式,用意是对一组算法的封装。动态的选择需要的算法并使用。 策略模式:程序中涉及决策控制的一种模式。策略模式功能非常强大,因为这个设计模式本身的核心思想就是面向对象编程的多形性思想。 策略模式的三个角色:1.抽象策略角色 2.具体策略角色 3.环境角色(对抽象策略角色的引用) 实现步骤: 1.定义抽象角色类(定义好各个实现的共同抽象方法) 2.定义具体策略类(具体实现父类的共同方法) 3.定义环境角色类(私有化申明抽象角色变量,重载构造方法,执行抽象方法) <?ph

zhang_pei12_pei的博客 261

PHP设计模式项目常见问题解决方案

PHP设计模式项目常见问题解决方案 一、项目基础介绍 本项目是一个开源的PHP设计模式实现库,包含了所有23个GoF(Gamma, Helm, Johnson, Vlissides)设计模式以及其他一些模式。该项目旨在提供一个简单的设计模式实现,帮助开发者理解设计模式的概念和用法。项目使用的主要编程语言是PHP。 二、新手常见问题及解决步骤 问题一:如何运行和测试代码? 问题描述:新手可能不清楚如...

gitblog_01111的博客 424

PHP常见的设计模式及其应用

本文主要讨论下Web开发中,准确而言,是PHP开发中的相关的设计模式及其应用。有经验的开发者肯定对于设计模式非常熟悉,但是本文主要是针对那些初级的开发者。首先我们要搞清楚到底什么是设计模式,设计模式并不是一种用来解释的模式,它们并不是像链表那样的常见的数据结构,也不是某种特殊的应用或者框架设计。事实上,设计模式的解释如下: descriptions of communicating ob

hevenue的专栏 486

PHP 实战之设计模式:PHP 中的设计模式

源文:https://segmentfault.com/a/1190000003817321本文主要讨论下Web开发中,准确而言,是PHP开发中的相关的设计模式及其应用。有经验的开发者肯定对于设计模式非常熟悉,但是本文主要是针对那 些初级的开发者。首先我们要搞清楚到底什么是设计模式,设计模式并不是一种用来解释的模式,它们并不是像链表那样的常见的数据结构,也不是某种特殊的应用 或者框架设计。事实上,设

简单-生活 484

PHP设计模式——简单工厂

声明:本系列博客参考资料《大话设计模式》,作者程杰。         前面两节内容介绍了什么是设计模式以及六大原则,相信看完前两节内容大家对设计模式已经有了初步的认识,接下来说一下设计模式的分类。         一般将面向对象设计模式分为三类:创建型、结构型、行为型三种。         创建型:创建对象时,不再由我们直接实例化对象;而是根据特定场景,由程序来确定创

姜海强 2937

DesignPatternsPHP:提升代码质量的23个核心设计模式全解析

DesignPatternsPHP是一个专注于PHP 8.x设计模式实现的开源项目,提供了23种经典设计模式的完整代码示例。本文将带你快速掌握这些模式的应用场景与实现方法,帮助你写出更优雅、可维护的PHP代码。 ## 为什么设计模式对PHP开发至关重要? 在现代PHP开发中,设计模式是解决常见架构问题的"最佳实践"。无论是构建大型企业应用还是开发轻量级API,合理运用设计模式都能带来三大核心价

gitblog_00869的博客 806

DesignPatternsPHP:面试必备的23种设计模式终极指南

DesignPatternsPHP是一个专注于PHP 8.x设计模式实现的开源项目,提供了23种经典设计模式的完整代码示例。无论是准备技术面试还是提升代码架构能力,这个项目都能帮助开发者系统掌握设计模式的核心思想与实战应用。通过学习这些经过验证的解决方案,你将能够编写出更优雅、可维护且灵活的PHP代码。 ## 设计模式的三大分类与应用场景 📚 设计模式主要分为创建型、结构型和行为型三大类别,

gitblog_00417的博客 950

第 13 章 Design pattern (设计模式)

常用设计模式包括 Singleton 单件模式 Abstract Factory 抽象工厂模式 Builder 生成器模式 Factory Method 工厂方法模式 Prototype 原型模式 Adapter 适配器模式 Bridge 桥接模式 Composite 组合模式 Decorator 装饰模式 Facade 外观模式 Flyweight 享...

weixin_34248258的博客 106
上一篇: Nginx统计PV、NV
下一篇: Laravel 框架开发 ERP 系统,技术选型和分析以及实施计划
WishYouAFortune
博客等级 码龄15年 1465粉丝 111原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值