定义:
定义一组算法,将每个算法都封装起来,并且使他们之间可以互换
策略模式使用的就是面向对象的继承和多态机制
//////////////////////// ********** 1. 策略模式(通用版),代码清单18-3:***************//
//抽象的策略角色
class Strategy
{
public:
virtual void operate() = 0;
};
//具体策略角色
class ConcreteStrategy1: public Strategy
{
public:
virtual void operate(){qDebug() << "ConcreteStrategy1";}
};
//吴国太开绿灯
class ConcreteStrategy2: public Strategy
{
public:
virtual void operate(){qDebug() << "ConcreteStrategy2";}
};
//封装角色
class Context
{
public:
Context(Strategy* strategy)
{
this->m_strategy = strategy;
}
void operate()
{
this->m_strategy->operate();
}
private:
Strategy *m_strategy;
};
//使用计谋
int main()
{
Strategy *gy1 = new ConcreteStrategy1();
Strategy *gy2 = new ConcreteStrategy2();
Context *context = new Context(gy1);
context->operate();
context = new Context(gy2);
context->operate();
return 0;
}
策略模式就是采用了面向对象的继承和多态机制。在真实的业务环境中,需要看清楚哪个接口是抽象策略接口,哪些是和策略模式没有任何关系的。
////////////////////// ********** 2. 三国策略,代码清单18-2:***************//
//妙计接口
class IStrategy
{
public:
virtual void operate() = 0;
};
//乔国老开后门
class BackDoor: public IStrategy
{
public:
virtual void operate(){qDebug() << "BackDoor";}
};
//吴国太开绿灯
class GivenGreenLight: public IStrategy
{
public:
virtual void operate(){qDebug() << "GivenGreenLight";}
};
//孙夫人断后
class BlockEnemy: public IStrategy
{
public:
virtual void operate(){qDebug() << "BlockEnemy";}
};
//锦囊
class Context
{
public:
Context(IStrategy* strategy)
{
this->m_strategy = strategy;
}
void operate()
{
this->m_strategy->operate();
}
private:
IStrategy *m_strategy;
};
//使用计谋
int main()
{
IStrategy *backDoor = new BackDoor();
IStrategy *greenLight = new GivenGreenLight();
IStrategy *block = new BlockEnemy();
Context *context = new Context(backDoor);
context->operate();
context = new Context(greenLight);
context->operate();
context = new Context(block);
context->operate();
return 0;
}
如果系统中的一个策略家族的具体策略数量超过4个,则需要考虑使用混合模式,解决策略类膨胀和对外暴露的问题,否则日后的系统维护就会很麻烦。
1. 需求说明
输入3个参数,进行加减运算,参数中两个是int,一个是QString,只有“+”、“-”两个符号可以选择,不考虑校验
//////////////////////// ********** 3. 算数加减法(方案一),代码清单18-3:***************//
class Calculator
{
public:
int exec(int a, int b, QString symbol)
{
int result = 0;
if (symbol == this->m_add)
{
result = this->add(a, b);
}
else if (symbol == this->m_sub)
{
result = this->sub(a, b);
}
return result;
}
private:
int add(int a, int b){return a + b;}
int sub(int a, int b){return a - b;}
private:
static QString m_add;
static QString m_sub;
};
QString Calculator::m_add = "+";
QString Calculator::m_sub = "-";
int main()
{
int a = 10;
int b = 20;
Calculator cal;
qDebug() << cal.exec(a, b, "+");
return 0;
}
//////////////////////// ********** 4. 算数加减法(方案二),代码清单18-4:***************//
class Calculator
{
public:
int exec(int a, int b, QString symbol)
{
return (symbol == m_add)? a+b:a-b;
}
private:
int add(int a, int b){return a + b;}
int sub(int a, int b){return a - b;}
private:
static QString m_add;
static QString m_sub;
};
QString Calculator::m_add = "+";
QString Calculator::m_sub = "-";
int main()
{
int a = 10;
int b = 20;
Calculator cal;
qDebug() << cal.exec(a, b, "+");
return 0;
}
////////////// ********** 5. 算数加减法(方案三:策略模式),代码清单18-5:***************//
class Calculator
{
public:
virtual int exec(int a, int b) = 0;
};
class Add:public Calculator
{
public:
virtual int exec(int a, int b)
{
return a + b;
}
};
class Sub:public Calculator
{
public:
virtual int exec(int a, int b)
{
return a - b;
}
};
class Context
{
public:
Context(Calculator *cal)
{
this->m_cal = cal;
}
int exec(int a, int b)
{
return this->m_cal->exec(a, b);
}
private:
Calculator *m_cal;
};
int main()
{
int a = 10;
int b = 20;
Calculator *cal = new Add();
Context context(cal);
qDebug() << context.exec(a, b);
return 0;
}
策略模式是一个非常简单的模式。他在项目中使用的非常多,但单独使用的地方比较少,因为有致命缺陷:所有的策略都需要暴露出去,这样才方便客户端决定使用哪一个策略。
参考文献《秦小波. 设计模式之禅》(第2版) (华章原创精品) 机械工业出版社