## 模式定義 ? ? ? ?
策略模式定義了算法族,分別封裝起來,讓它們之間可以互相替換,此模式讓算法的變化獨立于使用算法的客戶。
## 模式結構

## 舉例:
? ? ? 游泳池中有不同種類的鴨子,有綠頭鴨,紅頭鴨,橡皮鴨,木頭鴨等。不同鴨子的特征或行為不同。綠頭鴨(MallardDuck)可以叫聲是“quack”,會飛;橡皮鴨叫聲是“queak”,不會飛;木頭鴨不會叫,也不會飛。利用面向對象原理來設計來泳池中的各種鴨。要求:1.可擴展性好,當有新鴨加入時或鴨的行為有變動時,不用大量改動代碼;2.復用性強。
## 設計UML圖

? ? ? 其中,Duck為一個基類,MallardDuck,RedheadDuck, RubberDuck, DecoyDuck繼承自Duck。
FlyBehavior, QuackBehavior為鴨子的飛行和叫聲行為,在java中可用接口表示,在C++中用抽象類表示。FlyWithWings等方法用來實現鴨子的行為。
## 代碼實現及執行結果:
~~~
#include <iostream>
//飛行行為,用抽象類表示
classFlyBehavior{
public:
virtual ~FlyBehavior(){};
virtual void fly() =0;
};
//叫聲行為,用抽象類表示
classQuackBehavior{
public:
virtual ~QuackBehavior(){};
virtual void quack()= 0;
};
//鴨子基類,有display,performFly, performQuack,swim等方法。
classDuck{
public:
Duck(FlyBehavior*p_FlyBehavior,QuackBehavior* p_QuackBehavior)
{
pFlyBehavior= p_FlyBehavior;
pQuackBehavior= p_QuackBehavior;
}
virtual ~Duck(){};
virtual voiddisplay(){};
void performFly()
{
pFlyBehavior->fly();
}
void performQuack()
{
pQuackBehavior->quack();
}
void swim()
{
std::cout<<("All ducks float, even decoys!")<< std::endl;
}
private:
FlyBehavior*pFlyBehavior;
QuackBehavior*pQuackBehavior;
};
//實現飛行行為的方法類
classFlyWithWings : public FlyBehavior{
public:
void fly(){
std::cout<< ("I'm flying!!")<<std::endl;
}
};
classFlyNoWay : public FlyBehavior{
public:
void fly(){
std::cout<< ("I can't fly")<<std::endl;
}
};
//實現叫聲行為的類
classQuack : public QuackBehavior{
public:
void quack(){
std::cout<< ("Quack") <<std::endl;
}
};
classMuteQuack : public QuackBehavior{
public:
void quack(){
std::cout<< ("<< Slience >>")<< std::endl;
}
};
classSqueak : public QuackBehavior{
public:
void quack(){
std::cout<< "Squeak"<<std::endl;
}
};
//綠頭鴨類
classMallardDuck : public Duck{
public:
MallardDuck(FlyBehavior*fly_behavior = new FlyWithWings(),
QuackBehavior*quack_behavior = new Quack())
:Duck(fly_behavior,quack_behavior){}
void display()
{
std::cout<< "I'm a real Mallard duck"<< std::endl;
}
};
intmain()
{
Duck*mallard = new MallardDuck();
mallard->performFly();
mallard->performQuack();
return 0;
}
~~~
執行結果如下:
I'm flying!!
Quack
請按任意鍵繼續. . .
## 設計原則
? ? ? 可擴張性:當有新類型鴨子加入時,只要讓其繼承Duck類,并添加相應的行為方法類,初始化式用需要的行為方法類來初始化即可。
? ? ? 復用性:如會飛的鴨都可以用FlyWithWings。
? ? ? 設計原則的應用:
? ? ? 設計原則1:找出應用中可能需要變化之處,把他們獨立出來,不要和哪些不需要變化的代碼混在一起。(另外一種表述:將會變化的部分取出來并封裝起來,好讓其他部分不會受影響)。如上述例子中的FlyBehavior和QuackBehavior行為。
? ? ? 設計原則2:針對接口編程,而不是針對實現編程。如上述例子中的FlyBehavior和QuackBehavior,它們的實現都將實現其中的一個接口,而鴨子基類不會負責實現FlyBehavior和QuackBehavior接口。
? ? ? 設計原則3:多用組合,少用繼承。如本例中,每一鴨子都有一個FlyBehavior和QuackBehavior。
參考
Head First設計模式