定義
策略模式定義了一系列的算法,并將每一個算法封裝起來,而且使他們之間可以相互替換,策略模式讓算法獨立于使它的客戶獨立而變化
角色
1.環(huán)境(Context)角色
持有一個Strategy的引用2.抽象策略(Strategy)角色
這是一個抽象角色,通常由一個接口或抽象類實現(xiàn)。此角色給出所有的具體策略類所需的接口。3.具體策略(ConcreteStrategy)角色
包裝了相關(guān)的算法或行為。
需求
假設(shè)現(xiàn)在要一個上商店個搞活動。 對所有的高級會員打20%的促銷折扣;對中級會員打10%的促銷折扣;對初級會員沒有折扣。
得知算法
算法一:對初級會員沒有折扣。
算法二:對中級會員提供10%的促銷折扣。
算法三:對高級會員提供20%的促銷折扣。
實現(xiàn)代碼
抽象策略接口:Strategy
interface IStrategy {
public void doSomething();
}
具體策略1
class ConcreteStrategy1 implements IStrategy {
public void doSomething() {
System.out.println("具體策略1");
}
}
具體策略2
class ConcreteStrategy2 implements IStrategy {
public void doSomething() {
System.out.println("具體策略2");
}
}
策略的上下文,具體的執(zhí)行者:Context
class Context {
private IStrategy strategy;
public Context(IStrategy strategy){
this.strategy = strategy;
}
public void execute(){
strategy.doSomething();
}
}
客戶端
public class Client {
public static void main(String[] args){
Context context;
System.out.println("-----執(zhí)行策略1-----");
context = new Context(new ConcreteStrategy1());
context.execute();
System.out.println("-----執(zhí)行策略2-----");
context = new Context(new ConcreteStrategy2());
context.execute();
}
}
重點
策略模式的重心不是如何實現(xiàn)算法,而是如何組織、調(diào)用這些算法,從而讓程序結(jié)構(gòu)更靈活,具有更好的維護性和擴展性。
特點
運行時策略的唯一性
運行期間,策略模式在每一個時刻只能使用一個具體的策略實現(xiàn)對象,雖然可以動態(tài)地在不同的策略實現(xiàn)中切換,但是同時只能使用一個。
平等性
策略模式一個很大的特點就是各個策略算法的平等性。對于一系列具體的策略算法,大家的地位是完全一樣的,正因為這個平等性,才能實現(xiàn)算法之間可以相互替換。所有的策略算法在實現(xiàn)上也是相互獨立的,相互之間是沒有依賴的。
優(yōu)缺點
1.優(yōu)點
策略模式提供了管理相關(guān)的算法族的辦法。策略類的等級結(jié)構(gòu)定義了一個算法或行為族。恰當使用繼承可以把公共的代碼移到父類里面,從而避免代碼重復(fù)。
使用策略模式可以避免使用多重條件(if-else)語句。多重條件語句不易維護,它把采取哪一種算法讓子類實現(xiàn)
2.缺點
客戶端必須知道所有的策略類,并自行決定使用哪一個策略類。這就意味著客戶端必須理解這些算法的區(qū)別,以便適時選擇恰當?shù)乃惴悺Q言之,策略模式只適用于客戶端知道算法或行為的情況。
由于策略模式把每個具體的策略實現(xiàn)都單獨封裝成為類,如果備選的策略很多的話,那么對象的數(shù)目就會很可觀。
注意:和狀態(tài)模式不同的是,策略模式是客戶端自己定義不同策略,而狀態(tài)模式是內(nèi)部封裝得狀態(tài),不同客戶端去設(shè)置具體的狀態(tài)處理。
例子
交通工具的收費:城市乘坐交通工具,打的收費標準、公交收費標準、地鐵收費標準,按照公里來計算價格,普通處理就是各種條件判斷。對于同樣都是收費這個計算,如果將收費方法抽象出來,然后按照不同對象去計算,就會讓代碼顯得沒那么臃腫,而且維護起來也很靈活;
將不同收費方式放到不同的對象中,減少在客戶的判斷計算
只要告訴用的是什么交通工具,然后點收費
方法:
(1)抽象一個收費接口
(2)不同交通工具,實現(xiàn)收費計算
(3)客戶端指明交通工具,然后調(diào)用收費
Android中應(yīng)用
動畫框架
插值器
1.給屬性動畫設(shè)置參數(shù):動畫的作用view、動畫屬性、動畫起始值和終值、執(zhí)行時間、延遲時間等等,這些數(shù)據(jù)
都封裝到ProtorValusHolder中。因為可能是一連串動畫,把這些動畫信息放到動畫執(zhí)行隊列。
而實際動畫是一楨楨數(shù)據(jù)聯(lián)動起來,這里將keyFrame數(shù)據(jù)放到KeyFrameSet(是一個list)。
2.動畫執(zhí)行隊列
線程