PHP中常用的三种设计模式详解【单例模式、工厂模式、观察者模式】

yizhihongxing

PHP中常用的三种设计模式详解【单例模式、工厂模式、观察者模式】

在PHP开发中,设计模式是一种很常见的编程思想。设计模式是对软件开发中经常出现的问题得出的通用解决方案。下面我将详细讲解PHP中三种常用的设计模式:单例模式、工厂模式、观察者模式。

单例模式

单例模式是一种创建型模式,它的目的是保证一个类只有一个实例,而且提供了一个全局访问该实例的方法。
下面是PHP单例模式的代码示例:

class Singleton
{
    private static $instance;

    private function __construct()
    {
        //构造函数私有化,避免外部创建实例
    }

    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __clone()
    {
        //禁止克隆
    }

    private function __wakeup()
    {
        //禁止反序列化
    }
}

$singleton1 = Singleton::getInstance();
$singleton2 = Singleton::getInstance();
var_dump($singleton1 === $singleton2); // true

在上面的示例代码中,使用了一个私有静态变量保存了该类的实例,然后提供了一个静态方法 getInstance() 来获取该实例。在 getInstance() 方法中先判断实例是否存在,如果不存在就创建该实例。同时将构造函数声明为私有,禁止外部创建这个类的实例,避免创建多个实例。

工厂模式

工厂模式是一种创建型模式,它提供了一种创建对象的最佳方式。工厂模式使用工厂方法来解决生成对象的问题,它通过工厂类来创建对象,而不需要直接调用类的构造函数。
下面是PHP工厂模式的代码示例:

interface Product
{
    public function getName();
}

class ProductA implements Product
{
    public function getName()
    {
        return "ProductA";
    }
}

class ProductB implements Product
{
    public function getName()
    {
        return "ProductB";
    }
}

class ProductFactory
{
    public function createProduct($type)
    {
        switch ($type) {
            case 'A':
                return new ProductA();
            case 'B':
                return new ProductB();
            default:
                throw new Exception("Invalid product type.");
        }
    }
}

$productFactory = new ProductFactory();
$productA = $productFactory->createProduct('A');
$productB = $productFactory->createProduct('B');

echo $productA->getName() . PHP_EOL; // ProductA
echo $productB->getName() . PHP_EOL; // ProductB

在上面的示例代码中,我们创建了一个 Product 接口,其中声明了 getName() 方法,然后分别创建了两个 Product 的实现类,ProductAProductB 实现了 Product 接口,并分别实现了 getName() 方法。最后创建了一个 ProductFactory 工厂类,它具有 createProduct() 方法,这个方法通过传递参数来创建不同类型的产品。如果传递的参数不在工厂类支持的产品类型中,则抛出一个异常。

观察者模式

观察者模式是一种行为型模式,当对象状态发生改变时,所有依赖于它的对象都会收到通知并自动更新。
下面是PHP观察者模式的代码示例:

interface Observer
{
    public function update($data);
}

class ConcreteObserver1 implements Observer
{
    public function update($data)
    {
        echo "ConcreteObserver1 has received data: " . $data . PHP_EOL;
    }
}

class ConcreteObserver2 implements Observer
{
    public function update($data)
    {
        echo "ConcreteObserver2 has received data: " . $data . PHP_EOL;
    }
}

interface Subject
{
    public function addObserver(Observer $observer);

    public function removeObserver(Observer $observer);

    public function notifyObservers($data);
}

class ConcreteSubject implements Subject
{
    private $observers = array();

    public function addObserver(Observer $observer)
    {
        $this->observers[] = $observer;
    }

    public function removeObserver(Observer $observer)
    {
        foreach ($this->observers as $key => $val) {
            if ($val === $observer) {
                unset($this->observers[$key]);
            }
        }
    }

    public function notifyObservers($data)
    {
        foreach ($this->observers as $observer) {
            $observer->update($data);
        }
    }
}

$subject = new ConcreteSubject();
$observer1 = new ConcreteObserver1();
$observer2 = new ConcreteObserver2();
$subject->addObserver($observer1);
$subject->addObserver($observer2);

$subject->notifyObservers('Hello world!');

$subject->removeObserver($observer1);

$subject->notifyObservers('Hello world again!');

在上面的示例代码中,我们创建了一个 Observer 接口,其中定义了 update() 方法,然后创建了两个具体的观察者 ConcreteObserver1ConcreteObserver2,它们实现了 Observer 接口,并分别实现了 update() 方法。接下来创建了一个 Subject 接口,定义了 addObserver()removeObserver()notifyObservers() 方法。然后创建了一个具体的主题 ConcreteSubject,实现了 Subject 接口,并实现了其中的方法。最后创建了一个观察者案例,先将两个观察者添加到主题中,然后调用 notifyObservers() 方法通知所有观察者,当主题状态改变时,观察者可以收到通知。最后再移除一个观察者并再次调用 notifyObservers() 方法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:PHP中常用的三种设计模式详解【单例模式、工厂模式、观察者模式】 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • php实现遍历文件夹的方法汇总

    为了实现遍历文件夹的功能,可以使用PHP提供的目录迭代器(DirectoryIterator)、文件迭代器(FilesystemIterator)和递归函数等方式。 目录迭代器(DirectoryIterator) DirectoryIterator 的基本使用 DirectoryIterator 可以基于指定的目录路径或文件夹资源句柄来创建,然后通过对其进…

    PHP 2023年5月26日
    00
  • 解决PHP超大文件下载,断点续传下载的方法详解

    解决PHP超大文件下载,断点续传下载的方法详解 问题 在网站开发中,经常需要下载一些较大的文件,比如视频、音频、PDF等。但这些文件往往都很大,如果采用普通的下载方式,可能会因为网络不稳定或者其他原因导致下载失败。为了解决这个问题,我们需要实现断点续传下载,以确保下载成功率。 方法 为了实现断点续传下载,我们需要在服务器端和客户端都进行相应的处理。 服务器端…

    PHP 2023年5月26日
    00
  • PHP无限分类代码,支持数组格式化、直接输出菜单两种方式

    PHP无限分类可以通过递归的方式,处理多层级分类数据,实现扁平化的存储和展示。本文将介绍两种方式:支持数组格式化和直接输出菜单,详细解释其使用方法和示例应用。 支持数组格式化的PHP无限分类代码 实现思路 通过递归方法,处理多层级数组中每个元素的子元素,最终返回格式化后的结果数组。 递归方法会输入两个参数:原始数组和当前分类ID(默认为0,表示根分类)。 对…

    PHP 2023年5月26日
    00
  • php 模拟POST|GET操作实现代码

    下面我会详细讲解使用 PHP 模拟 POST/GET 操作实现代码的步骤: 准备工作 在开始之前,需要准备以下内容: 一个目标网站的 URL 需要提交的 POST 或 GET 参数 如果要使用模拟登录,则需要知道需要提交用户名和密码的字段名 模拟 GET 请求 使用 PHP 模拟 GET 请求需要使用 cURL 库,cURL 是一个广泛被使用的向 URL 传…

    PHP 2023年5月27日
    00
  • php 从一个数组中随机的取出若干个不同的数实例

    要从一个数组中随机取出若干个不同的数有很多种方法,这里共享两种常用的实现方式,供大家参考。 方法一:使用 array_rand 函数 array_rand 是 PHP 中的一个内置函数,旨在从数组中随机选取一个或多个键名,返回键名或键名列表: mixed array_rand ( array $array [, int $num = 1 ] ) 其中参数1 …

    PHP 2023年5月26日
    00
  • 浅析php-fpm静态和动态执行方式的比较

    浅析php-fpm静态和动态执行方式的比较 前言 php-fpm 是 PHP 官方针对处理高并发等情况下的替代 FCGI 环境的进程管理器,相较于传统的 php-cgi 方式,php-fpm 众多的优异表现,比如在性能、应对并发、改善 PHP 进程管理等方面。 php-fpm 提供了两种执行方式:静态执行和动态执行。静态方式在 PHP-FPM 启动时,根据 …

    PHP 2023年5月26日
    00
  • 时间戳与时间相互转换(php .net精确到毫秒)

    要将时间戳转换为具体的日期和时间格式,可以使用PHP的date()函数,具体方法如下: <?php // 设定时间戳 $timestamp = 1625575859000; // 将时间戳转换为具体的日期和时间格式 $datetime = date("Y-m-d H:i:s", $timestamp/1000); // 输出转换后的…

    PHP 2023年5月27日
    00
  • 在PHP中操作文件的扩展属性

    操作文件的扩展属性是指除了文件名、大小、创建时间等基本属性之外,还可以附加其他自定义属性,以实现更丰富的操作。在PHP中,我们可以使用 stream_set_meta_data() 和 stream_get_meta_data() 函数来实现对扩展属性的操作。 设置扩展属性 我们可以使用 stream_set_meta_data() 函数来设置文件的扩展属性…

    PHP 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部