PHP设计模式

1. 单例模式 (Singleton)

作用:确保一个类只有一个实例,并提供全局访问点。
使用场景:数据库连接、日志记录器、配置管理。
代码示例

class Database {
    private static $instance;

    private function __construct() {}  // 防止外部实例化
    private function __clone() {}      // 防止克隆

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

    public function query($sql) { /* ... */ }
}

// 使用
$db1 = Database::getInstance();
$db2 = Database::getInstance();
var_dump($db1 === $db2); // true

注意事项:单例模式可能增加耦合性,需谨慎使用。


2. 工厂模式 (Factory)

作用:封装对象的创建逻辑,客户端无需关心具体实现。
使用场景:支付方式、日志存储方式等需要动态创建对象的场景。
代码示例

interface Logger {
    public function log($message);
}

class FileLogger implements Logger {
    public function log($message) {
        file_put_contents('app.log', $message, FILE_APPEND);
    }
}

class DatabaseLogger implements Logger {
    public function log($message) { /* 记录到数据库 */ }
}

class LoggerFactory {
    public static function create($type) {
        return match ($type) {
            'file' => new FileLogger(),
            'database' => new DatabaseLogger(),
            default => throw new Exception("不支持的日志类型"),
        };
    }
}

// 使用
$logger = LoggerFactory::create('file');
$logger->log("Error occurred!");

3. 观察者模式 (Observer)

作用:定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会收到通知。
使用场景:事件处理系统、消息订阅、用户注册后发送邮件和短信。
代码示例

interface Subject {
    public function attach(Observer $observer);
    public function detach(Observer $observer);
    public function notify();
}

class UserRegistration implements Subject {
    private $observers = [];
    
    public function attach(Observer $observer) {
        $this->observers[] = $observer;
    }
    
    public function notify() {
        foreach ($this->observers as $observer) {
            $observer->handle();
        }
    }
    
    public function registerUser() {
        // 注册逻辑...
        $this->notify(); // 触发通知
    }
}

interface Observer {
    public function handle();
}

class EmailNotifier implements Observer {
    public function handle() { echo "发送欢迎邮件\n"; }
}

class SMSNotifier implements Observer {
    public function handle() { echo "发送短信通知\n"; }
}

// 使用
$registration = new UserRegistration();
$registration->attach(new EmailNotifier());
$registration->attach(new SMSNotifier());
$registration->registerUser();

4. 策略模式 (Strategy)

作用:定义一系列算法,使其可以相互替换,算法的变化独立于客户端。
使用场景:支付方式选择、排序算法切换、折扣计算。
代码示例

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

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

class BlackFridayDiscount implements DiscountStrategy {
    public function calculate($price): float { return $price * 0.7; }
}

class Checkout {
    private $discountStrategy;

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

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

// 使用
$checkout = new Checkout(new BlackFridayDiscount());
echo $checkout->finalizeOrder(100); // 输出 70

5. 装饰器模式 (Decorator)

作用:动态地为对象添加功能,避免继承导致的类爆炸。
使用场景:为对象动态添加日志、缓存、权限校验等功能。
代码示例

interface Notifier {
    public function send($message);
}

class EmailNotifier implements Notifier {
    public function send($message) { echo "发送邮件:$message\n"; }
}

abstract class NotifierDecorator implements Notifier {
    protected $notifier;

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

class SMSDecorator extends NotifierDecorator {
    public function send($message) {
        $this->notifier->send($message);
        echo "发送短信:$message\n";
    }
}

// 使用
$notifier = new EmailNotifier();
$notifier = new SMSDecorator($notifier);
$notifier->send("订单已发货");
// 输出:
// 发送邮件:订单已发货
// 发送短信:订单已发货

6. 适配器模式 (Adapter)

作用:将一个类的接口转换成客户端期望的另一个接口。
使用场景:兼容旧系统、集成第三方库。
代码示例

// 旧类(需要适配)
class LegacyWeatherService {
    public function getTemperatureF() { return 68; } // 返回华氏度
}

// 新接口(客户端期望的接口)
interface WeatherService {
    public function getTemperatureC(): float;
}

// 适配器类
class WeatherAdapter implements WeatherService {
    private $legacyService;

    public function __construct(LegacyWeatherService $service) {
        $this->legacyService = $service;
    }

    public function getTemperatureC(): float {
        $f = $this->legacyService->getTemperatureF();
        return ($f - 32) * 5 / 9; // 转换为摄氏度
    }
}

// 使用
$legacyService = new LegacyWeatherService();
$adapter = new WeatherAdapter($legacyService);
echo $adapter->getTemperatureC(); // 输出 20

7. 依赖注入 (Dependency Injection)

作用:将依赖对象的创建和绑定移到外部,降低耦合。
使用场景:需要松耦合的模块化架构。
代码示例

interface CacheDriver {
    public function get($key);
}

class RedisCache implements CacheDriver {
    public function get($key) { /* Redis 实现 */ }
}

class UserService {
    private $cache;

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

    public function getUser($id) {
        $user = $this->cache->get("user_$id");
        // 逻辑...
    }
}

// 使用(依赖由外部容器注入)
$cache = new RedisCache();
$userService = new UserService($cache);

8. 责任链模式 (Chain of Responsibility)

作用:将请求沿着处理链传递,直到有对象处理它。
使用场景:中间件、权限校验链、日志处理管道。
代码示例

abstract class Handler {
    private $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['is_authenticated']) {
            throw new Exception("未授权");
        }
        return parent::handle($request);
    }
}

class LoggingHandler extends Handler {
    public function handle($request) {
        echo "记录请求日志\n";
        return parent::handle($request);
    }
}

// 使用
$auth = new AuthHandler();
$logging = new LoggingHandler();
$auth->setNext($logging);

$auth->handle(['is_authenticated' => true]);

总结

模式核心思想典型场景
单例模式全局唯一实例数据库连接、配置管理
工厂模式封装对象创建动态创建不同子类对象
观察者模式一对多事件通知用户行为触发多系统响应
策略模式算法可替换支付方式、折扣策略
装饰器模式动态扩展功能添加日志、缓存等非核心功能
适配器模式接口兼容整合旧系统或第三方库
责任链模式链式处理请求中间件、权限校验链

设计原则:

一、单一职责原则 (Single Responsibility Principle, SRP)

定义‌:一个类应该仅有一个引起变化的原因。
应用场景‌:避免将多个功能耦合在同一个类中。
PHP示例‌:

// 违反SRP的类:同时处理用户数据和日志记录 
class User { 
    public function saveToDatabase() { /*...*/ } 
    public function logActivity() { /*...*/ } 
} 

// 改进后拆分职责 
class User { 
    public function saveToDatabase() { /*...*/ } 
} 
class Logger { 
    public function logActivity() { /*...*/ } 
}

二、开闭原则 (Open/Closed Principle, OCP)

定义‌:对扩展开放,对修改关闭。
应用场景‌:通过抽象和继承扩展功能,而非修改原有代码。
PHP示例‌:

// 抽象支付接口 
interface Payment { 
    public function pay(float $amount); 
} 

// 扩展新支付方式无需修改已有类 
class Alipay implements Payment { 
    public function pay(float $amount) { /*...*/ } 
} 
class WechatPay implements Payment {
    public function pay(float $amount) { /*...*/ } 
}

三、里氏替换原则 (Liskov Substitution Principle, LSP)

定义‌:子类必须能够完全替换父类且不破坏系统。
应用场景‌:继承关系中的方法重写需保持行为一致性。
PHP示例‌:

class Bird { 
    public function fly(): string { 
        return "Flying"; 
    } 
} 

// 错误示例:企鹅不会飞,违反LSP 
class Penguin extends Bird { 
    public function fly(): string { 
        throw new Exception("Cannot fly"); 
    } 
} 

// 正确做法:拆分接口(符合接口隔离原则) 
interface Flyable {
    public function fly(); 
} 
class Sparrow implements Flyable { /*...*/ } 
class Penguin { /*...*/ }

四、接口隔离原则 (Interface Segregation Principle, ISP)

定义‌:客户端不应依赖它不需要的接口。
应用场景‌:避免庞大臃肿的接口,按需拆分。
PHP示例‌:

// 违反ISP的接口 
interface Worker { 
    public function code(); 
    public function test(); 
} 

// 拆分后 
interface Developer { 
    public function code(); 
} 
interface Tester { 
    public function test(); 
}

五、依赖倒置原则 (Dependency Inversion Principle, DIP)

定义‌:高层模块不应依赖低层模块,二者都应依赖抽象。
应用场景‌:通过依赖注入降低耦合度。
PHP示例‌:

// 低层模块 
class MySQLConnection { 
    public function connect() { /*...*/ } 
} 

// 高层模块依赖抽象 
interface DBConnection { 
    public function connect(); 
} 
class UserService { 
    public function __construct(private DBConnection $db) {} 
} 

// 使用依赖注入 
$userService = new UserService(new MySQLConnection());

六、迪米特法则 (Law of Demeter, LoD)

定义‌:一个对象应对其他对象保持最少了解。
应用场景‌:减少类间直接依赖,通过中介通信。
PHP示例‌:

class Order { 
    private $customer; 

    // 违反LoD:直接访问Customer的地址 
    public function getCustomerAddress() { 
        return $this->customer->getAddress()->getFullAddress(); 
    } 

    // 改进后:委托给Customer处理 
    public function getCustomerAddress() {
        return $this->customer->getFullAddress(); 
    } 
}

原则综合应用建议

原则核心目标典型技术手段
单一职责原则功能解耦类拆分、职责分离
开闭原则扩展友好抽象类/接口、策略模式
里氏替换原则继承安全接口隔离、契约设计
接口隔离原则接口精简接口拆分、角色分离
依赖倒置原则降低耦合依赖注入、控制反转容器
迪米特法则减少依赖链门面模式、中介者模式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值