策略模式/Strategy

策略模式/Strategy

意圖/適用場景:

策略模式是針對一組算法,將每一個算法封裝到具有共同接口的獨立類中,從而使得它們可以互換。這樣做的好處是,客戶端可以以插件的方式更換算法。

電子商務網站的購物車系統是一個策略模式非常適用的場景:比如,在優惠方式上,某一類商品是每件優惠一元,另一類商品是折扣5%,還有一類商品也是打折,但折扣幅度是10%。所以需要應用不同的優惠算法來計算最終的價格。

在這個系統中,可以想象到會有一個計算者角色(與本模式中的Context相同功能),它負責計算價格。但如果把所有的算法都放在它裏面來實現的話,會比較混亂。如果應用策略模式的話,就可以把行爲和上下文環境分開。上下文類(計算者)中負責維持和查詢行爲類,各種算法則在具體策略類中提供。由於算法和環境獨立開來,算法的增減、修改都不會影響到上下文和客戶端。這也爲上下文類減輕了負擔。

UML:

策略模式/Strategy

參與者:

  1. 上下文角色(Context):持有一個Strategy類的引用。
  2. 抽象策略角色(Strategy):抽象角色,通常是一個接口或者抽象類。定義出所有的具體策略類的公共接口。如果具體策略類有共同的行爲,可以把Strategy定義爲抽象類,並實現這些公共的行爲;否則最好定義爲接口。
  3. 具體策略(ConcreteStrategy):包裝了相關的算法或行爲。

要點:

在下面的情況下應當考慮使用策略模式:

  1. 系統需要動態地在多種算法中選擇一種;
  2. 算法很多,如果由一個角色來處理的話,邏輯會非常混亂;
  3. 算法不可讓客戶端知道。

策略模式的最大優點在於把算法分門別類,由不同的實體類來維護,實現了算法本身與算法的使用者之間的弱耦合。而且把一個攪在一起的大算法分而治之,避免了大量使用條件而造成的混亂。

應用實例:

排序策略系統,參見《Java與模式》本章。

策略模式/Strategy

相關模式:

以下模式在結構上與策略模式相似,它們的區別多半在於用意不同,適用的場景是不同的。

  1. 策略模式:強調的是算法的分治與選擇。
  2. 建造模式:它的核心功能是以一步一步的方式創建一個產品,把各個零件分別製造並組裝起來,最後形成一個產品。
  3. 適配模式:它的用意在於把不同接口的對象“轉接”成客戶端所需要的接口。
  4. 裝飾模式:它的用意在於在不改變接口的情況下,增強一個對象的功能。

示例代碼:

   [java]
// Source code from file:  ConcreteStrategyA.java

package designPatterns.Strategy;

public class ConcreteStrategyA implements Strategy {
public void strategy() {
System.out.println("ConcreteStrategyA.strategy()");
}
}

// Source code from file:  ConcreteStrategyB.java

package designPatterns.Strategy;

public class ConcreteStrategyB implements Strategy {
public void strategy() {
System.out.println("ConcreteStrategyA.strategy()");
}
}

// Source code from file:  Context.java

package designPatterns.Strategy;

public class Context {
private Strategy strategy;

public void strategy(char type) {
if ('A' == type)
strategy = new ConcreteStrategyA();
else if ('B' == type)
strategy = new ConcreteStrategyB();
strategy.strategy();
}
}

// Source code from file:  Strategy.java

package designPatterns.Strategy;

public interface Strategy {
public void strategy();
}

// Source code from file:  User.java

package designPatterns.Strategy;

public class User {
public static void main(String[] args) {
Context ctxt = new Context();
ctxt.strategy('A');
ctxt.strategy('B');
}
}
[/java]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章