定义
策略模式定义了一系列算法,并将每一个算法封装起来,而且使它们可以相互替换。策略模式让算法独立于使用它的客户端独立变化。
使用场景
当我们处理问题时,如果需要根据不同的条件来选择不同的解决方案,最简单的方式就是用if-else,但每增加一种方案,就要修改原来的代码,而且容易出现错误,最终导致代码臃肿、耦合性高、难维护等,同时也违背了开放封闭原则,所以就需要使用策略模式来解决这样的问题。
实现
比如现在我们要做一个图片加载的工具,需要提供给用户设置缓存的方法。来,先看第一个版本:
首先定义两个缓存类:内存缓存、磁盘缓存:
public class MemoryCache {
public void cache() {
Log.e("CacheStrategy", "MemoryCache");
}
}
public class DiskCache {
public void cache() {
Log.e("CacheStrategy", "DiskCache");
}
}
然后设置缓存的方法写在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类,来增加对应的缓存类对象和条件逻辑,这很明显违背了开放封闭原则,增加了维护成本和出现错误的概率。
基于这些问题,所以就有了第二个版本:
先定义一个缓存策略接口:
public interface CacheStrategy {
void cache();
}
然后修改之前的内存缓存类、磁盘缓存类,实现这个共工接口:
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();
}
}
}
这样,当需要增加新的缓存策略时就不用修改ImageLoader类了,只需要通过CacheStrategy接口来扩展新的缓存策略,而不会影响原来的业务逻辑。设置缓存时可按如下方式:
public class Client {
public static void test(){
ImageLoader imageLoader = new ImageLoader();
imageLoader.setCache(new DiskCache());
}
}
最后看一下log:
小结
可以看到策略模式主要用来分离算法,同一个抽象行为可以有不同的具体实现策略,使代码的结构清晰,将低了耦合。符合开放封闭原则,扩展性好。当然,随着具体策略的增多相应的类也会增加。
网友评论