定義
策略模式定義了一系列算法,并將每一個(gè)算法封裝起來所灸,而且使它們可以相互替換搞挣。策略模式讓算法獨(dú)立于使用它的客戶端獨(dú)立變化。
使用場景
當(dāng)我們處理問題時(shí)磕蛇,如果需要根據(jù)不同的條件來選擇不同的解決方案景描,最簡單的方式就是用if-else,但每增加一種方案秀撇,就要修改原來的代碼超棺,而且容易出現(xiàn)錯(cuò)誤,最終導(dǎo)致代碼臃腫呵燕、耦合性高棠绘、難維護(hù)等,同時(shí)也違背了開放封閉原則再扭,所以就需要使用策略模式來解決這樣的問題氧苍。
實(shí)現(xiàn)
比如現(xiàn)在我們要做一個(gè)圖片加載的工具,需要提供給用戶設(shè)置緩存的方法泛范。來让虐,先看第一個(gè)版本:
首先定義兩個(gè)緩存類:內(nèi)存緩存、磁盤緩存:
public class MemoryCache {
public void cache() {
Log.e("CacheStrategy", "MemoryCache");
}
}
public class DiskCache {
public void cache() {
Log.e("CacheStrategy", "DiskCache");
}
}
然后設(shè)置緩存的方法寫在ImageLoader類中:
public class ImageLoader {
private MemoryCache memoryCache = new MemoryCache();
private DiskCache diskCache = new DiskCache();
public void setCache(int type) {
if (type == 1) {
memoryCache.cache();
} else if (type == 2) {
diskCache.cache();
}
}
}
看起來還是蠻簡單的罢荡,但是問題也不少赡突,每增加一種緩存策略,我們就需要修改ImageLoader類区赵,來增加對(duì)應(yīng)的緩存類對(duì)象和條件邏輯惭缰,這很明顯違背了開放封閉原則,增加了維護(hù)成本和出現(xiàn)錯(cuò)誤的概率笼才。
基于這些問題漱受,所以就有了第二個(gè)版本:
先定義一個(gè)緩存策略接口:
public interface CacheStrategy {
void cache();
}
然后修改之前的內(nèi)存緩存類、磁盤緩存類患整,實(shí)現(xiàn)這個(gè)共工接口:
public class MemoryCache implements CacheStrategy{
@Override
public void cache() {
Log.e("CacheStrategy", "MemoryCache");
}
}
public class DiskCache implements CacheStrategy {
@Override
public void cache() {
Log.e("CacheStrategy", "DiskCache");
}
}
最后重寫ImageLoader類:
public class ImageLoader {
public void setCache(CacheStrategy cacheStrategy) {
if (cacheStrategy != null) {
cacheStrategy.cache();
}
}
}
這樣拜效,當(dāng)需要增加新的緩存策略時(shí)就不用修改ImageLoader類了喷众,只需要通過CacheStrategy接口來擴(kuò)展新的緩存策略,而不會(huì)影響原來的業(yè)務(wù)邏輯紧憾。設(shè)置緩存時(shí)可按如下方式:
public class Client {
public static void test(){
ImageLoader imageLoader = new ImageLoader();
imageLoader.setCache(new DiskCache());
}
}
最后看一下log:
小結(jié)
可以看到策略模式主要用來分離算法到千,同一個(gè)抽象行為可以有不同的具體實(shí)現(xiàn)策略,使代碼的結(jié)構(gòu)清晰赴穗,將低了耦合憔四。符合開放封閉原則,擴(kuò)展性好般眉。當(dāng)然了赵,隨著具體策略的增多相應(yīng)的類也會(huì)增加。