设计模式之策略模式

author author     2022-09-23     473

关键词:

策略模式属于对象行为型的设计模式

定义 :封装了一些列算法,它们之前可以相互替换,此模式使得算法的改变,不会影响到使用它们的客户端

 

技术分享

 

策略模式有以下3个角色组成

抽象策略类 : 所有策略类的父类,为所支持的策略算法声明了抽象方法

具体策略类 :实现抽象策略类的方法

Context环境类 : 维护一个对Strategy对象的引用

策略模式分离了算法的定义和使用,要做到这样客户端要依赖于策略接口,而不是具体的实现所有策略类对象可以互相替换,说明具有共同的特性->行为相同

以下是PHP对上述UML的实现

<?php
/*
 *抽象策略类 
 */
abstract class Stratrgy{
    abstract function AlgorithmInterface();
}

//具体实现类A
class ConcreateStratrgyA extends Stratrgy{
    public function AlgorithmInterface() {
        echo ‘算法A‘, PHP_EOL;
    }
}

//具体实现类B
class ConcreateStratrgyB extends Stratrgy{
    public function AlgorithmInterface() {
        echo ‘算法B‘, PHP_EOL;
    }
}

//具体实现类C
class ConcreateStratrgyC extends Stratrgy{
    public function AlgorithmInterface() {
        echo ‘算法C‘, PHP_EOL;
    }
}

//上下文环境类
class Context{
    private $_strategy;
    //通过构造方法注入策略对像
    public function __construct(Stratrgy $strategy) {
        $this->_strategy = $strategy;
    }
    public function ContextInterface(){
        $this->_strategy->AlgorithmInterface();
    }
}

//客户端类
class Client{
    public static function main(){
        $context = new Context(new ConcreateStratrgyA());
        $context->ContextInterface();
        
        $context = new Context(new ConcreateStratrgyB());
        $context->ContextInterface();
        
        $context = new Context(new ConcreateStratrgyC());
        $context->ContextInterface();
    }
}
Client::main();

 

在实际开发中,我们项目里很多地方都用到了策略模式,这里以支付回调为栗子介绍下策略模式在我们项目中的应用。

首先所有的支付回调都是由第三方发起,行为相同,最终都是给用户发送道具并通知第三方。整个流程可以抽象为3个步骤 :验证第三方参数 ->发送道具给用户 ->返回报文给第三方,因此我们的抽象策类里可以定义3个抽象方法,另外一些公共使用的方法都可以放到抽象

策略类里,具体策略类只需要继承就可以复用。策略环境类这里做了一些改动,加入了简单工厂模式生成具体的策略对象。每种支付的参数验证,发具体的道具数,以及报文响应都不相同,具体的支付类需要实现3个抽象方法。

由微信切换成支付宝,需要增加对应的支付宝类,然后回调的时候在工厂方法传入支付宝参数即可,这样微信,支支付宝...达到了相互替换的目的,而且具体的支付宝微信类改变不会影响到回调的入口。

抽简后的代码如下:

<?php
//抽象策略类
abstract class StrategyNotify{
   //参数检查
   abstract function checkParam();
   //发送道具
   abstract function sendProp();
   //输出报文
   abstract function outputMessage();
   //支付回调状态
   protected $_status = -1;
   //第三方参数
   protected $_params = array();

   protected $_errMsg = array(
       ‘-1‘=>‘系统错误‘,
       ‘-2‘=>‘参数验证错误‘,
       ‘-3‘=>‘发送道具失败‘,
   );
   //通知方法
   public final function notify(){
       if(!$this->checkParam()){
           $this->_status = -2;
       }else if(!$this->sendProp()){
           $this->_status = -3;
       }else{
           $this->_status = 1;
       }
       if($this->_status != 1){
           $this->log();
       }
       $this->outputMessage();
   }
   //写日志例子
   protected function log(){
       echo isset($this->_errMsg[$this->_status]) ? $this->_errMsg[$this->_status] : ‘‘;
       echo PHP_EOL;
   }
}

//微信支付
class Weixin extends StrategyNotify{
   public function checkParam() {
       return false;
   }

   public function outputMessage() {
       if($this->_status === 1){
           die(‘OK‘);
       }else{
           die(‘FAIL‘);
       }
   }

   public function sendProp() {
       return false;
   }
}

//支付环境类
class Pay{
    private static $_notify = null;
    //策略工厂
    public static function factory($notify){
        if(class_exists($notify) && self::$_notify == null){
            self::$_notify = new $notify();
        }
        return self::$_notify;
    }
}

Pay::factory(‘Weixin‘)->notify();

 

总结

优点:

1.当新增策略的时候,只需要增加具体的策略类,达到了开闭原则的目的

2.分离了算法的定义和使用,使得算法可以复用

缺点

1.每增加一个策略就需要增加一个策略类(目前我们的app接近200种支付,意味着有200个子类)

2.无法在客户端同时使用两种策略(我们的支付下单,需要从多种支付依照优先级一个个去下单,直到成功为止)

 

设计模式之策略模式

策略模式属于对象行为型的设计模式定义:封装了一些列算法,它们之前可以相互替换,此模式使得算法的改变,不会影响到使用它们的客户端  策略模式有以下3个角色组成抽象策略类:所有策略类的父类,为所支持的... 查看详情

《设计模式之禅》之策略模式

一、策略模式的定义策略模式是一种比较简单的模式,也叫做政策模式,其定义如下:定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。策略模式使用的是面向对象的继承和多态机制,我们看看策略模式的三个... 查看详情

设计模式之策略模式

1、定义  策略模式属于对象的行为模式。其用意是针对一组算法,将每一组算法封装到具有共同接口的独立子类中,从而可以使得他们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。2、策略模式... 查看详情

设计模式之策略模式

...,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的context对象。策略对象改变context对象的执行算法。介绍意图... 查看详情

015设计模式之策略模式

抽象策略角色:策略类,通常由一个接口或者抽象类实现。-具体策略角色:包装了相关的算法和行为。-环境角色:持有一个策略类的引用,最终给客户端调用。 #pragmaonce//策略接口(纯虚函数)classIStrategypublic: IStrategy() virtual~IStrate... 查看详情

大话设计模式之策略模式

策略模式  定义了一系列的算法,分别封装起来,让他们之间可以互相替换。此模式让算法的改变不会影响到使用算法的客户。  在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的context对... 查看详情

设计模式之策略模式

  软件工程师都会学习设计模式,设计模式可以说是前人智慧与经验的结晶,虽然不是哪里都用得到,但是在合适的地方使用合适的设计模式,能够带来巨大的收益。我通过学习《headfirst设计模式》,逐渐掌握这些设计方法,... 查看详情

java设计模式之策略模式

    策略模式属于对象的行为模式,策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换,策略模式让算法独立于使用它的客户而独立变化。策略模式使这些算法在客户端调用它们... 查看详情

java设计模式之策略模式

...此模式让算法的变化,不会影响到使用算法的客户(大话设计模式)。策略模式UML图      策略模式代码   古代的各种计谋都是一种策略,这次我们的例子就拿其中一种离间计来写的,理解起来非常容易,代码... 查看详情

设计模式之策略模式20170720

行为型设计模式之策略模式:一、含义策略模式是一种比较简单的模式,也叫做政策模式,其定义如下:定义一组算法(可抽象出接口),将每个算法都封装起来,并且使它们之间可以互换(定义一个类实现封装与算法切换) 二、... 查看详情

设计模式之-策略模式(strategypattern)(代码片段)

...,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的context对象。策略对象改变context对象的执行算法。 C++实... 查看详情

设计模式之策略模式(代码片段)

设计模式之策略模式  策略模式(StraregyPattern)是一种比较简单的模式,也叫政策模式(PolicyPattern),定义如下:Defineafamilyofalgorithms,encapsulateeachone,andmaketheminterchangeable.(定义一组算法,将每个算法都封装起来,并... 查看详情

设计模式之策略模式

目录 策略模式介绍鸭子事例简单的鸭子会飞的鸭子橡皮鸭登场噩梦开始策略模式鸭子策略模式介绍策略模式就是将功能定义为算法簇,分别封装起来,让他们之间可以替换,此模式可以让算法的变化独立于使用算法... 查看详情

设计模式之策略模式

设计模式之策略模式Jul23,2015策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户。正文在理解策略模式之前,我们先来一个例子,一般情况下,如果我们要做数... 查看详情

java设计模式之策略模式

1.策略模式的介绍  策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。简单的... 查看详情

设计模式:helloworld之策略模式

一.概述策略模式定义了算法族,分别封装起来,让他们可以互相替换,此模式让算法的变化独立于使用算法的客户。策略模式的三要素:抽象策略角色:策略类,通常由一个接口或者抽象类实现。具体策略角色:包装了相关的... 查看详情

《设计模式之禅》--策略扩展:策略枚举

接上篇《设计模式之禅》--代理扩展:动态代理需求:加减法计算publicenumCalculator{//加法运算ADD("+"){publicintexec(inta,intb){returna+b;}},//减法运算SUB("-"){publicintexec(inta,intb){returna-b;}};Stringvalue="";//定义成员值类型privateCalculator(S 查看详情

设计模式之桥梁模式和策略模式的差别

桥接(Bridge)模式是结构型模式的一种,而策略(strategy)模式则属于行为模式。下面是它们的UML结构图。桥梁模式:策略模式:在桥接模式中,Abstraction通过聚合的方式引用Implementor。举一个样例:策略模式:我要画圆。要实心圆,... 查看详情