一天一個設計模式---策略模式

介紹:將具體的算法封裝到獨立的類中,當我們需要使用不同的策略時,只需要給執行對象提供不同的策略就行了。

場景:VR是現在很火的產品,一套好的VR設備是十分昂貴的,在初期由於市場供不應求,可能買來設備的價格高於官方報價。過了一段時間,賣家會降價,再過段時間,VR的勢頭過去,堆積的商品會進行促銷。

這個時候我們就可以使用策略模式,在不同時期,對於商品使用不同的價格策略來對價格進行調控。

優點:
- 避免過多使用if-else語句
- java源碼中FilterReader的一個構造函數會放入Reader類型的對象,這採用的就是策略模式
- 我們只需要在不同業務代碼提供不同策略,使得代碼高內聚低耦合
- 有的時候我們可能會考慮父類繼承,或者接口的方式,但是這樣可擴展性會很差,如下例子

一個方法,有很多個業務場景,繼承後業務不同,子類可能就需要重寫很多地方
public abstract class Bird {
    public void fly() {
        System.out.print("fly");
    }
}
// 有些鴨子不會飛
// 由於父類方法的繼承性這個時候如果大量子類需要對fly重寫爲cant fly就會改很多地方,100個就改100次
public class Bird extends Bird {
    public void fly() {
        System.out.print("cant fly");
    }
}
// 那麼考慮接口形式,那麼當實現類很多的時候,每個都要實現接口,100個也就100次,這裏就不擴展代碼了

一、角色及作用

角色 作用
環境(Context) 持有一個(Strategy)的引用
抽象策略(Strategy) 定義所有的具體策略類所需的實現的方法
具體策略(ConcreteStrategy) 實現具體方法,定義方法中的具體算法

二、應用場景

策略基類

提供降價接口

public interface Strategy {
    public double offerPrice(double orgPrice);
}

小幅度降價:打8折

public class DepreciateStrategy implements Strategy {

    @Override
    public double offerPrice(double orgPrice) {
        System.out.println("現在商品小降價");
        return .8 * orgPrice;
    }

}

提價:供不應求.爲原價的1.2倍

public class RaiseStrategy implements Strategy {

    @Override
    public double offerPrice(double orgPrice) {
        System.out.println("現在商品擡價");
        return 1.2 * orgPrice;
    }

}

促銷價:爲原價的一半

public class PromotionStrategy implements Strategy {

    @Override
    public double offerPrice(double orgPrice) {
        System.out.println("現在商品促銷價");
        return .5 * orgPrice;
    }

}

VR設備:環境類

public class VR {

    public double orgPrice = 10000.0; // 商品官方的報價

    private Strategy strategy;

    public VR(Strategy strategy) {
        this.strategy = strategy;
    }

    public double getPrice() {
        return strategy.offerPrice(orgPrice);
    }

}

場景應用

    public static void main(String[] args) {
        Strategy sg1 = new RaiseStrategy();
        VR vr1 = new VR(sg1);
        System.out.println(vr1.getPrice());

        Strategy sg2 = new DepreciateStrategy();
        VR vr2 = new VR(sg2);
        System.out.println(vr2.getPrice());

        Strategy sg3 = new PromotionStrategy();
        VR vr3 = new VR(sg3);
        System.out.println(vr3.getPrice());
    }

輸出

現在商品擡價
12000.0
現在商品小降價
8000.0
現在商品促銷價
5000.0

三、狀態模式和策略模式的比較

在網上學習其他大神博客的時候看到很多評論,這不是狀態模式是策略模式,或者這不是策略模式是狀態模式,不要誤人子弟。但是其實博主是正確的,而那些言語粗魯的人反而是自己無知(讓我十分反感)。狀態模式經常與策略模式相混淆。一個簡單的方法是考察環境角色是否有明顯的狀態和狀態的過渡。

狀態模式:
狀態模式處理的核心問題是狀態的遷移,因爲在對象存在很多狀態情況下,各個狀態之間跳轉和遷移過程都是及其複雜的。在狀態模式中,狀態改變是由對象的內部條件決定,外界只需關心其接口,不必關心其狀態對象的創建和轉化。

策略模式:
策略模式的好處在於你可以動態的改變對象的策略行爲。策略模式裏,採取何種策略由外部條件決定,也就是說使用什麼策略由我們來提供,而策略的具體實現類實現對應算法。比如一種商品,我們可以有很多降價和提價策略,我們只需要定義好各種策略的規則,然後讓商品去執行就行了。


更多模式: 一天一個設計模式—分類與六大原則

更多源碼: https://github.com/oDevilo/Java-Base

發佈了92 篇原創文章 · 獲贊 136 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章