策略模式
定義了算法族,分別封裝起來,讓他們之間能夠互相替換,此模式讓算法的變化獨立於使用算法的客戶。
例子:要設計一套成功的模擬鴨子游戲:SimUDuck.遊戲中會出現各類鴨子,一邊游泳戲水,一邊呱呱叫。可是有些鴨子是否是通常的鴨子,例如橡皮鴨子(會叫不會飛),木頭鴨子(不會飛也不會叫),若是全部鴨子都繼承Duck,那麼不少方法要覆蓋掉,不經過繼承又實現不了代碼的通用。
class Duck{
quack();
swim();
display();
flay();
}
那麼咱們應該這樣,找出應用中可能須要變化之處,把它們單獨出來,不要和那些不須要變化的代碼混合在一塊兒,這也是咱們須要掌握的設計原則。
咱們知道Duck類內的fly()和quack()會隨着鴨子的不一樣而改變。
如今Duck類仍是全部鴨子的超類,可是飛行和呱呱叫的行爲已經取出來,放在別的類的結構中。
那麼如何設計那組實現飛行和呱呱叫的行爲的類呢?
咱們但願一切能有彈性 ,畢竟,正是由於一開始鴨子行爲沒有彈性,才讓咱們走上如今這條路的。咱們還想可以「指定」行爲到鴨子的實例。好比說,咱們想要產生一個新的綠頭鴨實例,並指定特定類型的飛行行爲給它。乾脆隨便讓鴨子的行爲能夠動態地改變好了,換句話說,咱們應該在鴨子類中包含設定行爲的方法,這樣就能夠在「運行時」動態地「改變」綠頭鴨子的飛行行爲。
因此咱們應該
針對接口編程,而不是針對實現編程
「針對實現編程」
Dog d=new Dog();
d.bark();
而「針對接口/超類型編程」
Animal animal=new Dog();
animal.makeSound();
因此,在此,咱們有兩個接口,FlyBehavior和QuackBehavior,還有它們對應的類,負責實現具體的行爲:
interface FlyBehavior{
fly();
}
這是一個接口,全部的飛行類都實現它,全部新的飛行類都必須實現fly()方法。
class FlyWithWings implements
FlyBehavior{
fly(){
//實現鴨子飛行
}
}
class FlyNoWay implements
FlyBehavior{
fly(){
//什麼都不會作,不會飛
}
}
這樣一來,有了繼承的"複用"好處,卻沒有繼承帶來的包袱。(這樣的設計,可讓飛行和呱呱叫的動做被其餘的對象複用,由於這些行爲已經與鴨子類無關了,而咱們能夠新增一些行爲,不會影響到既有的行爲類,也不會影響」使用「到飛行行爲的鴨子類 )
下面是到整合鴨子的行爲了
class Duck{
FlyBehavior flyBehavior;//飛行行爲
public void performFly(){
flyBehavior.fly();
}
}
而後繼續Duck類即可以了。
public class MallardDuck extends{
public MallardDuck(){
flyBehavior=new FlyWithWings();
}
}
public class Test{
public static void main(String[] args){
Duck d=new MallardDuck();
d.fly();
}
} 算法