单例模式 (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 方法:返回容器中绑定的类标识。