首先什麼是“策略模式”:定義了算法家族,分別封裝起來,讓他們之間可以相互替換,讓算法的變化,不會影響到使用算法的客戶。大話設計模式P23)
我們先來看看策略模式的UML類圖是怎樣的。

1、其中Context類利用ConcreteStrategy類來配置,維護Strategy的引用
2、Strategy類是算法的公共接口
3、ConcreteStrategy類則實現了算法的行為
注意:其中Context類和Strategy類是一種“聚合關系”,是一種弱的擁有關系,其與組合關系的區別是:組合關系是一種強的擁有關系,組合關系中相互之間的生命周期是相同的。而聚合關系則不要求,我的理解是:Context可以有Strategy,但是即使不存在Context,Strategy本身也是可以存在的。其中的細微差別需要好好品味。
代碼實現:
為簡便我省略掉頭文件和命名空間的聲明。
//Context
class Context {
public:
Context(Strategy* s) : strategy(s) {}
void ContextInterface() {
strategy->AlgorithmInterface();
}
private:
Strategy *strategy;
};//Strategy
class Strategy {
public:
virtual void AlgorithmInterface() = 0;
};
//ConcreteStrategyA
class ConcreteStrategyA : public Strategy {
public:
void AlgorithmInterface() {
//do A
}
};
//ConcreteStrategyB
class ConcreteStrategyB : public Strategy {
public:
void AlgorithmInterface() {
//do B
}
};客戶端:
int main() {
//以下代碼只作示范使用,實際上用new產生的對象是在heap中的
//所以第二次new的時候,第一次產生的對象不會自動刪除,因此會產生內存洩露
//我們可以手動delete,或者利用智能指針來解決
Strategy *s = new ConcreteStrategyA();
Context *c = new Context(s);
c->ContextInterface();
s = new ConcreteStrategyB();
c = new Context(s);
c->ContextInterface();
return 0;
}下面我找個例子來試驗一下:游戲中根據選擇的職業不同,攻擊方式也會不同
游戲角色類
//游戲角色類
class Player {
public:
Player(Character* c) : pChar(c) {}
void action() {
pChar->attack();
}
private:
Character *pChar;
};職業類
//職業類接口
class Character {
public:
virtual void attack() = 0;
};
//劍士
class Saber : public Character {
public:
void attack() {
cout << "斬擊" << endl;
}
};
//弓箭手
class Archer : public Character {
public:
void attack() {
cout << "射擊" << endl;
}
};
//魔法師
class Caster : public Character {
public:
void attack() {
cout << "火球術" << endl;
}
};客戶端
int main() {
Player *player;
cout << "魔法師攻擊: ";
player = new Player(new Caster());
player->action();
cout << "劍士攻擊: ";
player = new Player(new Saber());
player->action();
return 0;
}
策略模式有助於我們應對算法行為的變化,例如上述的例子中,如果我們增加新的職業,我們只需要添加新職業的類,之後在人物當中配置新職業的類,我們就可以應對這種變化。
本文出自 “加和文的世界” 博客,請務必保留此出處http://xuyjun.blog.51cto.com/7470650/1303831