thinkphp6.0常用设计模式实例

news2025/1/9 13:20:09

单例模式 (Singleton)

场景:确保一个类只有一个实例,并提供一个全局访问点。
实际业务:数据库连接、日志记录器、配置管理等。

ThinkPHP 6.0 实现:

namespace app\common;

class DatabaseConnection
{
    private static $instance = null;

    private function __construct() {}

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

    public function connect()
    {
        // 连接数据库
        return "Database connected!";
    }
}

// 使用
$db = DatabaseConnection::getInstance();
echo $db->connect();
namespace app\lib;

class Database
{
    private static $instance = null;

    private function __construct()
    {
        // 私有化构造函数,防止外部实例化
    }

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

    public function query($sql)
    {
        // 执行数据库查询
        return "Executing: $sql";
    }
}

// 使用
$db = Database::getInstance();
echo $db->query("SELECT * FROM users");

工厂模式 (Factory)

场景:根据不同的条件创建不同的对象。
实际业务:支付方式选择、日志记录器创建等。

namespace app\lib;

class PaymentFactory
{
    public static function create($type)
    {
        switch ($type) {
            case 'wechat':
                return new WechatPayment();
            case 'alipay':
                return new AlipayPayment();
            default:
                throw new \Exception("Unsupported payment type");
        }
    }
}

class WechatPayment
{
    public function pay()
    {
        return "Paying with WeChat";
    }
}

class AlipayPayment
{
    public function pay()
    {
        return "Paying with Alipay";
    }
}

// 使用
$payment = PaymentFactory::create('wechat');
echo $payment->pay();

观察者模式 (Observer)

场景:当一个对象的状态发生变化时,通知依赖它的所有对象。
实际业务:订单状态变更通知、用户注册后发送邮件等。

示例代码:

namespace app\lib;

class Order
{
    private $observers = [];

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

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

    public function complete()
    {
        echo "Order completed!\n";
        $this->notify();
    }
}

class EmailNotifier
{
    public function update($order)
    {
        echo "Sending email notification...\n";
    }
}

// 使用
$order = new Order();
$order->attach(new EmailNotifier());
$order->complete();

策略模式 (Strategy)

场景:定义一系列算法,使它们可以互相替换。
实际业务:支付方式选择、折扣计算等。

示例代码:

namespace app\lib;

interface DiscountStrategy
{
    public function calculate($price);
}

class NoDiscount implements DiscountStrategy
{
    public function calculate($price)
    {
        return $price;
    }
}

class HalfDiscount implements DiscountStrategy
{
    public function calculate($price)
    {
        return $price * 0.5;
    }
}

class Order
{
    private $discountStrategy;

    public function setDiscountStrategy(DiscountStrategy $strategy)
    {
        $this->discountStrategy = $strategy;
    }

    public function calculatePrice($price)
    {
        return $this->discountStrategy->calculate($price);
    }
}

// 使用
$order = new Order();
$order->setDiscountStrategy(new HalfDiscount());
echo $order->calculatePrice(100); // 输出: 50

命令模式 (Command)

场景:将请求封装为对象,使请求的发送者和接收者解耦。
实际业务:任务队列、撤销操作等。

示例代码:

namespace app\lib;

interface Command
{
    public function execute();
}

class LightOnCommand implements Command
{
    private $light;

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

    public function execute()
    {
        $this->light->on();
    }
}

class Light
{
    public function on()
    {
        echo "Light is on\n";
    }
}

// 使用
$light = new Light();
$command = new LightOnCommand($light);
$command->execute();

适配器模式 (Adapter)

场景:将一个类的接口转换成客户端期望的另一个接口。
实际业务:兼容不同第三方库、接口转换等。

示例代码:

namespace app\lib;

class OldLibrary
{
    public function specificRequest()
    {
        return "Old library response";
    }
}

interface NewLibraryInterface
{
    public function request();
}

class Adapter implements NewLibraryInterface
{
    private $oldLibrary;

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

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

// 使用
$oldLibrary = new OldLibrary();
$adapter = new Adapter($oldLibrary);
echo $adapter->request();

装饰者模式 (Decorator)

场景:动态地为对象添加功能。
实际业务:日志记录、权限校验等。

示例代码:

namespace app\lib;

interface Component
{
    public function operation();
}

class ConcreteComponent implements Component
{
    public function operation()
    {
        return "ConcreteComponent";
    }
}

class Decorator implements Component
{
    protected $component;

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

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

class LogDecorator extends Decorator
{
    public function operation()
    {
        echo "Logging before operation\n";
        $result = parent::operation();
        echo "Logging after operation\n";
        return $result;
    }
}

// 使用
$component = new ConcreteComponent();
$decorator = new LogDecorator($component);
echo $decorator->operation();

责任链模式 (Chain of Responsibility)

场景:将请求的发送者和接收者解耦,使多个对象都有机会处理请求。
实际业务:权限校验、日志记录等。

示例代码:

namespace app\lib;

abstract class Handler
{
    protected $nextHandler;

    public function setNext(Handler $handler)
    {
        $this->nextHandler = $handler;
    }

    public function handle($request)
    {
        if ($this->nextHandler !== null) {
            return $this->nextHandler->handle($request);
        }
        return null;
    }
}

class AuthHandler extends Handler
{
    public function handle($request)
    {
        if ($request === 'auth') {
            return "AuthHandler: Handling request\n";
        }
        return parent::handle($request);
    }
}

class LogHandler extends Handler
{
    public function handle($request)
    {
        if ($request === 'log') {
            return "LogHandler: Handling request\n";
        }
        return parent::handle($request);
    }
}

// 使用
$authHandler = new AuthHandler();
$logHandler = new LogHandler();
$authHandler->setNext($logHandler);

echo $authHandler->handle('log');

访问者模式 (Visitor)

场景:将算法与对象结构分离。
实际业务:报表生成、数据导出等。

示例代码:

namespace app\lib;

interface Visitor
{
    public function visitElementA(ElementA $element);
    public function visitElementB(ElementB $element);
}

class ConcreteVisitor implements Visitor
{
    public function visitElementA(ElementA $element)
    {
        echo "Visiting ElementA\n";
    }

    public function visitElementB(ElementB $element)
    {
        echo "Visiting ElementB\n";
    }
}

interface Element
{
    public function accept(Visitor $visitor);
}

class ElementA implements Element
{
    public function accept(Visitor $visitor)
    {
        $visitor->visitElementA($this);
    }
}

class ElementB implements Element
{
    public function accept(Visitor $visitor)
    {
        $visitor->visitElementB($this);
    }
}

// 使用
$visitor = new ConcreteVisitor();
$elementA = new ElementA();
$elementB = new ElementB();

$elementA->accept($visitor);
$elementB->accept($visitor);

中介者模式 (Mediator)

场景:减少对象之间的直接依赖,通过中介者进行通信。
实际业务:聊天室、事件调度等。

示例代码:

namespace app\lib;

class ChatRoom
{
    public static function showMessage($user, $message)
    {
        echo "[" . $user . "] : " . $message . "\n";
    }
}

class User
{
    private $name;

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

    public function sendMessage($message)
    {
        ChatRoom::showMessage($this->name, $message);
    }
}

// 使用
$john = new User("John");
$jane = new User("Jane");

$john->sendMessage("Hi Jane!");
$jane->sendMessage("Hello John!");

备忘录模式 (Memento)

场景:捕获并外部化对象的内部状态,以便以后可以恢复。
实际业务:撤销操作、游戏存档等。

示例代码:

namespace app\lib;

class Editor
{
    private $content;

    public function setContent($content)
    {
        $this->content = $content;
    }

    public function getContent()
    {
        return $this->content;
    }

    public function save()
    {
        return new EditorMemento($this->content);
    }

    public function restore(EditorMemento $memento)
    {
        $this->content = $memento->getContent();
    }
}

class EditorMemento
{
    private $content;

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

    public function getContent()
    {
        return $this->content;
    }
}

// 使用
$editor = new Editor();
$editor->setContent("First content");
$saved = $editor->save();

$editor->setContent("Second content");
echo $editor->getContent(); // 输出: Second content

$editor->restore($saved);
echo $editor->getContent(); // 输出: First content

迭代器模式 (Iterator)

场景:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。
实际业务:遍历集合、分页查询等。

示例代码:

namespace app\lib;

class Book
{
    private $title;

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

    public function getTitle()
    {
        return $this->title;
    }
}

class BookList implements \Iterator
{
    private $books = [];
    private $position = 0;

    public function addBook(Book $book)
    {
        $this->books[] = $book;
    }

    public function current()
    {
        return $this->books[$this->position];
    }

    public function next()
    {
        $this->position++;
    }

    public function key()
    {
        return $this->position;
    }

    public function valid()
    {
        return isset($this->books[$this->position]);
    }

    public function rewind()
    {
        $this->position = 0;
    }
}

// 使用
$bookList = new BookList();
$bookList->addBook(new Book("Design Patterns"));
$bookList->addBook(new Book("Clean Code"));

foreach ($bookList as $book) {
    echo $book->getTitle() . "\n";
}

门面模式

ThinkPHP 6.0 的门面模式依赖于容器(Container)和门面类(Facade)。门面类通过 __callStatic 方法将静态调用转发到容器中的实例。

示例代码:
以下是一个自定义门面类的实现:

namespace app\facade;

use think\Facade;

class MyService extends Facade
{
    protected static function getFacadeClass()
    {
        // 返回容器中绑定的类标识
        return 'my_service';
    }
}

绑定服务到容器:
在服务提供者中,将具体的实现类绑定到容器:

namespace app\provider;

use think\Service;

class MyServiceProvider extends Service
{
    public function register()
    {
        // 绑定服务到容器
        $this->app->bind('my_service', \app\service\MyService::class);
    }
}

具体实现类:

namespace app\service;

class MyService
{
    public function doSomething()
    {
        return "Doing something...";
    }
}

使用门面类:

use app\facade\MyService;

echo MyService::doSomething(); // 输出: Doing something...

ThinkPHP 6.0 内置门面类

ThinkPHP 6.0 提供了许多内置的门面类,例如:

Db:数据库操作

Cache:缓存操作

Log:日志记录

Request:请求对象

Config:配置管理

示例:使用内置门面类

use think\facade\Db;
use think\facade\Cache;
use think\facade\Log;

// 数据库查询
$users = Db::table('users')->select();

// 缓存操作
Cache::set('name', 'ThinkPHP');
echo Cache::get('name');

// 日志记录
Log::info('This is a log message.');

门面模式的优势

简化调用:通过静态方法调用,代码更加简洁。

解耦:调用者无需关心具体的实现类,降低了耦合度。

易于扩展:可以通过绑定不同的实现类来扩展功能。

统一接口:为复杂的子系统提供一个统一的接口。

门面模式的使用场景

数据库操作:通过 Db 门面类,统一调用数据库操作方法。

缓存操作:通过 Cache 门面类,统一调用缓存操作方法。

日志记录:通过 Log 门面类,统一调用日志记录方法。

配置管理:通过 Config 门面类,统一调用配置管理方法。

自定义服务:为自定义的服务提供统一的静态调用接口。

门面模式的实现原理

ThinkPHP 6.0 的门面模式依赖于容器和 Facade 基类。以下是其核心实现原理:

Facade 基类:

namespace think;

abstract class Facade
{
    protected static $app;

    public static function setFacadeApplication($app)
    {
        self::$app = $app;
    }

    public static function __callStatic($method, $params)
    {
        $instance = self::$app->make(static::getFacadeClass());

        return $instance->$method(...$params);
    }

    protected static function getFacadeClass()
    {
        throw new \RuntimeException('Facade does not implement getFacadeClass method.');
    }
}

关键点:
__callStatic 方法:将静态调用转发到容器中的实例。

getFacadeClass 方法:返回容器中绑定的类标识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2273804.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

道品科技智慧农业与云平台:未来农业的变革之路

随着全球人口的不断增长,农业面临着前所未有的挑战。如何在有限的土地和资源上提高农业生产效率,成为了各国政府和农业从业者亟待解决的问题。智慧农业的兴起,结合云平台的应用,为农业的可持续发展提供了新的解决方案。 ## 一、智…

【Linux基础指令】第一期

一、Linux的介绍 Linux是一个开源的操作系统,性能、稳定性、安全性方面上都是很优秀的,所以它一直是企业后端系统的首选。所以其图形化界面并不是Linux的必需品,所以我们避免不了要使用命令行的形式来使用Linux,也就离不开…

​​​​​​芯盾时代以数据为核心的车联网业务安全解决方案

芯盾时代车联网业务安全建设聚焦智能网联业务运行过程产生的多维度、多模态、多视角数据以及因业务需求产生的过程数据和业务衍生数据,以网络安全等级保护为基础,坚持网络安全管理体系和技术体系并重的原则,加强网络安全体系化、实战化、常态…

剖析 Claim-Check 模式:以小传大,赋能分布式系统与微服务

1. 前言 1.1 写作背景与目的 在当今分布式系统与微服务架构盛行的时代,服务间的消息传递与数据交换越来越频繁。传统的消息传输在面对海量数据时,往往会遇到以下痛点: 消息体过大:直接通过消息队列或服务间接口发送大体量数据&…

VS2022引入sqlite数据库交互

法一:用官网编译好的动态库(推荐) 下载所需文件 sqlite官网地址:https://www.sqlite.org/howtocompile.html 下载以下的2个压缩包 第一个压缩包 sqlite-amalgamation-xxxx.zip,xxxx是版本号,保持一致即可,这里面有sqite3.h 第…

计算机的错误计算(二百零五)

摘要 基于一位读者的问题,提出题目:能用数值计算证明 吗?请选用不同的点(即差别大的数)与不同的精度。实验表明,大模型理解了题意。但是,其推理能力值得商榷。 例1. 就摘要中问题&#xff0…

设计形成从业务特点到设计模式的关联

规范和指引在应用架构、数据架构等各架构方向上形成规范性约束指导。同一个决策要点、架构单元在统一的架构原则指导下,会因业务特点差异有不同的实现,经过总结形成了最佳实践。在开展新应用的设计时,根据决策要点以及相关的业务特点&#xf…

深度学习blog-深刻理解线性变换和矩阵

深度学习中避免不了矩阵运算,或者张量(其实是矩阵数组)运算。卷积是矩阵加、乘法,注意力也是一样。本质都一样,所谓注意力,卷积、滤波,是对不必了解数学的人说的,底层都是矩阵运算&a…

C/C++程序性能测试方法综述

摘要 性能测试是软件开发中不可或缺的一部分,特别是在对性能要求较高的C/C程序中。本文将详细介绍多种C/C程序性能测试方法,包括时间复杂度分析、事后统计方法、事前分析估算方法、使用性能测试工具(如Google Benchmark、gprof、Valgrind等&…

jmeter 中 BeanShell 预处理程序、JSR223后置处理程序使用示例

1. 各个组件如何新建的? 2. "http请求" 组件内容样例: "消息体数据" 源码: {"task_tag": "face_detect","image_type": "base64","extra_args": [{"model"…

电脑32位和64位之区别(Difference between 32-Bit and 64 Bit Computers)

电脑32位和64位之区别 很多小伙伴还不知道电脑32位和64位是什么意思,今天小编就来普及一下。 32位和64位是指电脑处理器(CPU)和操作系统的架构,决定了电脑如何处理数据、存储信息、运行程序等。 32位和64位是指电脑系统中每个处…

vue -关于浏览器localstorge数据定期清除的实现

1.实现背景 用户登录时的信息存在了localstorge中,但它会一直存在。一般来说,我们希望这个数据能够定期被清除掉,以下一个定时清除的实现。 2.实现原理 在用户登录时,将用户信息存入localstorge的同时,将当前时间作…

【JavaEE进阶】获取Cookie/Session

🍀Cookie简介 HTTP协议自身是属于 "⽆状态"协议. "⽆状态"的含义指的是: 默认情况下 HTTP 协议的客⼾端和服务器之间的这次通信,和下次通信之间没有直接的联系.但是实际开发中,我们很多时候是需要知道请求之间的关联关系的. 例如登陆⽹站成…

【工具变量】统计行业锦标赛激励数据集(2008-2023年)

一、数据简介 坚持创新驱动发展,要强化企业创新主体地位,发挥企业家在技术创新中的重要作用。作为企业组织内部最具有影响力的角色,高级管理人员拥有企业经营管理的自由裁量权,对企业战略决策及由此产生的经营绩效具有举足轻重的…

UVM: TLM机制

topic overview 不建议的方法:假如没有TLM TLM TLM 1.0 整个TLM机制下,底层逻辑离不开动作发起者和被动接受者这个底层的模型基础,但实际上,在验证环境中,任何一个组件,都有可能成为动作的发起者&#xff0…

Scratch023-(沙漠变绿洲)

提示: 知识回顾: 1、画笔的各个属性 2、“将笔的颜色设为”积木 3、“将笔的颜色增加”积木 文章目录 前言一、案例展示二、功能分析三、步骤拆解1.背景角色和画笔的初始化(1)初始化画笔2、一起绘制一个小雨滴3、绘制多个随机的小…

游戏语音趋势解析,社交互动有助于营造沉浸式体验

语音交互的新架构出现 2024 年标志着对话语音 AI 取得了突破,出现了结合 STT → LLM → TTS 模型来聆听、推理和回应对话的协同语音系统。 OpenAI 的 ChatGPT 语音模式将语音转语音技术变成了现实,引入了基于音频和文本信息进行端到端预训练的模型&…

详细全面讲解C++中重载、隐藏、覆盖的区别

文章目录 总结1、重载示例代码特点1. 模板函数和非模板函数重载2. 重载示例与调用规则示例代码调用规则解释3. 特殊情况与注意事项二义性问题 函数特化与重载的交互 2. 函数隐藏(Function Hiding)概念示例代码特点 3. 函数覆盖(重写&#xff…

计算机网络之---物理层设备

什么是物理层设备 物理层设备是指负责数据在物理媒介上传输的硬件设备,它们主要处理数据的转换、信号的传输与接收,而不涉及数据的内容或意义。常见的物理层设备包括网卡、集线器、光纤收发器、调制解调器等。 物理层设备有哪些 1、网卡(N…

js状态模式

允许一个对象在其内部状态改变时改变它的行为。 状态模式将对象的状态封装成独立的类,并使它们可以互相转换 // 定义状态接口class State {constructor() {if (this.constructor State) {throw new Error(不能实例化抽象类);}}// 定义状态方法handle(context) {th…