設計模式之策略模式

1、核心

策略模式定義了一系列的算法,並將每一個算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨立於使用它的客戶而獨立變化。

2、應用場景

  1. JAVASE中GUI編程中,佈局管理
  2. Spring框架中,Resource接口,資源訪問策略
  3. javax.servlet.http.HttpServlet#service()

3、策略模式角色

—抽象策略角色: 策略類,通常由一個接口或者抽象類實現。
—具體策略角色:包裝了相關的算法和行爲。
—環境角色:持有一個策略類的引用,最終給客戶端調用。
策略模式——結構圖
Context(應用場景):
1、需要使用ConcreteStrategy提供的算法。
2、 內部維護一個Strategy的實例。
3、 負責動態設置運行時Strategy具體的實現算法。
4、負責跟Strategy之間的交互和數據傳遞。
Strategy(抽象策略類):定義了一個公共接口,各種不同的算法以不同的方式實現這個接口,Context使用這個接口調用不同的算法,一般使用接口或抽象類實現。
ConcreteStrategy(具體策略類): 實現了Strategy定義的接口,提供具體的算法實現。

4、代碼示例

問題:商場不同打折策略
策略模式——類圖

/**
 * 算法接口
 * @author ly1
 *
 */
public interface Strategy {
    double getPrice(double standardPrice);
}
/**
 * 新客戶小批量購買策略
 * @author ly1
 *
 */
public class NewCustomerFewStrategy implements Strategy{

    @Override
    public double getPrice(double standardPrice) {
        return standardPrice;
    }

}
/**
 * 新客戶大批量購買策略
 * @author ly1
 *
 */
public class NewCustomerManyStrategy implements Strategy{

    @Override
    public double getPrice(double standardPrice) {
        return standardPrice * 0.9;
    }

}
/**
 * 老客戶小批量購買策略
 * @author ly1
 *
 */
public class OldCustomerFewStrategy implements Strategy{

    @Override
    public double getPrice(double standardPrice) {
        return standardPrice * 0.85;
    }

}
/**
 * 老客戶大批量購買策略
 * @author ly1
 *
 */
public class OldCustomerManyStrategy implements Strategy{

    @Override
    public double getPrice(double standardPrice) {
        return standardPrice * 0.8;
    }

}
/**
 * 負責與具體算法交互,實現了客戶端與算法的完全分離
 * @author ly1
 *
 */
public class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        super();
        this.strategy = strategy;
    }

    public void printPrice(double standardPrice){
        System.out.println("原價:" + standardPrice);
        System.out.println("現價:" + strategy.getPrice(standardPrice));
    }
}
/**
 * 客戶端調用
 * @author ly1
 *
 */
public class Client {
    public static void main(String[] args) {
        Context context = new Context(new OldCustomerFewStrategy());

        context.printPrice(1000);
    }
}

結果:
原價:1000.0
現價:850.0

5、優點

  1. 策略模式提供了管理相關的算法族的辦法。策略類的等級結構定義了一個算法或行爲族。恰當使用繼承可以把公共的代碼轉移到父類裏面,從而避免重複的代碼。
  2. 策略模式提供了可以替換繼承關係的辦法。繼承可以處理多種算法或行爲。如果不是用策略模式,那麼使用算法或行爲的環境類就可能會有一些子類,每一個子類提供一個不同的算法或行爲。但是,這樣一來算法或行爲的使用者就和算法或行爲本身混在一起。決定使用哪一種算法或採取哪一種行爲的邏輯就和算法或行爲的邏輯混合在一起,從而不可能再獨立演化。繼承使得動態改變算法或行爲變得不可能。
  3. 使用策略模式可以避免使用多重條件轉移語句。多重轉移語句不易維護,它把採取哪一種算法或採取哪一種行爲的邏輯與算法或行爲的邏輯混合在一起,統統列在一個多重轉移語句裏面,比使用繼承的辦法還要原始和落後。

6、缺點

  1. 客戶端必須知道所有的策略類,並自行決定使用哪一個策略類。這就意味着客戶端必須理解這些算法的區別,以便適時選擇恰當的算法類。換言之,策略模式只適用於客戶端知道所有的算法或行爲的情況。
  2. 策略模式造成很多的策略類,每個具體策略類都會產生一個新類。有時候可以通過把依賴於環境的狀態保存到客戶端裏面,而將策略類設計成可共享的,這樣策略類實例可以被不同客戶端使用。換言之,可以使用享元模式來減少對象的數量。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章