当前位置: 首页 > article >正文

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.kler.cn/a/487521.html

相关文章:

  • 大模型搜索引擎增强问答demo-纯python实现
  • 【C++/控制台】2048小游戏
  • 常见的开源网络操作系统
  • Linux 文件的特殊权限—ACL项目练习
  • 【设计模式-2】23 种设计模式的分类和功能
  • jenkins入门12-- 权限管理
  • 基于滑动窗口的限流方案
  • cv2.imwrite保存的图像是全黑的
  • React PureComponent使用场景
  • 基于SpringBoot的时间管理系统设计与实现
  • Spring Boot + MyBatis Plus 存储 JSON 或 List 列表全攻略
  • matlab离线安装硬件支持包
  • WPF连接USB相机,拍照,视频 示例
  • 《Spring Framework实战》4:Spring Framework 文档
  • Qt仿音乐播放器:媒体类
  • 降噪去噪学习流程和算法分类总结
  • 6 分布式限流框架
  • 蓝桥杯 第十五届 研究生组 B题 召唤数学精灵
  • C# 使用iText 编辑PDF
  • Golang学习笔记_23——error补充
  • AI绘画:Midjourney和stable diffusion到底有什么区别?
  • 基于单片机的空调温度测试测控系统设计
  • es 单个节点cpu过高
  • EasyExcel(二)导出Excel表自动换行和样式设置
  • 大数据高级ACP学习笔记(3)
  • 腾讯云AI代码助手编程挑战赛-武器大师