策略模式是一种行为模式,将算法封装在独立的类中,使客户端可以独立于算法进行变化。换言之,策略模式允许客户端在运行时选择使用哪种算法,而无需修改代码。

策略模式通常用于实现不同的行为,例如发送通知的方式。例如,您可以通过电子邮件、SMS 或 FCM 发送通知。策略模式允许您轻松地在这些不同的通知方法之间切换。

例子:

以下 PHP 代码示例演示了如何使用策略模式发送通知:

interface Sendable
{
    public function send(): void;
}

class Mail implements Sendable
{
    public function send(): void
    {
        echo "Notification send from: Mail \n";
    }
}

class FCM implements Sendable
{
    public function send(): void
    {
        echo "Notification send from: FCM \n";
    }
}

class SMS implements Sendable
{
    public function send(): void
    {
        echo "Notification send from: SMS \n";
    }
}

class Notification
{
    public Sendable $sendable;
    public function setSendable(Sendable $sendable): self
    {
        $this->sendable = $sendable;
        return $this;
    }
    public function notify()
    {
        return $this->sendable->send();
    }
}

class SendVerificationEmail extends Notification {}
class SendAnnouncementFCM extends Notification {}
class SendOtpSMS extends Notification {}

$email = new Mail();
(new SendVerificationEmail())->setSendable($email)->notify(); // 通知发送自: Mail

$fcm = new FCM();
(new SendAnnouncementFCM())->setSendable($fcm)->notify(); // 通知发送自: FCM 

$sms = new SMS();
(new SendOtpSMS())->setSendable($sms)->notify(); // 通知发送自:SMS 

在该示例中,我们定义了 Sendable 接口,该接口包含单个 send() 方法。该接口有三个具体实现:Mail、FCM 和 SMS。这些具体实现提供了发送通知的不同方式。

Notification类 是使用策略模式发送通知的客户端代码。该类具有一个名为 sendable 的属性,用于存储 Sendable 对象的引用。该类的 notify() 方法只是调用 sendable 对象的 send() 方法。

要发送通知,首先需要创建一个 Notification 对象,并向其传递接口的具体实现 Sendable。例如,要发送验证电子邮件,可以执行以下操作:

$email = new Mail();
(new SendVerificationEmail())->setSendable($email)->notify();

这样做将创建一个新的 SendVerificationEmail 对象,并将其 sendable 属性设置为 Mail 对象。然后,notify() 方法将调用 Mail 对象的 send() 方法,该方法将发送验证电子邮件。

// 通知发送自:Mail

使用策略模式的好处:

策略模式提供了许多好处,包括:

  • 灵活性:策略模式将算法封装在独立的类中,允许在运行时动态更改算法的使用。这对于支持多种算法或根据上下文更改算法的情况非常有用。
  • 可重用性:策略模式通过将算法封装成独立的类,实现了算法在不同上下文的复用。这有助于减少代码重复,提高代码的可维护性。
  • 可测试性:策略模式将算法封装在独立的类中,使得每个算法都可以单独进行测试。这有助于提高代码的可测试性,确保代码的正确性。

策略模式是一种强大的模式,可以用于实现同一行为的不同算法。它具有高度的灵活性、可重用性和可测试性,可以帮助您编写更优雅、更可靠的代码。