設計模式|01 策略模式

  • 2019 年 10 月 4 日
  • 筆記

開頭說幾句

博主博客地址:https://www.jeffcc.top/ 設計模式系列是我通過看Head First 的《設計模式》中學到的知識總結,這是本不錯的設計模式入門書籍,強烈推薦!

什麼是策略模式

權威定義:策略模式定義了算法簇,使不同的行為分別封裝起來,讓他們可以相互替換,此模式讓算法的變化獨立於使用算法的對象! 我的理解:將相同的行為共同封裝進入超類,不同的行為單獨封裝,以實現功能!

設計原則

  1. 找到應用中可能需要變化的部分,並且把他們獨立起來,通過面向接口的編程方式進行獨立劃分,不需要和那些不需要變化的代碼混合在一起。
  2. 針對接口(超類型)編程,而不是針對實現編程。
  3. 多用組合,少用繼承。

模式實例

背景

  1. 需要定義一個鴨子超類,用於顯示組合鴨子的共性的行為;
  2. 需要我們定義出一些鴨子的所具有的一些特性:例如飛行和叫聲的行為單獨接口組合
  3. 實現鴨子的相關正確的行為,(不會出現橡皮鴨會飛等的情況)

代碼實現

項目類圖
項目結構
鴨子的超類
package main;    import main.fly.IFlyBehavior;  import main.quack.IQuackBehavior;    /**   * 模擬策略模式   * 行為對象代替繼承   */  public abstract class Duck {    //    定義一個飛行的行為      private IFlyBehavior flyBehavior;  //    定義一個叫聲的行為      private IQuackBehavior quackBehavior;        public Duck(IFlyBehavior flyBehavior, IQuackBehavior quackBehavior) {  //        構造函數聲明          this.flyBehavior = flyBehavior;          this.quackBehavior = quackBehavior;      }    //    鴨子的行為      public abstract void displace();    //    組合一層鴨子的飛行行為,不使用繼承      public void performFly(){          flyBehavior.fly();      }  //    組合一層鴨子的叫聲行為,不使用繼承      public void performQuack(){          quackBehavior.quack();      }    //    手動設置飛行行為      public void setFlyBehavior(IFlyBehavior flyBehavior) {          this.flyBehavior = flyBehavior;      }  //    手動設置叫聲行為      public void setQuackBehavior(IQuackBehavior quackBehavior) {          this.quackBehavior = quackBehavior;      }  }  
模型鴨類

package main;    import main.fly.Impl.FlyNoWayImpl;  import main.quack.Impl.MuteQuackImpl;    /**   * 模型鴨   * 繼承鴨子行為   */  public class ModelDuck extends Duck {    //    給模型鴨設定一個 不能飛 不會叫的行為      public ModelDuck(){          super(new FlyNoWayImpl(),new MuteQuackImpl());      }        @Override      public void displace() {          System.out.println("I am a model duck!");      }  }  
叫聲行為接口
package main.quack;    /**   * 叫聲行為接口   */  public interface IQuackBehavior {      void quack();  }  

飛行行為接口

package main.fly;    /**   * 飛行行為接口   */  public interface IFlyBehavior {      void fly();  }  
不能飛的實現類
package main.fly.Impl;    import main.fly.IFlyBehavior;    /**   * 不能飛的實現類   */  public class FlyNoWayImpl implements IFlyBehavior {      @Override      public void fly() {          System.out.println("I can not fly!");      }  }    
可以飛的實現類
package main.fly.Impl;    import main.fly.IFlyBehavior;    /**   * 可以飛的實現類   */  public class FlyWithWingsImpl implements IFlyBehavior {        @Override      public void fly() {          System.out.println("I can fly!");      }  }    
叫聲行為接口
package main.quack;    /**   * 叫聲行為接口   */  public interface IQuackBehavior {      void quack();  }    
不能叫的實現類
package main.quack.Impl;    import main.quack.IQuackBehavior;    /**   * 不能叫的實現類   */  public class MuteQuackImpl implements IQuackBehavior {      @Override      public void quack() {          System.out.println("Silence");      }  }    
哇哇叫的實現類
package main.quack.Impl;    import main.quack.IQuackBehavior;    /**   * 哇哇叫的實現類   */  public class QuackImpl implements IQuackBehavior {      @Override      public void quack() {          System.out.println("Qucak");      }  }    
呱呱叫的實現類
package main.quack.Impl;    import main.quack.IQuackBehavior;    /**   * 呱呱叫   */  public class SqueckImpl implements IQuackBehavior {      @Override      public void quack() {          System.out.println("Squeak");      }  }  
測試類
package test;    import main.Duck;  import main.ModelDuck;  import main.fly.Impl.FlyWithWingsImpl;  import main.quack.Impl.QuackImpl;    /**   * 測試類   */  public class DuckTest{        public static void main(String[] args) {  //        創建一個模型鴨的實例          Duck duck = new ModelDuck();          duck.setFlyBehavior(new FlyWithWingsImpl());          duck.setQuackBehavior(new QuackImpl());          duck.performFly();          duck.performQuack();          duck.displace();      }  }  
輸出結果: