设计模式--策略模式

本文探讨了如何通过策略模式来避免复杂的if-else结构,遵循单一职责原则和开闭原则,提高代码的可扩展性和可维护性。示例展示了在PHP中实现策略模式,用于发送不同类型的的通知(如短信、邮件、微信)。总结了策略模式的三个关键点:定义多个类,使用工厂类实例化所有策略,并根据需要选择相应策略执行方法。
摘要由CSDN通过智能技术生成

策略模式(Strategy Pattern)定义了一组策略,分别在不同类中封装起来,每种策略都可以根据当前场景相互替换,从而使策略的变化可以独立于操作者。

大家都写过这样的代码

if (conditionA) {
    逻辑1
} else if (conditionB) {
    逻辑2
} else if (conditionC) {
    逻辑3
} else {
    逻辑4
}

这种代码虽然写起来简单,但是很明显违反了面向对象的 2 个基本原则:

单一职责原则(一个类应该只有一个发生变化的原因):因为之后修改任何一个逻辑,当前类都会被修改 (单一职责一个类做一件事,这个有时非常不友好,文件太多了

开闭原则(对扩展开放,对修改关闭):如果此时需要添加(删除)某个逻辑,那么不可避免的要修改原来的代码

因为违反了以上两个原则,尤其是当 if-else 块中的代码量比较大时,后续代码的扩展和维护就会逐渐变得非常困难且容易出错

if-else 不超过 2 层,块中代码 1~5 行,直接写到块中,否则封装为方法

if-else 超过 2 层,且块中代码超过 3 行,尽量使用策略模式

下面是PHP策略模式的demo,需求是当需要发送各种通知的时候 , 比如发送短信 ,发送邮件 , 发送微信通知 等等 ,可以拆分成一个个策略

<?php
//短信类
class Sms{
  public function send(){
    echo "send sms";
  }
}
//邮件类
class Email{
  public function send(){
    echo "send email";
  }
}
//微信类
class Weixin{
  public function send(){
    echo "send weixin";
  }
}
//存储上面策略的工厂
class Factory{
  public $products=array();
  public function get($type){
      return $this->products[$type];
  }
  public function register($type){
      $class=ucfirst($type);
      $this->products[$type]=new $class;
  }
}
//控制器代码
class Controller{
  public $types=array("sms","email","weixin"); //控制器一次性实例化多个策略对象
  public $factory=null;
  public function __construct(){
    //先生成出所有策略的对象
    $this->factory=new Factory();
    foreach($this->types as $t){
        $this->factory->register($t);
    }
  }

  public function doAction(){
   //根据传递的type参数 , 选择使用哪一个策略
    $type="sms";
    $notice=$this->factory->get($type);
    $notice->send();

    $type="email";
    $notice=$this->factory->get($type);
    $notice->send();
  }
}
$c=new Controller();
$c->doAction();

function numAdd($attr_id_list = [], $num = 0, $shop_id = 0, $goods_id = 0, $type = 0)
{
    switch ($type) {
        case 0:
            $model = "\app\models\Inventory";
            break;
        case 1:
            $model = "\app\models\MsInventory";
            break;
        case 2:
            $model = "\app\models\PtInventory";
            break;
        case 3:
            $model = "\app\models\YyInventory";
            break;
        case 4:
            $model = "\app\models\YsGoods";
            break;
        case 5:
            $model = "\app\models\IntegralInventory";
            break;
    }
    if($type == 4){
        $inventoryInfo = $model::findOne(['id' => $goods_id]);
        if(!$inventoryInfo) return false;
        $res = $inventoryInfo->updateCounters(['presale_num' => $num]);
        return $res ? true : false;
    }else{
        $inventoryInfo = $model::findOne([
            'goods_id' => $goods_id,
            'shop_id' => $shop_id,
            'attr_id' => (string)implode(",", $attr_id_list)
        ]);
    }
    if(!$inventoryInfo) return false;
    $res = $inventoryInfo->updateCounters(['stock' => $num]);
    return $res ? true : false;
}

总结:①策略模式其实就是定义多个类,每一个类中的方法名可以起一样。

           ②定义一个工厂类,可以一次性实例化所有类的实例。

            ③实例化工厂类,根据对应的 “实例名”去调用对应实例的对应的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值