简介
摘自百度百科
“对象有某种行为,但是在不同场景中,该行为有不同的实现”,这不禁使我想起了某盘的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);
}
}