簡介
摘自百度百科
“對象有某種行爲,但是在不同場景中,該行爲有不同的實現”,這不禁使我想起了某盤的Vip用戶和普通用戶下載速度的差別,今天我們就來借用某盤的例子說一說策略模式。
代碼實例
首先,我們將用戶分爲三種:普通用戶(Comm)、會員(Vip)、超級會員(SVip)。他們都可以下載文件,即都有下載方法(download)
於是我們新建一個接口,表示下載功能
public interface IDownload {
void download();
}
普通用戶、會員、超級會員都實現了下載方法
public class Comm implements IDownload {
@Override
public void download() {
System.out.println("普通用戶,下載速度3KB/S");
}
}
public class Vip implements IDownload {
@Override
public void download() {
System.out.println("會員:想不到吧,下載速度還是3KB/S");
}
}
public class SVip implements IDownload {
@Override
public void download() {
System.out.println("超級會員:下載速度2M/S");
}
}
還有一個客戶端,也就是某盤,來調用下載方法
public class MouPan {
private IDownload iDownload;
public MouPan(IDownload iDownload) {
this.iDownload = iDownload;
}
public void downloadFiles() {
this.iDownload.download();
}
}
這個時候,超級會員、會員和普通用戶都要下載某國的一部影片。
public class Test {
public static void main(String[] args) {
MouPan mouPan;
System.out.print("普通用戶下載影片-->");
mouPan = new MouPan(new Comm());
mouPan.downloadFiles();
System.out.print("會員下載影片-->");
mouPan = new MouPan(new Vip());
mouPan.downloadFiles();
System.out.print("超級會員下載影片-->");
mouPan = new MouPan(new SVip());
mouPan.downloadFiles();
}
}
他們都調用的是下載方法,可是因爲身份不同卻要遭受不同的待遇:
普通用戶下載影片-->普通用戶,下載速度3KB/S
會員下載影片-->會員:想不到吧,下載速度還是3KB/S
超級會員下載影片-->超級會員:下載速度2M/S
優缺點
以上就是策略模式,使用策略模式主要有以下幾點好處:
- 避免多重判斷:想像一下,如果上面的代碼不使用策略模式的話們就有很多 if else判斷,策略模式使代碼思路更加清晰,方便維護。
- 擴展性好:還是上面的例子,假如某一天某盤想出一個“SSVip”,就只用寫一個SSVip的類,來繼承IDownload就行了
當然,策略模式也有一些缺點:
- 客戶端必須知道所有的策略類,並自行決定使用哪一個策略類。
- 策略模式會出現很多的策略類。
適用場景
場景1:
現在我想實現一個圖片上傳功能,可能用到阿里雲的對象存儲,也可能用到七牛雲的。這個時候就可以使用策略模式。
- 定義一個接口,封裝關於圖片的上傳功能。
- 定義一個類實現該接口,使用阿里雲對象存儲來實現圖片上傳功能。
- 定義一個類實現該接口,使用七牛雲來實現圖片上傳功能。
這個時候,我們想要切換服務的時候,只用切換一下實現類就行了
場景2:
就像上面某盤的例子,當不同角色都要執行這一個操作,但是不同角色有不同實現的時候,可以使用策略模式,可以減少if else判斷,例如商品結賬的時候,會員和非會員的結算方式不同。
枚舉策略
以上不同用戶下載速度不同的例子,還可以使用枚舉策略來實現
public enum MouPanUser {
COMM() {
@Override
public void download() {
System.out.println("普通用戶,下載速度3KB/S");
}
},
SVIP() {
@Override
public void download() {
System.out.println("超級會員:下載速度2M/S");
}
},
VIP() {
@Override
public void download() {
System.out.println("會員:想不到吧,下載速度還是3KB/S");
}
};
public abstract void download();
}
這個時候,對於不同用戶來說,我們可以專門新建一個下載器來實現下載功能
public class Downloader {
public void download(MouPanUser user) {
user.download();
}
}
這樣就可以很方便的根據不同用戶,執行不同的下載方法:
public class Test {
public static void main(String[] args) {
Downloader downloader = new Downloader();
System.out.print("普通用戶下載影片-->");
downloader.download(MouPanUser.COMM);
System.out.print("會員下載影片-->");
downloader.download(MouPanUser.VIP);
System.out.print("超級會員下載影片-->");
downloader.download(MouPanUser.SVIP);
}
}