thinkphp6.0常用设计模式实例

单例模式 (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.rhkb.cn/news/503898.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【 算法设计与分析-回顾算法知识点】福建师范大学数学与计算机科学学院 2006 — 2007学年第二学期考试 A 卷

一.填空题(每空2分,共30分) 1.算法的时间复杂性指算法中 元运算 的执行次数。 2.在忽略常数因子的情况下,O、和三个符号中, O 提供了算法运行时间的一个上界。 3.设Dn…

嵌入式技术之Linux(Ubuntu) 一

一、Linux入门 1.硬件和操作系统以及用户的关系 一个传感器,获得数据后,需要向服务器发送数据。传感器传数据给上位机。 上位机需要一个程序来接收数据,那么这个上位机是什么机器? 我们的笔记本电脑就可以当成上位机。 两个手…

Flink系统知识讲解之:如何识别反压的源头

Flink系统知识之:如何识别反压的源头 什么是反压 Ufuk Celebi 在一篇古老但仍然准确的文章中对此做了很好的解释。如果您不熟悉这个概念,强烈推荐您阅读这篇文章。如果想更深入、更低层次地了解该主题以及 Flink 网络协议栈的工作原理,这里有…

浙江安吉成新的分布式光伏发电项目应用

摘 要:分布式光伏发电站是指将光伏发电组件安装在用户的建筑物屋顶、空地或其他适合的场地上,利用太阳能进行发电的一种可再生能源利用方式,与传统的大型集中式光伏电站相比,分布式光伏发电具有更灵活的布局、更低的建设成本和更高…

IDEA 字符串拼接符号“+”位于下一行的前面,而不是当前行的末尾

效果图 IDEA 默认效果是“历史效果”,经过修改后为“预期效果” 设置方式 在设置中找到Editor > Code Style > Java > Wrapping and Braces > Binary expressions > 勾选 Operation sign on next line 即可实现。具体设置如图。

基于phpstudy快速搭建本地php环境(Windows)

好好生活,别睡太晚,别爱太满,别想太多。 声明 仅作为个人学习使用,仅供参考 对于CTF-Web手而言,本地PHP环境必不可少,但对于新手来说从下载PHP安装包到配置PHP环境是个非常繁琐的事情,因此笔者…

后台管理系统引导功能的实现

引导是软件中经常见到的一个功能,无论是在后台项目还是前台或者是移动端项目中。 那么对于引导页而言,它是如何实现的呢?通常情况下引导页是通过 聚焦 的方式,高亮一块视图,然后通过文字解释的形式来告知用户该功能的作…

vscode通过ssh连接服务器实现免密登录

一、通过ssh连接服务器 1、打开vscode,进入拓展(CtrlShiftX),下载拓展Remote - SSH。 2、点击远程资源管理器选项卡,选择远程(隧道/SSH)类别。 3、点击SSH配置。 4、在中间上部分弹出的配置文件…

解决HBuilderX报错:未安装内置终端插件,是否下载?或使用外部命令行打开。

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 错误描述 在HBuilderX中执行npm run build总是提醒下载插件;图示如下: 但是,下载总是失败。运行项目时候依然弹出上述提醒。 解决方案 …

Wi-Fi Direct (P2P)原理及功能介绍

目录 Wi-Fi Direct (P2P)介绍Wi-Fi Direct P2P 概述P2P-GO(P2P Group Owner)工作流程 wifi-Direct使用windows11 wifi-directOpenwrtwifi的concurrent mode Linux环境下的配置工具必联wifi芯片P2P支持REF Wi-Fi Direct &#xff…

分享:osgb倾斜数据转cesium-3dtiles 小工具.

背景: 很多知识殊途同归,在三维软件这块,少不了要和各种各样的数据格式打交道.osgb,stl,obj,3dtiles,3ds等等..虽然里面本质核心基本都是几何数据拓扑数据材质纹理数据等等,但是由于其组织方式不同和特殊的应用场景,导致很多模型需要转来转去...相信很多人在这方面都或多或少吃…

spring boot 多数据源集成mysql、postgresql、phoenix、doris等

如何搭建多数据源项目只要以下简单几步; 一. 创建核心在config.datasource文件夹里 二. 引入相对应的jar包 三. 创建数据库连接配置 四. 写逻辑代码进行验证 1.DataSource package com.irootech.config.datasource;import java.lang.annotation.*;Target({ElementType.MET…

25年01月HarmonyOS应用基础认证最新题库

判断题 “一次开发,多端部署”指的是一个工程,一次开发上架,多端按需部署。为了实现这一目的,HarmonyOS提供了多端开发环境,多端开发能力以及多端分发机制。 答案:正确 《鸿蒙生态应用开发白皮书》全面阐释…

uniapp 导入uview-plus,使用组件出现,页面出现<up-parse>元素不存在,请检查你的代码

错误截图: 原因: 未按照官网方式进行配置,需要进行以下配置。具体详情 // pages.json {"easycom": {"autoscan": true,// 注意一定要放在custom里,否则无效,https://ask.dcloud.net.cn/question…

unity 播放 序列帧图片 动画

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、方法一:代码控制播放序列帧1、设置图片属性2、创建Image组件3、简单的代码控制4、挂载代码并赋值 二、方法二:直接使用1.Image上添加…

使用JMeter玩转tidb压测

作者: du拉松 原文来源: https://tidb.net/blog/3f1ada39 一、前言 tidb是mysql协议的,所以在使用过程中使用tidb的相关工具连接即可。因为jmeter是java开发的相关工具,直接使用mysql的jdbc驱动包即可。 二、linux下安装jmet…

CANN 学习——基于香橙派 KunpengPro(1)

异构计算架构CANN(Compute Architecture for Neural Networks)是昇腾针对AI场景推出的异构计算架构,向上支持多种AI框架,包括MindSpore、PyTorch、TensorFlow等,向下服务AI处理器与编程。 1CANN 总体架构 CANN 软件架…

计算机毕业设计Python中华古诗词知识图谱可视化 古诗词智能问答系统 古诗词数据分析 古诗词情感分析模型 自然语言处理NLP 机器学习 深度学习

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

海陵HLK-TX510人脸识别模块 stm32使用

一.主函数 #include "stm32f10x.h" // Device header #include "delay.h" #include "lcd.h" #include "dht11.h" #include "IOput.h" #include "usart.h" //#include "adc.h" …

apex安装

安装过程复杂曲折,网上说的很多办法,貌似成功了,实际还是没起作用。 先说成功过程,执行下面命令,安装成功(当然,前提是你要先配置好编译环境): (我的环境&a…