策略模式

作者: SheHuan | 来源:发表于2017-04-26 15:40 被阅读83次
定义

策略模式定义了一系列算法,并将每一个算法封装起来,而且使它们可以相互替换。策略模式让算法独立于使用它的客户端独立变化。

使用场景

当我们处理问题时,如果需要根据不同的条件来选择不同的解决方案,最简单的方式就是用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:


小结

可以看到策略模式主要用来分离算法,同一个抽象行为可以有不同的具体实现策略,使代码的结构清晰,将低了耦合。符合开放封闭原则,扩展性好。当然,随着具体策略的增多相应的类也会增加。

相关文章

网友评论

    本文标题:策略模式

    本文链接:https://www.haomeiwen.com/subject/mwrfzttx.html