定义
定义一系列的算法,把它们一个一个的封装起来,并且使它们可以相互替换,策略模式使得算法可以独立于使用者而变化。
案例
比如现在有一个文件编辑器Editor,它在保存的时候,可以保存为任意的格式。所有文件内容转换均由Convertor提供,根据不同的选择,提供不同内容转换支持:TXTConvertor,PDFConvertor,DOCConvertor等等。Editor维护对Convertor对象的一个引用,一旦要进行文件内容转换,就把职责交给Convertor对象。把转换算法和Editor分离,可以简化代码的复杂性,便于维护,又可以很好的扩充新的算法。实现的时候不一定非要使用一个公共的基类,也可以使用模板的方式进行,这里使用基类的方式:
在Editor类中维护一个Convertor对象,在保存的时候调用该对象的相关方法:
class Editor
{
public:
void save();
void setConvertor(Convertor* convertor) { m_convertor = convertor; }
private:
string m_text;
Convertor* m_convertor;
};
void Editor::save()
{
String text = m_convertor->convert(m_text);
// save text to file.
}
Convertor提供接口供Editor调用:
class Convertor
{
public:
vritual string& convert(const string& text) = 0;
};
其子类对该方法进行不同的实现:
class TXTConvertor : public Convertor
{
public:
virtual string& convert(const string& text)
{
// convert to txt data.
}
};
class PDFConvertor : public Convertor
{
public:
virtual string& convert(const string& text)
{
// convert to pdf data.
}
};
class DOCConvertor : public Convertor
{
public:
virtual string& convert(const string& text)
{
// convert to doc data.
}
};
在使用的时候,根据不同情况设置不同Convertor:
Edtior* editor = new Editor();
Convertor* txtConvertor = new TXTConvertor();
editor->setConvertor(txtConvertor);
editor->save();
...
Convertor* pdfConvertor = new PDFConvertor();
editor->setConvertor(pdfConvertor);
editor->save();
适用性
- 如果许多的类之间仅仅是行为有异
- 需要使用一个算法的不同变体
- 算法使用用户不知道的数据,策略模式避免了暴露复杂的、与算法相关的数据结构
- 一个类定义了多种行为,并且这些行为在这个类中是以多个条件语句方式出现的。