策略模式

概念:

  策略模式定義了算法族,分別封裝起來,讓它們之間能夠互相替換,此模式讓算法的變化獨立於使用算法的客戶。java

  不少同窗可能不太理解這個定義,我舉個簡單的例子,好比客戶要實現一個功能,分爲A,B,C,D4個步驟完成,其中A和C步驟是很容易發生改變的,因此咱們將A和C步驟分別封裝起來,算法

  具體實現方式是將A和C定義爲接口,各自分別有1,2,3種實現方式。此時A和C對應的就是算法族,各自的實現叫作算法,各個算法之間能夠相互替換,來達到不一樣的實現目的。客戶編程

  須要實現的功能能夠由A和C算法族組合實現各式各樣不一樣的功能,而咱們實現功能的主幹永遠不會改變。ide

設計原則:

  上面的小例子也用到了幾個設計原則:測試

  1,將程序中可能須要改變的部分獨立出來,不要和不須要變化的代碼放在一塊兒。this

  2,針對接口編程,而不是針對實現編程。設計

  3,少用繼承,多用組合。對象

  第1點相信你們都能理解,可是在實際工做中,要完美的運用實際上並無那麼簡單。blog

  第2點,先說說針對接口編程的好處,就好比例子中,主幹功能代碼不須要任何改變,咱們就能實現各類不一樣功能的實現,精髓就在各個具體的算法實現了一個接口,咱們只須要傳入不一樣的具體的實現繼承

  就能輕鬆實現不一樣的功能。若是你不理解爲何能這樣作,那你可能還不理解java的多態,父類引用指向子類對象。咱們也能夠經過這個例子來反向理解多態,你會發現原來多態就是這樣,so easy!

  第3點,少用繼承,多用組合。繼承太過於笨重,若是我繼承某個接口或者類,我就必須實現這個接口或者類的全部方法,這顯然是不合理的,組合就不同了,我能夠任意組合實現各類各樣的功能。

  好比A的一種具體實現和C的一種具體實現就是一類組合,這裏咱們能夠實現3x3=9種組合,也就意味着有9種實現該功能的方式,若是須要增長,咱們只須要增長一種實現類,而不須要修改主幹的任意

  代碼就能輕易實現。

代碼實現:

  這裏舉一個簡單的小例子,好比某明顯開一場演唱會,後臺調音師須要根據明星演唱的歌曲準備背景音樂。這裏就能夠運用策略模式去實現。

  1,先定義一個背景音樂的接口,建立一個播放的方法。

package strategy;

/**
 * @ClassName BackgroundMusic
 * @Description 背景音樂接口
 * @Author liuyi
 * @Date 2020/6/14 11:08
 * @Version 1.0
 */
public interface BackgroundMusic {
    /**
     * @Author liuyi
     * @Description 定義播放的方法
     * @Date 11:10 2020/6/14
     * @Param []
     * @return void
     **/
    public void play();
}

  

2,分別有三種背景音樂去實現該接口

  背景音樂1

package strategy;

/**
 * @ClassName BackgroundMusic1
 * @Description TODO
 * @Author liuyi
 * @Date 2020/6/14 11:12
 * @Version 1.0
 */
public class BackgroundMusic1 implements BackgroundMusic {
    @Override
    public void play() {
        System.out.println("開始播放背景音樂1");
    }
}

  背景音樂2

package strategy;

/**
 * @ClassName BackgroundMusic2
 * @Description TODO
 * @Author liuyi
 * @Date 2020/6/14 11:13
 * @Version 1.0
 */
public class BackgroundMusic2 implements BackgroundMusic{
    @Override
    public void play() {
        System.out.println("開始播放背景音樂2");
    }
}

  背景音樂3

package strategy;

/**
 * @ClassName BackgroundMusic3
 * @Description TODO
 * @Author liuyi
 * @Date 2020/6/14 11:13
 * @Version 1.0
 */
public class BackgroundMusic3 implements BackgroundMusic {
    @Override
    public void play() {
        System.out.println("開始播放背景音樂3");
    }
}

  3,建立背景音樂編號枚舉類

package strategy;

/**
 * @ClassName MusicNumEnum
 * @Description 背景音樂編號枚舉類
 * @Author liuyi
 * @Date 2020/6/14 11:20
 * @Version 1.0
 */
public enum MusicNumEnum {
    music1(1,"strategy.BackgroundMusic1"),
    music2(2,"strategy.BackgroundMusic2"),
    music3(3,"strategy.BackgroundMusic3");

    MusicNumEnum(int num, String className){
        this.num = num;
        this.className = className;
    }
    //編號
    private int num;
    //類名稱
    private String className;

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }
    //根據num獲取className
    public static String getClassNameByNum(int num){
        MusicNumEnum[] values = MusicNumEnum.values();
        for (MusicNumEnum value : values) {
            if(value.getNum()==num){
                return value.getClassName();
            }
        }

        return null;
    }

}

  4,測試

package strategy;

/**
 * @ClassName StrategyTest
 * @Description 策略模式測試類
 * @Author liuyi
 * @Date 2020/6/14 11:16
 * @Version 1.0
 */
public class StrategyTest {
    public static void main(String[] args) throws Exception {
        palyByNum(1);
        palyByNum(3);
        palyByNum(2);
    }
    /**
     * @Author liuyi
     * @Description 根據播放編號播放對應的背景音樂
     * @Date 11:41 2020/6/14
     * @Param [num]
     * @return void
     **/
    public static void palyByNum(int num) throws Exception{
        //根據背景音樂編號播放對應的背景音樂
        BackgroundMusic backgroundMusic = (BackgroundMusic)(Class.forName(MusicNumEnum.getClassNameByNum(num)).newInstance());
        backgroundMusic.play();
    }
}

  從代碼能夠看出咱們須要播放某個由於,只須要傳入對應的編號便可,不須要對主幹代碼進行修改。若是下場演唱會須要新增背景音樂,則添加一個背景音樂類,而後在枚舉類配置對應的編號和類的關係便可。

從策略模式的概念來看,每一種背景音樂其實就是一種具體的算法,背景音樂1,背景音樂2,背景音樂3它們之間能夠互相替換,來達到不一樣的目的,而使用的客戶是不須要知道這些的存在的, 用戶只須要傳入算法

對應的編號或者類型便可。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息