策略模式:设计模式中的一种

2023年 8月 28日 66.4k 0

策略模式:设计模式中的一种

到目前为止,我们已经介绍了本系列中的三种设计模式。我们定义了四类不同的设计模式。在本文中,我将解释策略设计模式,它属于行为设计模式。

你可能有一个问题:什么时候应该使用这种设计模式?我想说,当我们有多种方法(算法)来执行相同的操作,并且我们希望应用程序根据您拥有的参数选择特定的方法时。这种模式也称为策略模式。

本文的一个非常简单的示例是排序功能。例如,我们有多种对数组进行排序的算法,但是根据数组元素的数量,我们应该选择使用哪种算法来获得最佳性能。

此模式也称为策略模式。

问题

我将举一个集成了多个支付网关的电子商务网站的例子。尽管该网站有多个支付网关,但根据要求,它们不会全部显示在前端。相反,需要根据购物车金额即时选择适当的支付网关。

举个简单的例子,如果购物车价值低于 500 美元,则应使用 PayPal 标准处理付款,但如果金额为 500 美元或以上,则应使用存储的信用卡详细信息进行处理(假设详细信息已存储)。

如果没有实施正确的策略,我们的代码将如下所示:

首先,我们将提供通过 Paypal 支付和通过信用卡支付的主要类,这些类将在下面添加。

// Class to pay using Credit Card
class payByCC {

private $ccNum = '';
private $ccType = '';
private $cvvNum = '';
private $ccExpMonth = '';
private $ccExpYear = '';

public function pay($amount = 0) {
echo "Paying ". $amount. " using Credit Card";
}

}

// Class to pay using PayPal
class payByPayPal {

private $payPalEmail = '';

public function pay($amount = 0) {
echo "Paying ". $amount. " using PayPal";
}

}

// This code needs to be repeated every place where ever needed.
$amount = 5000;
if($amount >= 500) {
$pay = new payByCC();
$pay->pay($amount);
} else {
$pay = new payByPayPal();
$pay->pay($amount);
}

登录后复制

在这里,您可能会说我们需要放置条件语句才能使我们的代码正常工作。想象一下,当我们需要对该逻辑进行新的更改或者您发现该逻辑中的错误时,您需要进行多少更改。我们必须向所有使用该代码的地方添加补丁。

解决方案

我们将实现相同的要求,但使用策略模式,这使我们能够使我们的代码更加清晰、易于理解和可扩展。

界面

首先,我们将实现所有不同支付网关类将使用的接口。最终,这些是我们的策略。

interface payStrategy {
public function pay($amount);
}

class payByCC implements payStrategy {

private $ccNum = '';
private $ccType = '';
private $cvvNum = '';
private $ccExpMonth = '';
private $ccExpYear = '';

public function pay($amount = 0) {
echo "Paying ". $amount. " using Credit Card";
}

}

class payByPayPal implements payStrategy {

private $payPalEmail = '';

public function pay($amount = 0) {
echo "Paying ". $amount. " using PayPal";
}

}

登录后复制

接下来我们将创建我们的主类,它可以使用与我们迄今为止实施的策略不同的策略。

class shoppingCart {

public $amount = 0;

public function __construct($amount = 0) {
$this->amount = $amount;
}

public function getAmount() {
return $this->amount;
}

public function setAmount($amount = 0) {
$this->amount = $amount;
}

public function payAmount() {
if($this->amount >= 500) {
$payment = new payByCC();
} else {
$payment = new payByPayPal();
}

$payment->pay($this->amount);

}
}

登录后复制

在这里我们可以看到我们的付款方式的条件加载是在 payAmount 方法中完成的。让我们将所有内容包装在一起,看看如何进一步使用它。

interface payStrategy {
public function pay($amount);
}

class payByCC implements payStrategy {

private $ccNum = '';
private $ccType = '';
private $cvvNum = '';
private $ccExpMonth = '';
private $ccExpYear = '';

public function pay($amount = 0) {
echo "Paying ". $amount. " using Credit Card";
}

}

class payByPayPal implements payStrategy {

private $payPalEmail = '';

public function pay($amount = 0) {
echo "Paying ". $amount. " using PayPal";
}

}

class shoppingCart {

public $amount = 0;

public function __construct($amount = 0) {
$this->amount = $amount;
}

public function getAmount() {
return $this->amount;
}

public function setAmount($amount = 0) {
$this->amount = $amount;
}

public function payAmount() {
if($this->amount >= 500) {
$payment = new payByCC();
} else {
$payment = new payByPayPal();
}

$payment->pay($this->amount);
}
}

$cart = new shoppingCart(499);
$cart->payAmount();

// Output
Paying 499 using PayPal

$cart = new shoppingCart(501);
$cart->payAmount();

//Output
Paying 501 using Credit Card

登录后复制

我们可以看到支付网关的翻转对于应用程序来说并不透明。根据参数,它有适当的支付网关可用于处理交易。

添加新策略

如果在后期用户需要添加具有不同逻辑的新策略(此处为新支付网关),在这种情况下会非常简单。假设我们要添加一个新的支付网关 Moneybooker,并希望在购物车金额超过 500 美元但低于 1,000 美元时处理资金。

我们需要做的就是创建一个新的策略类来实现我们的接口,我们就可以开始了。

class payByMB implements payStrategy {

private $mbEmail = '';

public function pay($amount = 0) {
echo "Paying ". $amount. " using Money Booker";
}

}

登录后复制

我们现在已经准备好了新的策略类,我们需要更改的是主要的 payAmount 方法。需要修改如下:

public function payAmount() {

if($this->amount > 500 && $this->amount amount >= 500) {
$payment = new payByCC();
} else {
$payment = new payByPayPal();
}

$payment->pay($this->amount);
}

登录后复制

在这里您可以看到我们仅在 payAmount 方法中进行了更改,而不是在调用该方法的客户端代码中进行了更改。

结论

因此得出结论,当我们有多种方法来执行同一任务时(在软件语言中,当我们有多种算法来执行同一操作时),我们应该考虑实现策略模式。

通过使用这种模式,我们可以自由地添加/删除算法,因为这些算法的切换对于应用程序来说并不透明。

我已尽力提供一个基本但有用的示例来演示策略设计模式,但如果您有其他意见或问题,请随时将它们添加到下面的提要中。

以上就是策略模式:设计模式中的一种的详细内容,更多请关注每日运维网(www.mryunwei.com)其它相关文章!

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论