设计模式之策略模式 - strategy

典型的案例

在构造PriorityQueue优先级队列时,使用

public PriorityQueue(int initialCapacity, Comparator<? super E> comparator) {
}

给优先级队列指定一个元素的排序规则的比较器.

例如可以实现2个比较器, 一个是按照元素的某一个属性值进行正向排序, 另一个是按照元素的某一个属性值进行反向排序.
当以后需要新的排序规则时, 只需要实现Comparator接口里的方法, 并设置给PriorityQueue就可以了, 之前的代码都不需要修改.

这样就做到了对扩展开发, 对修改封闭.
这就是策略模式.

在android 属性动画中的使用

使用属性动画时, 有一个插值器的概念, 用于根据时间流逝的百分比, 计算出属性值要改变的百分比.

mUrlHintAnimationIn = ObjectAnimator.ofFloat(mUrlHit,
    "translationY", availableViewportHeight, availableViewportHeight - mUrlHit.getMeasuredHeight());
mUrlHintAnimationIn.setInterpolator(new DecelerateInterpolator());
mUrlHintAnimationIn.start();

通过给属性动画指定一个插值器, 实现不同动画速度的快慢变化.

public interface TimeInterpolator {

    float getInterpolation(float input);
}

默认提供了这么几种实现

LinearInterpolator, DecelerateInterpolator, AccelerateInterpolator, AccelerateDecelerateInterpolator

使用策略模式的优点是, 当需要新的插值器时, 只需要MyTimeInterpolator implements TimeInterpolator, 然后set到animation中去就可以了. 原有的插值器的代码都不需要修改.
这样就做到了对修改封闭, 对扩展开放的原则.

对Volley的灵活性修改

volley使用一个PriorityBlockingQueue存储外界的网络请求对象, 它在构造优先级队列的时候并没有指定比较器, 这些对象的排序是按照FIFO先进先出的方式存储.
通过在构造PriorityBlockingQueue的时候指定一个比较器, 可以对网络请求对象进行正向或反向的排序. 在滑动listview时, 可以让后添加进来的网络请求先被执行, 这样用户可见区的item最快得到展示, 能够提升一定的用户体验.

public class RequestQueue {
    /** The cache triage queue. */
    private final PriorityBlockingQueue<Request<?>> mCacheQueue =
        new PriorityBlockingQueue<Request<?>>();

    /** The queue of requests that are actually going out to the network. */
    private final PriorityBlockingQueue<Request<?>> mNetworkQueue =
        new PriorityBlockingQueue<Request<?>>();

}

用这个构造方法, 给PriorityBlockingQueue提供一个比较器.

    public PriorityBlockingQueue(int initialCapacity,
                                 Comparator<? super E> comparator)
public class PriorityQueue<E> extends AbstractQueue<E> implements Serializable {
    private Comparator<? super E> comparator;

    public PriorityQueue() {
        this(DEFAULT_CAPACITY);
    }

    public PriorityQueue(int initialCapacity, Comparator<? super E> comparator) {
        if (initialCapacity < 1) {
            throw new IllegalArgumentException("initialCapacity < 1: " + initialCapacity);
        }
        elements = newElementArray(initialCapacity);
        this.comparator = comparator;
    }

    private int compare(E o1, E o2) {
        if (comparator != null) {
            return comparator.compare(o1, o2);
        }
        return ((Comparable<? super E>) o1).compareTo(o2);
    }
}

如果比较器不为空的话, 调用比较器的compare()方法对元素进行排序, 如果比较器为空的话, 那就直接调用对象的compareTo()方法, 对元素进行排序.

------DONE.-----------

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 在程序设计中,我们也常常遇到这样的情况,要实现某一个功能有多种方案可以选择。比如一个压缩文件的程序,既可以选择 z...
    风铭阅读 1,469评论 0 0
  • 策略模式,是我们接触到的第一个设计模式,也是较容易理解的一个模式。我们可以给它下一个定义:** 定义了算法族,分别...
    六尺帐篷阅读 736评论 0 8
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,923评论 18 139
  • 今天学习了抽象类和拷贝构造函数 class 类名{virtual 类型 函数名(参数表)=0;...} 抽象类掌握...
    老翟_4856阅读 184评论 0 0
  • 798和花舞森林 人们都说798是艺术景区中必看的景点,正好去的时候赶上了花舞森林展览,就顺便也看了。聊聊感受吧,...
    cobs阅读 266评论 0 1