【设计模式】策略模式

1. 什么是策略模式

  策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。UML结构图如下:

     

 

 

  Strategy:抽象策略类。用来定义所有支持算法的公共接口。

  ConcreteStrategy:具体策略类。继承自Strategy,封装了具体的算法或行为。   

  Context:上下文。持有一个Strategy的引用,最终给客户端调用。起的承上启下作用,屏蔽了用户模块对策略、算法的直接访问。

2. 策略模式的应用

  • 何时使用

  如果在一个系统里有许多类,它们之间的区别仅在于它们的行为;或一个系统需要动态的在几种算法中选择一种。

  • 使用方法

  将这些行为或算法封装成一个一个类,任意替换。

  • 优点

  1. 算法可以自由切换;
  2. 避免使用多重判断条件,方便维护;
  3. 增加一个策略只需要实现接口即可,方便扩展;
  4. 公共代码放到父类(抽象策略类)当中,避免代码重复;
  • 缺点

  1. 策略类数量增多,每个策略都是一个类,复用的可能性很小;(可以通过享元模式来克服)
  2. 所有策略类都需要对外暴露,客户端需要知道所有策略类,才能自行决定使用哪一个;
  • 注意

  如果一个系统的策略过多(四个以上),就需要考虑使用混合模式来解决策略类膨胀的问题。

3. 策略模式样例

  小王的爷爷老王刚开始使用电脑,看着电脑里的各种格式.txt、docx、jpg,瞬间眼花缭乱,身为c++程序员出身的小王,立马拍着胸脯说要给爷爷写个程序,通过程序去自动的打开各种格式文件:

#include <iostream>
#include <string>

enum class fileType
{
    Type_TXT,
    Type_DOCX,
    Type_PNG,
};

class fileManager
{
    public:
    void openTxt()
    {
        std::cout<<"txt is opened"<<std::endl;
    }

    void openDocx()
    {
        std::cout<<"word is opened"<<std::endl;
    }

    void openPng()
    {
        std::cout<<"jpg is opened"<<std::endl;
    }
};

int main()
{
   fileType type = fileType::Type_TXT;
   fileManager manager;
    switch(type)
    {
    case fileType::Type_TXT:
        file.opentxtfile();
        break;
    case fileType::Type_DOCX:
        file.opendocxfile();
        break;
     case fileType::Type_PNG:
        file.openpngfile();
        break;
    default:
        break;
    } 
}

  爷爷选择了一个txt文件,文件就打开了,爷爷笑靥如花,小王仰起了骄傲的头。

  过了两天,爷爷给小王打电话,说.avi的视频文件打不开。

  于是小王不得不修改了枚举类、Switch语句。

  随着种类越来越多,小王不得不买了本设计模式。改成策略模式:

  • 抽象策略类
class openInterface
{
public:
    virtual void open()=0;
    virtual ~openInterface(){}
};
  • 具体策略类
//txt file
class txtFile:public openInterface
{
 public:
    void open() override
    {
        std::cout<<"txt is opened"<<std::endl;
    }
};

//jpg file
class jgpFile:public openInterface
{
 public:
     void open() override
     {
         std::cout<<"jpg is opened"<<std::endl;
     }
};
  • 管理类
class openFileManager
{
 public:
    openFileManager(openInterface* pOpen)
    {
        _pOpen = pOpen;
    }
    void openFile()
    {
        _pOpen->open();
    }
    ~openFileManager()
    {
        if(_pOpen)
            delete _pOpen;
    }
 private:
    openInterface* _pOpen;
};            
  • 客户端
int main()
{

    openFileManager* txtManager = new openFileManager(new txtFile);
    txtManager->openfile();

    openFileManager* pngManager = new openFileManager(new pngFile);
    pngManager->openfile();

    return 0;
}

 

 

策略模式Strategy(c++学习笔记) - 知乎 (zhihu.com)

简说设计模式——策略模式 - JAdam - 博客园 (cnblogs.com)

posted @ 2022-03-14 18:44  hik_wxy  阅读(76)  评论(0)    收藏  举报