第23章 行为型模式—策略模式

1. 状态模式(State Pattern)的定义

(1)定义:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。

  ①算法是同一接口的不同实现,地位是平等的,可以相互替换。

  ②引入上下文对象,可以实现让算法能独立使用它的客户。因为这个对象负责持有算法,但不负责决定具体选用哪个算法,把选择算法的功能交给了客户。

  ③当客户通知上下文对象执行功能的时候,上下文会转调具体的算法

(2)策略模式的结构和说明

  ①Strategy:策略接口,用来约束一系列具体的策略算法。Context使用这个接口来调用具体的策略实现定义的算法。

  ②ConcreteStrategy:具体的策略实现,也就是具体的算法实现。

  ③Context:上下文,负责和具体的策略类交互。通常会持有一个真正的策略实现,上下文还可以让具体的策略类来获取上下文的数据,甚至让具体的策略来回调上下文的方法。

【编程实验】报价管理

//行为型模式——策略模式
//场景:CRM系统报价策略
/*
1.对普通客户或者是新客户报全价
2.对老客户的价格,统一折扣5%
3.对大客户报的价格,统一折扣10%
*/

#include <iostream>
#include <string>

using namespace std;

//策略,定义计算报价算法的接口
class Strategy
{
public:
    //@param goodsPrice 商品销售原价
    //@return 计算出来的,应该给客户报的价格
    virtual double calcPrice(double goodsPrice) = 0;
};

//新客户或普通客户报价策略
class NormalCurstomerStrategy : public Strategy
{
public:
    double calcPrice(double goodsPrice)
    {
        cout << "对于新客户或者普通客户,没有打折." << endl;
        return goodsPrice;
    }
};

//老客户计算应报的价格
class OldCustomerStrategy : public Strategy
{
public:
    double calcPrice(double goodsPrice)
    {
        cout << "对于老客户,统一折扣5%" << endl;
        return goodsPrice*(1-0.05);
    }

};

//老客户计算应报的价格
class LargeCustomerStrategy : public Strategy
{
public:
    double calcPrice(double goodsPrice)
    {
        cout << "对于大客户,统一折扣10%" << endl;
        return goodsPrice*(1-0.1);
    }

};

//上下文实现
class Price
{
    Strategy* strategy;
public:
    Price(Strategy* strategy)
    {
        this->strategy = strategy;
    }

    //报价,计算对客户的报价(回调相应的打折策略)
    double quote(double goodsPrice)
    {
        return strategy->calcPrice(goodsPrice);
    }
};

int main()
{
    //1.选择并创建需要使用的策略对象
    Strategy* strategy = new LargeCustomerStrategy();
    //2.创建上下文
    Price ctx(strategy);

    //3.计算报价
    double price = ctx.quote(1000);

    cout << "向客户报价:"<< price << endl;

    return 0;
}
/*输出结果
对于大客户,统一折扣10%
向客户报价:900
*/

2. 思考策略模式

(1)策略模式的本质分离算法,选择实现

(2)策略模式的重心:不是如何实现算法,而是如何组织、调用这一系列的算法,从而让程序结构更加灵活,具有更好的维护性和扩展性。

(3)算法的平等性

  策略模式一个很大的特点就是各个策略算法的平等性。对于一系列具体的策略算法大家的地位是完全一样的,所以才能实现算法之间可以相互替换。可以这样描述策略算法:它是相同行为的不同实现。(如同样是打折这一行为,但商家可以在不同的时间,选择不同的打折策略)

4)谁来选择具体的策略算法

  ①一个地方是在客户端,当使用上下文的时候,由客户端选择具体的策略算法,然后把这个策略算法设置给上下文。

  ②还有一个地方是由上下文选择具体的策略算法。而状态模式可以由具体的状态实现去切换不同的状态。

(5)Strategy角色的实现方式:可以使用接口或抽象类,特别是当多个算法具有公共功能的时候,可以把Strategy实现成为抽象类。

(6)运行时策略的唯一性:运行期间,策略模式在每一个时刻只能使用一个具体的策略实现对象,虽然可以动态地在不同策略实现中切换,但是同时只能使用一个。

(7)Context和Strategy的关系

  ①在策略模式中,通常是上下文使用具体的策略实现对象。反过来,策略实现对象也可以从上下文获取所需要的数据。因此可以将上下文当作参数传递给策略实现对象。

  ②在这种情况下,上下文封装着具体策略对象进行算法运算所需要的数据,具体策略对象通过回调上下文的方法来获取这些数据。

3. 容错恢复机制

(1)在程序运行的时候,正常情况下应该按照某种方式来做,此时如果发生错误的话,系统并不会崩溃,而是有容忍出错的能力

(2)不但能容忍程序运行出现错误,还提供出现错误后的备用方案,也就是恢复机制来代替正常执行的功能,使程序继续向下运行。如日志记录,一般会记录在数据库里,但是当数据库暂时连不上时,可先记录在文本文件里,然后在合适的时候再转录到数据库中。

【编程实验】日志记录策略

4. 策略模式的优缺点

(1)优点

  ①定义一系列算法:策略模式的功能就是定义一系列的算法,实现让这些算法可以相互替换。所以会为这一系列算法定义公共的接口,以约束一系列算法要实现的功能。

  ②避免多重条件语句

  ③更好的扩展性:在策略模式中扩展新的策略实现非常容易,只要增加新的策略实现类,然后在使用策略的地方选择使用这个新的策略实现就可以了。

(2)缺点

  ①客户必须了解每种策略的不同。比如让客户端来选择具体使用哪一种策略,这就需要客户端了解所有的策略,还要了解各种策略的功能和不同,这样也暴露了策略的具体实现。

  ②增加了对象的数目。如果备选的策略很多的话,那么对象的数目就会很可观。

  ③只适合扁平的算法结构。策略模式的一系列算法地位是平等的,是可以相互替换的,事实上构成了一个扁平的算法结构,也就是在一个策略接口下,有多个平等的策略算法。而且运行的时刻只有一个算法被使用,这就限制了算法使用的层级,使用时不能嵌套使用。如折上折、折后返券等业务的实现,需要组合或嵌套使用多个算法的情况,可以考虑使用装饰模式或变形的责任链来实现。

5. 策略模式的应用场景

(1)GUI编程中的布局管理,资源访问策略等。

(2)出现多个if-else语句来选择行为的时候,可以考虑使用策略模式来代替这些条件语句。

(3)出现同一个算法,有很多不同的实现的情况下,可以使用策略模式来把这些“不同的实现”实现成一个算法的类层次。

6. 相关模式

(1)策略模式和状态模式

  ①状态模式是根据状态的变化来选择相应的行为。其处理的核心问题是状态迁移,因为当存在很多对象的状态下,各个状态之间的跳转和迁移过程是及其复杂的,涉及到多个角色的交互和跳转。在整个生命周期中存在一个状态的迁移曲线,这个迁移曲线对于客户是透明的。状态迁移是状态模式的核心内容;然而,在选择策略时,迁移与此毫无关系

  ②策略模式偏重于可替换的算法,以及这些算法在对应的Context中的正确调用。而状态模式偏重于各状态自身的逻辑运行,其功能类之间是不能相互替换的。如在策略模式中,可能根据不需情况对商品使用不同的打折策略,而状态模式中请假条的审批应先提交项目经理,再提交部门经理,而不能反过来,因固有的逻辑顺序,所以具有不可替换性

  ③状态模式在实现功能的同时,还会维护状态数据的变化及各个状态间的切换。一般在具体的状态实现里会改变Context中的当前状态并调用该状态下相应的方法。这是策略模式和状态模式的明显不同点!!

  ④策略模式允许一个客户选择或提供一种策略,而这种思想在状态模式中是不明显的策略模式行为对象的改变,一般都是外部造成的。而状态模式中对象行为的改变,则即可能是外部造成,也可能是行为对象自身造成的,但通常是自我控制状态的改变

  ⑤Strategy对象一般不会持有自己的数据(因为策略模式封装的只是算法!!),而状态对象则有可能持有自己的数据(stateless型或者state型)

(2)策略模式和模板方法模式

  ①模板方法重在封装算法骨架

  ②策略模式重在分离并封装算法实现

(3)策略模式和享元模式

  策略模式分离并封装出一系列的策略算法对象,这些对象的功能通常都比较单一,很多时候就是为了实现某个算法的功能而存在。因此,针对这一系列的、多个细粒度的对象,可以应用享元模式来节省资源。

时间: 2024-10-01 02:48:19

第23章 行为型模式—策略模式的相关文章

设计模式-行为型模式-策略模式

策略模式 在实际工作中我用到了策略模式,但为什么要有环境角色呢? 这里我贴上英文对含义的介绍, The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it. 然后看看这种设计模式的组成, 一般的,策略模式

行为型模型 策略模式

行为型模型 策略模式 Strategy:        策略(算法)抽象. ConcreteStrategy         各种策略(算法)的具体实现. Context         策略的外部封装类,或者说策略的容器类.根据不同策略执行不同的行为.策略由外部环境决定. 好处:         //算法的实现 和 客户端的使用 解耦合         //使得算法变化,不会影响客户端 适用于:         准备一组算法,并将每一个算法封装起来,使得它们可以互换. /** * 行为型模型

设计模式笔记:状态模式&amp;策略模式

这几天一直在忙期末考和实训,写笔记的时间也没有多少,不说废话了: 这文主要写两种模式:状态跟策略,主要是因为他们的类图一样,并且比较简单,写在同一篇文章里面容易甄别 状态模式:允许对象在内部状态改变时改变他的行为,对象看起来好像修改了他的类 先保留概念的意思,在平常的编程中,如果需要不同的状态,很一般的做法是在你要操作的类里面定义不同的常量代表不同的状态,然后if-else依据不同的状态有不同的实现: 1.你可以想象大量的if-else语句造成的低可读性和低效率 2.其次是你修改这个类的时候很麻

命令模式 &amp; 策略模式 &amp; 模板方法

一.策略模式 策略模式:封装易变化的算法,可互相替换. GoF<设计模式>中说道:定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换.该模式使得算法可独立于它们的客户变化. 比如:一个推送服务类,推送的方式,可以分为:QQ推送.邮箱推送.App推送.PC插件推送. 这里讲两个点: 1.推送方式可以互相替换: 2.这些推送方式只是单纯的属于推送服务这个类本身. 好好琢磨关键词:相互替换 二.命令模式 命令模式:解决“行为请求者”与“行为实现者”通常呈现一种“紧耦合”的问题. GoF&l

职责链模式+策略模式+反射+配置文件,完美实现下机操作(一)

纵观机房收费系统,逻辑最复杂的也就是下机操作了,这几天一直在考虑下机操作该如何进行. 流程分析: 判断卡号是否存在与是否上机 上机时间的处理 根据时间计算消费金额 更新余额,添加记录 关于逻辑的操作主要集中在两个计算上面时间和金额.首先说上机时间的处理问题,做之前我看了下第一版机房收费系统关于下机的操作: '计算消费时间 TxtTime.Text =DateDiff("n", Trim(TxtOntime.Text), Trim(Offtime)) TxtTime.Text = Txt

设计模式(行为型)之策略模式(Strategy Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 阅读前一篇<设计模式(行为型)之迭代器模式(Iterator Pattern)>http://blog.csdn.net/yanbober/article/details/45497881 概述 使用策略模式可以定义一些独立的类来封装不同的算法,每一个类封装一种具体的算法,在这里,每一个封

19 行为型模式-----策略模式

模式动机(Strategy Pattern):在完成一个任务时可能有多种方式,具体使用哪种方式最有效,需要视条件而定,不同条件下所选择的策略也有所不同,这就需要在一个环境中对当前的情况做出各种判断,在程序设计中表现为分支结构的实现,即在一个环境类中通过不同分支来决定使用哪种策略,这种将实现策略与当前环境都封装在一个类中的设计方法称为硬编码. 硬编码有如下缺点:其一,如果环境发生改变需要增加条件判断时,需要修改当前环境类以增加分支:其二,在实时性方面,也许客户不愿意支持它们不需要的分支算法,因为分

java设计模式--行为型模式--策略模式

策略模式: 1 策略模式 2 概述 3 定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化. 4 5 适用性 6 1.许多相关的类仅仅是行为有异.“策略”提供了一种用多个行为中的一个行为来配置一个类的方法. 7 8 2.需要使用一个算法的不同变体. 9 10 3.算法使用客户不应该知道的数据.可使用策略模式以避免暴露复杂的.与算法相关的数据结构. 11 12 4.一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现. 13

【23种设计模式】之策略模式——Strategy

Strategy--策略模式 程序员看问题需要有时间轴的概念,静态可能暴露不出问题,要动态的看. 看问题要加上时间轴. 一.定义 定义一系列算法,把它们一个个封装起来,并且使它们互相替换(变化),该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化) 二.假设场景 根据货币类型,计算税 1.传统思路 public class Strategy1 { ? /** * 根据货币类型,计算值 * 变化:当增加日元,泰铢等情况时,只能添加elseif的代码,违背了开闭原则 * @param