一玄柠、定義
策略模式:官方一點(diǎn)的定義就是定義好一組算法簇,將每個算法(變化)都封裝成一個類敏弃,并且使他們可以互相替換。
直白一點(diǎn)就是定義好一些會變化的行為接口蹬癌,然后將他們的不同實(shí)現(xiàn)封裝成類权她,最后 set 進(jìn)使用這些行為的客戶里面,讓客戶可以變換使用這些功能逝薪。
二、使用場景
- 多個子類只有在算法或行為上稍有不同蝴罪,不需要將子類和特定的行為捆綁在一起董济,還能自由切換算法的場景。
- 需要屏蔽算法規(guī)則的場景要门。
- Android 中虏肾,設(shè)計(jì)圖片加載框架的時候廓啊,可以預(yù)先實(shí)現(xiàn)好若干種加載策略,使用策略模式來選擇加載策略封豪。
三谴轮、栗子
策略的抽象及其實(shí)現(xiàn):
/**
* 抽象策略角色
* 通常為接口,定義每個策略或算法必須具有的方法和屬性吹埠。
*/
public interface Strategy {
void doMyStrategy();
}
/**
* 具體策略角色
* 實(shí)現(xiàn)抽象策略中的操作第步,該類含有具體的算法。
*/
public class ConcreteStrategy1 implements Strategy{
@Override
public void doMyStrategy() {
System.out.println("策略一算法");
}
}
public class ConcreteStrategy2 implements Strategy{
@Override
public void doMyStrategy() {
System.out.println("策略二算法");
}
}
上下文角色:
/**
* Context封裝角色:它也叫做上下文角色
* 起承上啟下封裝作用缘琅,屏蔽高層模塊對策略粘都、算法的直接訪問,封裝可能存在的變化刷袍。
*/
public class Context {
private Strategy strategy;
public Context(Strategy s) {
this.strategy = s;
}
public void setStrategy(Strategy s) {
this.strategy = s;
}
public void doThings() {
strategy.doMyStrategy();
}
}
場景類:
public class Client {
public static void main(String[] args) {
Strategy s1 = new ConcreteStrategy1();
Strategy s2 = new ConcreteStrategy2();
//執(zhí)行策略一算法
Context context = new Context(s1);
context.doThings();
//替換算法
context.setStrategy(s2);
context.doThings();
}
}
結(jié)果:
策略一算法
策略二算法
四翩隧、策略模式優(yōu)點(diǎn)
- 封裝性好,使用簡單呻纹。
- 將抽出來變化的部分封裝成接口實(shí)現(xiàn)類堆生,算法可以自由切換,避免多重條件判斷雷酪。
- 擴(kuò)展性良好顽频。擴(kuò)展只需要增加策略的具體實(shí)現(xiàn)類,替換策略太闺。符合開閉原則糯景。
五、策略模式缺點(diǎn)
- 隨著策略的增加省骂,策略類數(shù)量增多蟀淮。
- 所有的策略類都需要對外暴露,與迪米特原則相違背钞澳。