设计模式(21)——策略 Strategy

24 篇文章 0 订阅
24 篇文章 3 订阅
目录:

设计模式学习笔记首页
设计模式(1)——抽象工厂 AbstractFactory
设计模式(2)——生成器 Builder
设计模式(3)——工厂方法 Factory Method
设计模式(4)——原型 Prototype
设计模式(5)——单例 Singleton
设计模式(6)——适配器 Adapter
设计模式(7)——桥接 Bridge
设计模式(8)——组合 Composite
设计模式(9)——装饰 Decorator
设计模式(10)——外观 Facade
设计模式(11)——享元 Flyweight
设计模式(12)——代理 Proxy
设计模式(13)——职责链 Chain Of Responsibility
设计模式(14)——命令 Command
设计模式(15)——解释器 Interpreter
设计模式(16)——迭代器 Iterator
设计模式(17)——中介者 Mediator
设计模式(18)——备忘录 Memento
设计模式(19)——观察者 Observer
设计模式(20)——状态 State
设计模式(21)——策略 Strategy
设计模式(22)——模板方法 Template Method
设计模式(23)——访问者 Visitor

二十一、Strategy(策略模式,别名 Policy 政策,对象行为型模式)

1. 意图:

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

2. 适用:

  1. 许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
  2. 需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时,可以使用策略模式。
  3. 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
  4. 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的 Strategy 类中以代替这些条件语句。

3. 类图:

image

4. 应用:

  系统使用不同的迭代器(正序迭代器,反序迭代器,中序迭代器)可以认为就是策略模式的一个实例。不同迭代器的使用接口和方式完全一样,当系统想要切换遍历容器的方式时,只要创建一个相应的迭代器,而使用迭代器的方式完全不用改变。

5. 中间层思考:

  策略模式抽象出了一个 Strategy 类作为中间层,系统不直接访问某一个具体的算法,而是通过访问 Strategy 抽象类业调用算法,这样可以动态地在运行时切换算法。

6. C++实现:

  1. 编写策略抽象基类 Strategy,含有一个纯虚函数提供算法实现的接口 virtual void AlgrithmInterface() = 0;,具体子类如 ConcreteStrategyAConcreteStrategyB 实现不同的算法行为。
  2. 编写环境类 Contexthas-a 组合一个 Strategy 对象 _stg,含有一个执行函数 DoAction(),函数体内调用 _stg 的算法接口 AlgrithmInterface()
Strategy.h
//Strategy.h
#pragma once

class Strategy {
public:
    Strategy();
    virtual ~Strategy();
    virtual void AlgrithmInterface() = 0;
protected:
private:
};

class ConcreteStrategyA : public Strategy {
public:
    ConcreteStrategyA();
    virtual ~ConcreteStrategyA();
    void AlgrithmInterface();
protected:
private:
};

class ConcreteStrategyB : public Strategy {
public:
    ConcreteStrategyB();
    virtual ~ConcreteStrategyB();
    void AlgrithmInterface();
protected:
private:
};
Strategy.cpp
//Strategy.cpp
#include "Strategy.h"
#include <iostream>
using namespace::std;

Strategy::Strategy() {}
Strategy::~Strategy() {
    cout << "~Strategy......" << endl;
}
void Strategy::AlgrithmInterface(){}

ConcreteStrategyA::ConcreteStrategyA() {}
ConcreteStrategyA::~ConcreteStrategyA(){
    cout << "~ConcreteStrategyA......" << endl;
}
void ConcreteStrategyA::AlgrithmInterface() {
    cout << "test ConcreteStrategyA......" << endl;
}

ConcreteStrategyB::ConcreteStrategyB() {}
ConcreteStrategyB::~ConcreteStrategyB() {
    cout << "~ConcreteStrategyB......" << endl;
}
void ConcreteStrategyB::AlgrithmInterface() {
    cout << "test ConcreteStrategyB......" << endl;
}
Context.h
//Context.h
#pragma once

class Strategy;

/*
    这个类是 Strategy 模式的关键,也是 Strategy 模式和 Template 模式的根本区别所在。
    Strategy 通过“组合”(委托)方式实现算法(实现)的异构,而 Template 模式则采取的是继承方式。
    这两个模式的区别也是继承和组合两种实现接口征用的方式的区别。
*/

class Context {
public:
    Context(Strategy* stg);
    ~Context();
    void DoAction();
protected:
private:
    Strategy* _stg;
};
Context.cpp
//Context.cpp

#include "Context.h"
#include "Strategy.h"

#include <iostream>
using namespace::std;

Context::Context(Strategy* stg) {
    _stg = stg;
}
Context::~Context() {
    if (!_stg)
        delete _stg;
}
void Context::DoAction() {
    _stg->AlgrithmInterface();
}
main.cpp
//main.cpp

#include "Context.h"
#include "Strategy.h"
#include <iostream>
using namespace::std;

int main(int argc, char* argv[]) {
    Strategy* stg = new ConcreteStrategyA();
    Context* con = new Context(stg);
    con->DoAction();
    if (NULL != con)
        delete con;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值