時間:2017年08月31日星期四
說明:本文部份內容均來自慕課網。@慕課網:http://www.imooc.com
教學源碼:https://github.com/zccodere/s...
學習源碼:https://github.com/zccodere/s...git
課程大綱github
什麼是策略模式 策略模式如何實現 策略模式總結篇 實例案例分享
平常生活中的策略算法
World文檔中的排版佈局 購物支付過程當中選擇支付渠道
案例示意圖編程
策略模式定義架構
策略模式將可變的部分從程序中抽象分離成算法接口, 在該接口下分別封裝一系列算法實現並使他們能夠相互替換, 從而致使客戶端程序獨立於算法的改變。
模擬應用背景框架
經過代碼來實現策略模式,經過開發與重構虛擬應用 使用策略模式實現,在不變動代碼框架的前提下 不斷的擁抱需求的變化,從而知足客戶需求
項目背景:鴨子應用ide
代碼編寫工具
1.編寫Duck類佈局
package com.myimooc.designpattern.c7strategy; /** * @title 策略模式 * @describe 超類,全部的鴨子都要繼承此類,抽象了鴨子的行爲:顯示和鳴叫 * @author zc * @version 1.0 2017-08-31 */ public abstract class Duck { /** * 鴨子發出叫聲,通用行爲,由超類實現 */ public void quack(){ System.out.println("嘎嘎嘎"); } /** * 顯示鴨子的外觀,鴨子的外觀各不相同,聲明爲abstract,由子類實現 */ public abstract void display(); }
2.編寫MallardDuck類學習
package com.myimooc.designpattern.c7strategy; /** * @title 策略模式 * @describe 綠脖子的鴨子 * @author zc * @version 1.0 2017-08-31 */ public class MallardDuck extends Duck { @Override public void display() { System.out.println("個人脖子是綠色的"); } }
3.編寫RedheadDuck類
package com.myimooc.designpattern.c7strategy; /** * @title 策略模式 * @describe 紅色頭的鴨子 * @author zc * @version 1.0 2017-08-31 */ public class RedheadDuck extends Duck { @Override public void display() { System.out.println("個人頭是紅色的"); } }
在原有功能的基礎上新增飛行的功能
使用繼承:父類統一實現 定義抽象方法:由子類本身實現 使用組合:複合優先於繼承:多用組合,少用繼承
繼承優缺點
繼承是重用代碼的利器 但繼承並不老是最好的工具
什麼是組合
在類中增長一個私有域,引用另外一個已有的類的實例,經過調用引用實例的方法從而得到新的功能,這種設計被稱做組合(或複合)。
使用組合增長飛行功能
實現:將飛行行爲抽象爲接口,在父類中持有該接口,並由該接口代理飛行行爲 優勢:足夠靈活;複用代碼,更易於維護 缺點:策略類會增多;全部策略類都須要對外暴露
代碼編寫
1.編寫FlyingStrategy類
package com.myimooc.designpattern.c7strategy; /** * @title 策略模式 * @describe 策略接口,實現鴨子的飛行行爲 * @author zc * @version 1.0 2017-08-31 */ public interface FlyingStrategy { /** * 飛行行爲的方法 */ void performFly(); }
2.編寫FlyWithWin類
package com.myimooc.designpattern.c7strategy.impl; import com.myimooc.designpattern.c7strategy.FlyingStrategy; /** * @title 策略模式 * @describe 實現鴨子的飛行行爲,用翅膀飛行的類 * @author zc * @version 1.0 2017-08-31 */ public class FlyWithWin implements FlyingStrategy{ @Override public void performFly() { System.out.println("振翅高飛"); } }
3.修改Duck類
package com.myimooc.designpattern.c7strategy; /** * @title 策略模式 * @describe 超類,全部的鴨子都要繼承此類,抽象了鴨子的行爲:顯示和鳴叫 * @author zc * @version 1.0 2017-08-31 */ public abstract class Duck { /** * 鴨子發出叫聲,通用行爲,由超類實現 */ public void quack(){ System.out.println("嘎嘎嘎"); } /** * 顯示鴨子的外觀,鴨子的外觀各不相同,聲明爲abstract,由子類實現 */ public abstract void display(); // 組合進飛行的策略接口 private FlyingStrategy flyingStrategy; public void setFlyingStrategy(FlyingStrategy flyingStrategy) { this.flyingStrategy = flyingStrategy; } /** * 鴨子的飛行功能 */ public void fly(){ // 由飛行策略接口執行飛行的動做 flyingStrategy.performFly(); } }
4.修改MallardDuck類
package com.myimooc.designpattern.c7strategy; import com.myimooc.designpattern.c7strategy.impl.FlyWithWin; /** * @title 策略模式 * @describe 綠脖子的鴨子 * @author zc * @version 1.0 2017-08-31 */ public class MallardDuck extends Duck { public MallardDuck() { super(); super.setFlyingStrategy(new FlyWithWin()); } @Override public void display() { System.out.println("個人脖子是綠色的"); } }
5.修改RedheadDuck類
package com.myimooc.designpattern.c7strategy; import com.myimooc.designpattern.c7strategy.impl.FlyWithWin; /** * @title 策略模式 * @describe 紅色頭的鴨子 * @author zc * @version 1.0 2017-08-31 */ public class RedheadDuck extends Duck { public RedheadDuck() { super(); super.setFlyingStrategy(new FlyWithWin()); } @Override public void display() { System.out.println("個人頭是紅色的"); } }
6.編寫DuckTest類
package com.myimooc.designpattern.c7strategy; /** * @title 策略模式 * @describe 測試類 * @author zc * @version 1.0 2017-08-31 */ public class DuckTest { public static void main(String[] args) { System.out.println("測試鴨子程序"); System.out.println("*************************"); Duck duck = null; // duck = new MallardDuck(); // duck = new RedheadDuck(); // duck = new RubberDuck(); // duck = new BigYellowDuck(); duck = new SpaceDuck(); duck.display(); duck.quack(); duck.fly(); System.out.println("*************************"); System.out.println("測試程序完畢"); } }
業務場景
須要增長橡膠鴨、大黃鴨,它們都有一個共同的特色,不會飛行。 不會飛行也是一種飛行行爲,因此能夠經過良好的抽象複用代碼。
代碼編寫
1.編寫FlyNoWay類
package com.myimooc.designpattern.c7strategy.impl; import com.myimooc.designpattern.c7strategy.FlyingStrategy; /** * @title 策略模式 * @describe 實現鴨子的飛行行爲,不會飛行的策略類 * @author zc * @version 1.0 2017-08-31 */ public class FlyNoWay implements FlyingStrategy { @Override public void performFly() { System.out.println("我不會飛行!"); } }
2.編寫RubberDuck類
package com.myimooc.designpattern.c7strategy; import com.myimooc.designpattern.c7strategy.impl.FlyNoWay; /** * @title 策略模式 * @describe 橡膠鴨 * @author zc * @version 1.0 2017-08-31 */ public class RubberDuck extends Duck{ public RubberDuck() { super(); super.setFlyingStrategy(new FlyNoWay()); } @Override public void display() { System.out.println("我全身發黃,嘴巴很紅"); } @Override public void quack() { System.out.println("嘎~嘎~嘎~"); } }
3.編寫BigYellowDuck類
package com.myimooc.designpattern.c7strategy; import com.myimooc.designpattern.c7strategy.impl.FlyNoWay; /** * @title 策略模式 * @describe 大黃鴨 * @author zc * @version 1.0 2017-08-31 */ public class BigYellowDuck extends Duck{ public BigYellowDuck() { super(); super.setFlyingStrategy(new FlyNoWay()); } @Override public void display() { System.out.println("我身體很大,全身黃黃"); } }
4.修改DuckTest類
package com.myimooc.designpattern.c7strategy; /** * @title 策略模式 * @describe 測試類 * @author zc * @version 1.0 2017-08-31 */ public class DuckTest { public static void main(String[] args) { System.out.println("測試鴨子程序"); System.out.println("*************************"); Duck duck = null; // duck = new MallardDuck(); // duck = new RedheadDuck(); // duck = new RubberDuck(); // duck = new BigYellowDuck(); duck = new SpaceDuck(); duck.display(); duck.quack(); duck.fly(); System.out.println("*************************"); System.out.println("測試程序完畢"); } }
業務場景
如今又需增長太空鴨,太空鴨不能本身飛行,須要藉助先進的科學技術。
1編寫FlyWithRocket類
package com.myimooc.designpattern.c7strategy.impl; import com.myimooc.designpattern.c7strategy.FlyingStrategy; /** * @title 策略模式 * @describe 實現鴨子的飛行行爲,使用火箭飛行策略類 * @author zc * @version 1.0 2017-08-31 */ public class FlyWithRocket implements FlyingStrategy { @Override public void performFly() { System.out.println("用火箭在太空遨遊"); } }
2.編寫SpaceDuck類
package com.myimooc.designpattern.c7strategy; import com.myimooc.designpattern.c7strategy.impl.FlyWithRocket; /** * @title 策略模式 * @describe 太空鴨 * @author zc * @version 1.0 2017-08-31 */ public class SpaceDuck extends Duck { public SpaceDuck() { super(); super.setFlyingStrategy(new FlyWithRocket()); } @Override public void display() { System.out.println("我頭戴宇航盔"); } @Override public void quack() { System.out.println("我經過無線電與你通訊"); } }
3.修改DuckTest類
package com.myimooc.designpattern.c7strategy; /** * @title 策略模式 * @describe 測試類 * @author zc * @version 1.0 2017-08-31 */ public class DuckTest { public static void main(String[] args) { System.out.println("測試鴨子程序"); System.out.println("*************************"); Duck duck = null; // duck = new MallardDuck(); // duck = new RedheadDuck(); // duck = new RubberDuck(); // duck = new BigYellowDuck(); duck = new SpaceDuck(); duck.display(); duck.quack(); duck.fly(); System.out.println("*************************"); System.out.println("測試程序完畢"); } }
策略模式中的設計原則
找出應用中須要變化的部分,把他們獨立出來,不要和那些不須要變化的代碼混在一塊兒 面向接口編程,而不是面向實現編程 多用組合,少用繼承
策略模式的實現
經過分離變化得出的策略接口Strategy Strategy接口的實現類 客戶程序中有一個Strategy 在客戶程序中選擇和組裝正確的Strategy實現類
策略模式的優勢
使用了組合,使架構更加靈活 富有彈性,能夠較好的應對變化(開閉原則) 更好的代碼複用性(相對於繼承) 消除大量的條件語句
策略模式的缺點
客戶代碼須要瞭解每一個策略實現的細節 增長了對象的數目 全部策略類都須要對外暴露
策略模式的適用場景
許多相關的類僅僅是行爲差別 運行時選取不一樣的算法變體 經過條件語句在多個分支中選取其中一個