策略模式和工厂方法模式很类似(感觉策略模式是工厂方法模式的一部分)
策略模式就是将一系列的功能封装起来(用工厂方法模式封装),使之可以相互替换(C++多态调用),从而使功能更加独立,与客户程序的耦合性降低(工厂模式也是这样的)
举一个卖电脑的例子,比如有一家电脑店,平时卖华硕,惠普,过了一段时间,店主打算卖苹果电脑,就需要添加和苹果电脑相关的程序
代码
头文件
common.h
#ifndef COMMONHEAD
#define COMMONHEAD
#include <iostream>
#include <cassert>
using namespace std;
class saleprice
{
public:
saleprice(){cout<<__func__<<endl;}
virtual ~saleprice(){cout<<__func__<<endl;}
virtual void theprice()=0;
};
class computerfactory
{
public:
computerfactory(){cout<<__func__<<endl;}
virtual ~computerfactory(){cout<<__func__<<endl;}
virtual saleprice *producecomputer()=0;
};
#endif
huashuo.h
#ifndef HUASHUOHEAD
#define HUASHUOHEAD
#include "common.h"
class huashuoprice:public saleprice
{
public:
huashuoprice() {cout<<__func__<<endl;}
~huashuoprice() {cout<<__func__<<endl;}
virtual void theprice();
};
class huashuofactory:public computerfactory
{
public:
huashuofactory();
~huashuofactory();
virtual saleprice *producecomputer();
private:
saleprice *instance;
};
#endif
huipu.h
#ifndef HUIPUHEAD
#define HUIPUHEAD
#include "common.h"
class huipuprice:public saleprice
{
public:
huipuprice(){cout<<__func__<<endl;}
~huipuprice(){cout<<__func__<<endl;}
virtual void theprice();
};
class huipufactory:public computerfactory
{
public:
huipufactory();
~huipufactory();
virtual saleprice *producecomputer();
private:
saleprice *instance;
};
#endif
run.h
#ifndef RUNHEAD
#define RUNHEAD
#include "common.h"
#include "huashuo.h"
#include "huipu.h"
class run
{
public:
run(computerfactory *factory);
~run();
void startrun();
private:
computerfactory *m_factory;
};
#endif
源文件
huashuo.cpp
#include "huashuo.h"
void huashuoprice::theprice()
{
cout<<__func__<<endl;
}
huashuofactory::huashuofactory():
instance(nullptr)
{
cout<<__func__<<endl;
}
huashuofactory::~huashuofactory()
{
if (instance) {
delete instance;
instance=nullptr;
}
}
saleprice* huashuofactory::producecomputer()
{
cout<<__func__<<endl;
instance=new huashuoprice();
return instance;
}
huipu.cpp
#include "huipu.h"
void huipuprice::theprice()
{
cout<<__func__<<endl;
}
huipufactory::huipufactory():
instance(nullptr)
{
cout<<__func__<<endl;
}
huipufactory::~huipufactory()
{
cout<<__func__<<endl;
if (instance) {
delete instance;
instance=nullptr;
}
}
saleprice* huipufactory::producecomputer()
{
cout<<__func__<<endl;
instance=new huipuprice();
return instance;
}
run.cpp
#include "run.h"
run::run(computerfactory *factory):
m_factory(factory)
{
cout<<__func__<<endl;
}
run::~run()
{
cout<<__func__<<endl;
if(m_factory) {
delete m_factory;
m_factory=nullptr;
}
}
void run::startrun()
{
cout<<__func__<<endl;
saleprice *price=m_factory->producecomputer();
price->theprice();
}
main.cpp
#include "run.h"
int main(int argc, char const *argv[])
{
computerfactory *instance =new huipufactory();
run r(instance);
r.startrun();
return 0;
}
CMakeLists
cmake_minimum_required(VERSION 2.8)
project( strategy )
INCLUDE_DIRECTORIES(include)
AUX_SOURCE_DIRECTORY(src DIR_SRCS)
add_executable(strategy ./src/huashuo.cpp ./src/huipu.cpp ./src/run.cpp ./src/main.cpp)
这些代码实质和工厂方法模式的代码一模一样,运行结果如下
现在,添加苹果电脑的模拟程序
apple.h
#ifndef APPLEHEAD
#define APPLEHEAD
#include "common.h"
class appleprice:public saleprice
{
public:
appleprice() {cout<<__func__<<endl;}
~appleprice() {cout<<__func__<<endl;}
virtual void theprice();
};
class applefactory:public computerfactory
{
public:
applefactory();
~applefactory();
virtual saleprice *producecomputer();
private:
saleprice *instance;
};
#endif
apple.cpp
#include "apple.h"
void appleprice::theprice()
{
cout<<__func__<<endl;
}
applefactory::applefactory():
instance(nullptr)
{
cout<<__func__<<endl;
}
applefactory::~applefactory()
{
if (instance) {
delete instance;
instance=nullptr;
}
}
saleprice* applefactory::producecomputer()
{
cout<<__func__<<endl;
instance=new appleprice();
return instance;
}
CMakeLists
cmake_minimum_required(VERSION 2.8)
project( strategy )
INCLUDE_DIRECTORIES(include)
AUX_SOURCE_DIRECTORY(src DIR_SRCS)
add_executable(strategy ./src/apple.cpp ./src/huashuo.cpp ./src/huipu.cpp ./src/run.cpp ./src/main.cpp)
重新编译之后的结果
可见,当有新的需求需要添加时,可以直接在原有的基类上进行扩展,而不需要更改原有代码的逻辑,从而减少了编译时间,新的编译结果显示只是将新添加的功能重新编译。而且,新增功能(苹果电脑模拟程序)和原有功能彼此分离,彼此可以互相替换
策略模式一般包含在工厂方法模式中,用来封装不同的功能,使功能互相独立而彼此又可以相互替换
但是策略模式和工厂模式相对来说都有一个缺点,就是随着软件的扩大,类的个数不断增减,文件数量也不断增加
参考:
https://www.bilibili.com/video/BV1kW411P7KS?p=4
《设计模式,可复用面向对象软件的基础》
欢迎大家评论交流,作者水平有限,如有错误,欢迎指出