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.mzph.cn/bicheng/66467.shtml

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

相关文章

跨年烟花C++代码

嘿&#xff0c;朋友们&#xff01;今天来给大家讲讲一段挺有意思的C代码呀&#xff0c;这段代码主要是用来实现一个烟花效果展示的程序哦&#xff0c;下面咱们一点点来看哈。 效果 1. 开头包含的那些头文件 #include <graphics.h> #include <conio.h> #include &…

Element-plus表单总结

表单包含输入框&#xff0c;单选框&#xff0c;下拉选择&#xff0c;多选框等用户输入的组件。输入表单&#xff0c;您可以收集、验证和提交数据。 经典表单 最基础的表单包括各种输入表单项&#xff0c;比如input、select、radio、checkbox等。 在每一个form组件中&#xff0…

[Qt] 多元素控件 | 容器类控件 | 布局管理器layout

目录 一.多元素控件 1、List Widget 【使用 ListWidget】 2、Table Widget 【使用 QTableWidget】 3、Tree Widget 【使用 QTreeWidget】 二、容器类控件 1、Group Box 【给麦当劳案例加上分组框】 2、Tab Widget 【使用标签页管理多组控件】 三、布局管理器 1、…

【竞技宝】CS2:HLTV2024职业选手排名TOP8-broky

北京时间2025年1月7日,HLTV年度选手排名正在持续公布中,今日凌晨正式公布了今年的TOP8为FAZE战队的broky。 选手简介 broky是一位来自拉脱维亚的职业CS选手,现年23岁。2018年7月,broky获得了FPL资格,连续几季在榜上前5。他的首次赛场留名是跟随拉脱维亚本土战队Wolsung出征BES…

【Linux】记录一下考RHCE的学习过程(七)

年底了&#xff0c;公司接的北京地铁轨道交通的项目做不完了&#xff0c;一百多列地铁的设备都得调&#xff0c;派我出差了几周&#xff0c;这几天才回来&#xff0c;出差累死了实在是没办法更新。&#xff08;YOASOBI的二开票还没抢到ToT&#xff0c;哭死&#xff0c;看看回滚…

【简博士统计学习方法】第1章:3. 统计学习方法的三要素

3. 统计学习方法的三要素 3.1 监督学习的三要素 3.1.1 模型 假设空间&#xff08;Hypothesis Space&#xff09;&#xff1a;所有可能的条件概率分布或决策函数&#xff0c;用 F \mathcal{F} F表示。 若定义为决策函数的集合&#xff1a; F { f ∣ Y f ( X ) } \mathcal{F…

JavaEE初阶——计算机工作原理

一、什么是JavaEE JavaEE&#xff08;Java Platform&#xff0c;Enterprise Edition&#xff09;是sun公司&#xff08;2009年4月20日甲骨文将其收购&#xff09;推出的企业级应用程序版本。这个版本以前称为 J2EE。能够帮助我们开发和部署可移植、健壮、可伸缩且安全的服务器…

多目标优化算法——基于聚类的不规则Pareto前沿多目标优化自适应进化算法(CA-MOEA)

基于聚类的不规则Pareto前沿多目标优化自适应进化算法&#xff08;CA-MOEA&#xff09; 一、算法简介 简介&#xff1a; 现有的多目标进化算法&#xff08;moea&#xff09;在具有规则Pareto前沿且Pareto最优解在目标空间上连续分布的多目标优化问题&#xff08;MOPs&#xff…

短诗《腊八粥》

《腊八粥》现•佚名已买花生同煮粥&#xff0c;粥不似&#xff0c;少年稠也不复&#xff0c;少年仇亦不赴&#xff0c;少年愁终不负&#xff0c;少年筹 &#xff08;主编目前所有分类&#xff1a; 身&#xff0c;心&#xff0c;灵思 工作&#xff0c;生活 创作 剧 让世界更…

封装深拷贝方法

前言 在今年的四月份我写了一篇有关深拷贝的博客文章 我与深拷贝_radash 深拷贝-CSDN博客。在该文章中有一个令我感到遗憾的点就是我没有实现一个自己手写的深拷贝。如今我想弥补当初的遗憾&#xff0c;在这篇文章中详细的讲述一下如何手写一个深拷贝方法。 lodash中是如何实…

在不到 5 分钟的时间内将威胁情报 PDF 添加为 AI 助手的自定义知识

作者&#xff1a;来自 Elastic jamesspi 安全运营团队通常会维护威胁情报报告的存储库&#xff0c;这些报告包含由报告提供商生成的大量知识。然而&#xff0c;挑战在于&#xff0c;这些报告的内容通常以 PDF 格式存在&#xff0c;使得在处理安全事件或调查时难以检索和引用相关…

探索 Vue.js 的动态样式与交互:一个有趣的样式调整应用

修改日期备注2025.1.3初版 一、前言 今天和大家分享在 Vue.js 学习过程中开发的超酷的小应用。这个应用可以让我们通过一些简单的交互元素&#xff0c;如复选框、下拉菜单和输入框&#xff0c;来动态地改变页面上元素的样式哦 让我们一起深入了解一下这个项目的实现过程&…

css出现边框

前言 正常情况下&#xff0c;开启 contenteditable 属性后会出现 “黑色边框”。 如下图所示&#xff0c;很影响美观&#xff1a; 您可能想去掉它&#xff0c;就像下面这样&#xff1a; 解决方案 通过选择器&#xff0c;将 focus 聚焦时移除 outline 属性即可。 如下代码所示&a…

恋爱脑学编程之C++模板编程大冒险

一、模板编程初相识&#xff1a;开启泛型编程魔法之旅 嘿&#xff0c;小伙伴们&#xff01;今天咱们要一起探索C中超级厉害的模板编程。它就像是一把万能钥匙&#xff0c;可以打开各种类型数据的大门&#xff0c;让咱们写出超酷的与类型无关的代码&#xff0c;大大提高代码的复…

enzymejest TDD与BDD开发实战

一、前端自动化测试需要测什么 1. 函数的执行逻辑&#xff0c;对于给定的输入&#xff0c;输出是否符合预期。 2. 用户行为的响应逻辑。 - 对于单元测试而言&#xff0c;测试粒度较细&#xff0c;需要测试内部状态的变更与相应函数是否成功被调用。 - 对于集成测试而言&a…

继承(5)

大家好&#xff0c;今天我们继续来学习继承的相关知识&#xff0c;来看看子类构造方法&#xff08;也叫做构造器&#xff09;是如何做的。 1.6 子类构造方法 父子父子,先有父再有子,即:子类对象构选时,需要先调用基类构造方法,然后执行子类的构造方法 ★此时虽然执行了父类的…

VulnHub-Acid(1/100)

参考链接&#xff1a; ​​​​​​​【VulnHub】Acid靶场复盘-CSDN博客 靶场渗透&#xff08;二&#xff09;——Acid渗透_ambassador 靶场渗透-CSDN博客 网络安全从0到0.5之Acid靶机实战渗透测试 | CN-SEC 中文网 Vulnhub靶场渗透练习(四) Acid - 紅人 - 博客园 红日团队…

51c自动驾驶~合集45

我自己的原文哦~ https://blog.51cto.com/whaosoft/13020031 #运动控制和规划控制需要掌握的技术栈~ 各大垃圾家电造车厂又要开始了~~~​ 1、ROS的通信方式 李是Lyapunov的李&#xff1a;谈谈ROS的通信机制 话题通信和服务通信&#xff0c;其中话题通信是通过发布和订阅…

【Unity3D】AB包加密(AssetBundle加密)

加密前&#xff1a; 加密后&#xff0c;直接无法加载ab&#xff0c;所以无法正常看到ab内容。 using UnityEngine; using UnityEditor; using System.IO; public static class AssetBundleDemoTest {[MenuItem("Tools/打包!")]public static void Build(){//注意:St…

平面坐标转大地坐标(arcgisPro中进行)

1、将需要转换的红线导入arcgisPro中&#xff0c;如下&#xff1a; 2、在地图菜单栏中&#xff0c;选择坐标转换工具&#xff0c;如下&#xff1a; 3、打开坐标转换工具 4、开启捕捉 5、 设置大地坐标显示格式 6、如下&#xff1a; 7、显示如图&#xff1a; 8、再依次添加几个待…