《Head First設計模式》筆記整理...歡迎交流...算法
定義了算法簇,分別封裝起來,讓他們之間能夠 相互替換,此模式讓算法的變化獨立於使用算法的客戶。
這裏稍微提醒一下,策略模式是咱們學習的第一個模式,理解它仍是很是重要的。這個模式跟後面講到的 模板模式 有些類似的地方,我在學習的時候,看到模板模式已經忘記什麼是策略模式了,看的一臉懵逼。不過不要緊,後面我會針對這兩個進行整理,這裏要記住的是,策略模式封裝了一組能夠互換的算法簇,是針對接口編程的。編程
爲何要封裝變化?先來看下面的例子。設計模式
dock類是全部鴨子的超類,其中,飛行(fly)行爲和呱呱叫(quack)行爲會隨着鴨子的不一樣而改變。若是咱們不區分變化,將全部的行爲定義在超類裏。如圖:學習
顯而易見的,這種設計會致使測試
爲了便於之後能夠輕易地改動和擴展此部分,而不會影響不須要改變的其它部分,咱們把變化的部分取出並封裝起來。spa
使用繼承如何?設計一個flyable接口和一個quackable接口。設計
哇,一堆重複的代碼,並且代碼難以複用。甚至在會飛的鴨子中,飛行的動做也多是變幻無窮的。若是咱們想要更加彈性一點,在運行時也能夠動態地選擇行爲,該怎麼辦呢?code
針對接口編程,而不是針對實現編程。這裏所謂的「接口」有多個含義,接口能夠是一個「概念」。」針對接口變成「,關鍵就在於「多態」,能夠更明確地說,變量的聲明類型應該是超類型。這也意味着,聲明類是沒必要理會之後執行時的真正的對象類型。orm
如此,鴨子的行爲被放在分開的類中,此類專門提供行爲的接口實現。
這樣,鴨子類就再也不須要知道行爲的實現細節。對象
當你講兩個類結合起來使用,就是組合。如圖本列,將飛行行爲和呱呱叫行爲委託給FlyBehavior和QuackBehavior代爲處理。組合創建系統有很大的彈性,不只可將算法簇封裝成類,更能夠在運行時動態地改變行爲,只要組合的行爲對象符合正確的接口便可。
publick abstract class Duck { //爲行爲接口類型聲明兩個引用變量,全部鴨子子類都繼承它們 FlyBehavior flyBehavior; QuackBehavior quackBehavior; public Duck() { } publick abstract void display(); public void performFly() { flyBehavior.fly(); //委託行爲給類 } public void performQuack() { quackBehavior.quack(); //委託行爲給類 } public viod setFlyBehavior(FlyBehavior fb) { flyBehavior = fb; //動態設定飛行行爲 } public viod setQuackBehavior(QuackBehavior qb) { quackBehavior = qb; //動態設定呱呱叫行爲 } } ----------------------------------------------------------- public interface FlyBehavior { public void fly(); } public class FlyWithWings implements FlyBehavior { public viod fly() { System.out.printIn("I'm flying!"); } } public class FlyNoWay implements FlyBehavior { public void fly { System.out.printIn("I can't fly!"); } } ----------------------------------------------------------- public class QuackBehavior { public void quack(); } public class Quack implements QuackBehavior { public void quack() { //此處省略 } } public class MuteQuack implements QuackBehavior { public void quack() { //此處省略 } } public class Squack implements QuackBehavior { public void quack() { //此處省略 } }
//製造一個新的鴨子類型:模型鴨 public class ModelDuck extends Duck { public ModelDuck() { flyBehavior = new FlyNoWay(); quackBehavior = new Quack(); } public viod display () { System.out.printIn("I'm a model duck"); } } -------------------------------------------------------- //新建一個新的FlyBehavior類型 public class FlyRocketPowered implements FlyBehavior{ public viod fly() { System.out.printIn("I'm flying with a rocket!"); } }
最後,來看看一個簡單的測試
Duck model = new ModelDuck(); model.performFly(); // i can't fly! model.setFlyBehavior(new FlyRocketPowered()); //動態改變行爲 model.performFly(); // I'm flying with a rocket!
若是咱們再也不把鴨子的行爲看作「一組行爲」,而是想成是「一簇算法」,將這些算法抽離並封裝起來,委託給對象,經過組合實現運行時算法互換,這就是策略模式。
好了,你以爲個人整理如何呢?若是有什麼理解不對的地方,或者你有更好的想法歡迎交流。