帶你領略設計模式的魅力

一、策略模式——經典的“鴨子”行爲問題

1、定義策略模式定義了算法族,分別封裝起來,讓他們之間可以互相替換,此模式讓算法的變化獨立於使用算法的客戶

涉及設計原則

  1. 針對接口編程,而不是針對實現編程
  2. 找代碼中變化的地方並把他們獨立出來與不變的代碼區分開

核心:運用類的多態性 實現了超類引用對其所有子類的管理(向上轉型) 而子類的動作則是專門有行爲接口去規定 子類的具體行爲由動作接口實現去描述 最後超類和接口進行"組合" 實現了各個子類動作的真正區分

下面圖片 均來自headfirst 設計模式一書 源碼自己寫的

鴨子游戲問題:
模擬鴨子活動,有各種鴨子 會游泳、會飛、會叫
圖解:
在這裏插入圖片描述
選擇鴨子作爲一個超類 所有的鴨子都必須繼承它
在這裏插入圖片描述
但是這樣會導致各種各樣的問題

  1. 有的鴨子不會飛
  2. 有的鴨子不會叫
    所以我們不能一味的繼承 而是需要另一種方法 去實現
    在這裏插入圖片描述
    從上面我們知道了 鴨子都能游泳 但是有的鴨子卻不會叫,有的鴨子能飛!所以我們需要在鴨子的超類上保留游泳動作,而會叫和能飛這兩個動作就被提取出去了 但是接下來又該怎麼辦呢?
    在這裏插入圖片描述
    解決:
    將超類的飛 和叫 兩個動作提取出去 當做接口使用 面向接口化編程 即把 fly 和 quack 不確定的方法抽取出去 封裝在 一個飛動作接口 和 叫動作接口 下面是具體實現
    在這裏插入圖片描述
    整合鴨子的行爲 所有的動作接口變量都在超類duck中 由超類控制公共方法 實現類某個方法實現接口變量 下面是具體做法
    在這裏插入圖片描述
    在這裏插入圖片描述

具體代碼:
在這裏插入圖片描述

 * @description  超類
 **/
public abstract class Duck  {

    public FlyBehavior flyBehavior;

     public QuckBehavior quckBehavior;

    public void quck(){
          quckBehavior.quck();
    }

    public void fly(){
          flyBehavior.fly();
    }
    public void swimming(){
        System.out.println("鴨子都會游泳!");
    }

}

"飛"行爲接口

public interface FlyBehavior {
    /**
     * 飛
     */
    void fly();
}

"叫"行爲接口

public interface QuckBehavior {
    /**
     * 叫
     */
    void quck();
}

會飛鴨子動作具體實現

public class CanFlyImpl implements FlyBehavior {

    @Override
    public void fly() {
        System.out.println("這隻鴨子會飛");
    }
}

會叫鴨子動作具體實現

public class CanQuckImpl implements QuckBehavior {

    @Override
    public void quck() {
        System.out.println("這隻鴨子會叫");
    }
}

不會飛鴨子動作具體實現

public class NoWayFlyImpl implements FlyBehavior {


    @Override
    public void fly() {
        System.out.println("這隻鴨子不會飛");
    }
}

不會叫鴨子動作具體實現

public class NoWayQuckImpl implements QuckBehavior {


    @Override
    public void quck() {
        System.out.println("這隻鴨子不會叫");
    }
}

會飛的鴨子實體類

 * @description  會飛的鴨子
 **/ 
public class CanFlyDuck extends Duck  {

    public CanFlyDuck() {
        //具體實現動作接口
        this.flyBehavior = new CanFlyImpl();
        this.quckBehavior = new NoWayQuckImpl();
    }

    public void display(){
        System.out.println("會飛的鴨子卻不會叫");
    }
}

會叫的鴨子實體類

 * @description 會叫的鴨子
 **/
public class CanQuckDuck extends Duck {


    public CanQuckDuck() {
    //具體實現動作接口
        this.flyBehavior = new CanFlyImpl();
        this.quckBehavior = new NoWayQuckImpl();
    }

    public void display(){
        System.out.println("會飛的鴨子卻不會叫");
    }
}

測試:

/**
 * 策略模式
 */
Duck duck = new CanFlyDuck();
((CanFlyDuck) duck).display();
duck.fly();
duck.quck();
Duck duck1 = new CanQuckDuck();
((CanQuckDuck) duck1).display();
duck1.quck();
duck1.fly();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章