基于Android设计模式之--SDK源码之策略模式的详解

xmbovey

xmbovey

2016-02-19 10:03

get新技能是需要付出行动的,即使看得再多也还是要动手试一试。今天图老师小编跟大家分享的是基于Android设计模式之--SDK源码之策略模式的详解,一起来学习了解下吧!

策略模式其实特别简单(听到这句话,大家是不是心里一下子放松了?)。
比如排序,官方告诉大家我这里有一个排序的接口ISort的sort()方法,然后民间各尽其能,实现这个排序的方法:冒泡,快速,堆等等。
这些方法就是“不同的策略”。
然后,某个模块下,需要一个排序方法,但是暂时不能指定具体的sort方法(出于扩展的考虑),就需要使用ISort接口了。
最后,具体什么场景下,传入什么具体的sort方法,实现灵活的排序。
这就是策略模式!
下面,我们分析Android中的动画是如何使用策略模式的。

1. 意图
定义一系列的算法,把它们一个个封装起来,并且使它们可互相替换。
策略模式使得算法可独立于使用它的客户而变化。

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

2. 结构图和代码
Animation不同动画的实现,主要是依靠Interpolator的不同实现而变。

定义接口Interpolator:
代码如下:

package android.animation;

/**
 * A time interpolator defines the rate of change of an animation. This allows animations
 * to have non-linear motion, such as acceleration and deceleration.
 */
public interface Interpolator {

    /**
     * Maps a value representing the elapsed fraction of an animation to a value that represents
     * the interpolated fraction. This interpolated value is then multiplied by the change in
     * value of an animation to derive the animated value at the current elapsed animation time.
     *
     * @param input A value between 0 and 1.0 indicating our current point
     *        in the animation where 0 represents the start and 1.0 represents
     *        the end
     * @return The interpolation value. This value can be more than 1.0 for
     *         interpolators which overshoot their targets, or less than 0 for
     *         interpolators that undershoot their targets.
     */
    float getInterpolation(float input);

我们以AccelerateInterpolator为例,实现具体的策略,代码如下:
代码如下:

package android.view.animation;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;

/**
 * An interpolator where the rate of change starts out slowly and
 * and then accelerates.
 *
 */
public class AccelerateInterpolator implements Interpolator {
    private final float mFactor;
    private final double mDoubleFactor;

    public AccelerateInterpolator() {
        mFactor = 1.0f;
        mDoubleFactor = 2.0;
    }

    /**
     * Constructor
     *
     * @param factor Degree to which the animation should be eased. Seting
     *        factor to 1.0f produces a y=x^2 parabola. Increasing factor above
     *        1.0f  exaggerates the ease-in effect (i.e., it starts even
     *        slower and ends evens faster)
     */
    public AccelerateInterpolator(float factor) {
        mFactor = factor;
        mDoubleFactor = 2 * mFactor;
    }

    public AccelerateInterpolator(Context context, AttributeSet attrs) {
        TypedArray a =
            context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AccelerateInterpolator);

        mFactor = a.getFloat(com.android.internal.R.styleable.AccelerateInterpolator_factor, 1.0f);
        mDoubleFactor = 2 * mFactor;

        a.recycle();
    }

    public float getInterpolation(float input) {
        if (mFactor == 1.0f) {
            return input * input;
        } else {
            return (float)Math.pow(input, mDoubleFactor);
        }
    }
}

其他的Interpolator实现在此不列举了。
如何在Animation模块实现不同的动画呢?
在这里我想提一个应用很广的概念:依赖注入。
在Animation模块里实现不同的动画,就是需要我们把各个Interpolator以父类或者接口的形式注入进去。
注入的方法一般是构造函数,set方法,注释等等。
我们看看animation类是怎么做的:
代码如下:

public abstract class Animation implements Cloneable {
    Interpolator mInterpolator;
    // 通过set方法注入  
    public void setInterpolator(Interpolator i) {
         mInterpolator = i;
     }

    public boolean getTransformation(long currentTime, Transformation outTransformation) {
        // ... ...
        // 具体调用
        final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime);
        applyTransformation(interpolatedTime, outTransformation);
       // ... ...
    }

     // 缺省实现,是个小技巧,顺便提下,这个不是重点
     protected void ensureInterpolator() {
         if (mInterpolator == null) {
             mInterpolator = new AccelerateDecelerateInterpolator();
         }
     }

}

  策略模式其实就是多态的一个淋漓精致的体现。

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)

3. 效果
(1).行为型模式
(2).消除了一些if...else...的条件语句
(3).客户可以对实现进行选择,但是客户必须要了解这个不同策略的实现(这句话好像是废话,总而言之,客户需要学习成本)
(4).代码注释中提到了缺省实现,可以让客户不了解策略,也能实现默认的策略
(5).注入的方式有多种:构造函数,set方法,注释。配置解析等等

展开更多 50%)
分享

猜你喜欢

基于Android设计模式之--SDK源码之策略模式的详解

编程语言 网络编程
基于Android设计模式之--SDK源码之策略模式的详解

Android源码学习之组合模式定义及应用

编程语言 网络编程
Android源码学习之组合模式定义及应用

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

Android源码学习之单例模式应用及优点介绍

编程语言 网络编程
Android源码学习之单例模式应用及优点介绍

Android源码学习之工厂方法模式应用及优势介绍

编程语言 网络编程
Android源码学习之工厂方法模式应用及优势介绍

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

Android源码学习之观察者模式应用及优点介绍

编程语言 网络编程
Android源码学习之观察者模式应用及优点介绍

设计模式之State

编程语言 网络编程
设计模式之State

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

解析Android资源文件及他们的读取方法详解

解析Android资源文件及他们的读取方法详解

基于java开发之系统托盘的应用

基于java开发之系统托盘的应用
下拉加载更多内容 ↓