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

2016-02-19 10:03 10 1 收藏

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

【 tulaoshi.com - 编程语言 】

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

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

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

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();
         }
     }

}

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

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

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

来源:http://www.tulaoshi.com/n/20160219/1593176.html

延伸阅读
一、功能 保证一个类仅有一个实例。 三、优缺点 Singleton模式是做为"全局变量"的替代品出现的。所以它具有全局变量的特点:全局可见、贯穿应用程序的整个生命期,它也具有全局变量不具备的性质:同类型的对象实例只可能有一个。 四、实现 教科书上的Singleton定义如下: class Singleton { public: static Si...
今年十一国庆节,我呆在家里美美的享受了一下家的温馨。首先让我来介绍一下我的家庭成员:妻子(Wife)女儿(Daughter)我(Me)我们都是家庭(Family)的一分子,我们是以家庭对外的。就象我们国家对外是以中国,外国人都称我们是中国人,但在中国这个大家庭内部,包括了汉、回、蒙、。。。等56个民族一样。可见对外我们是要以统一的身份,或...
标签: PHP
上文:《PHP设计模式介绍》第六章 伪对象模式 《PHP设计模式介绍》第七章 策略模式 在编写面向对象的代码的时,有些时候你需要一个能够自己根据不同的条件来引入不同的操作对象实例。例如,一个菜单功能能够根据用户的皮肤首选项来决定是否采用水平的还是垂直的排列形式,或者一个计费系统可以自行根据用户的收货地址来决定税率。 一般...
标签: Java JAVA基础
一、引子 前几天陪朋友去装机店攒了一台电脑,看着装机工在那里熟练的装配着机器,不禁想起来了培训时讲到的建造模式。作为装机工,他们不用管你用的CPU是Intel还是AMD,也不管你的显卡是2000千大元还是白送的,都能挛宄淖芭湓谝黄稹惶≒C就诞生了!当然对于客户来说,你也不知道太多关于PC组装的细节。这和建...
从事Android开发,免不了会在应用里嵌入一些广告SDK,在嵌入了众多SDK后,发现几乎每个要求在AndroidManifest.xml申明Activity的广告SDK都会要求加上注明这么一句属性: 代码如下: android:configChanges="orientation|keyboard|keyboardHidden" 通过查阅Android API可以得知android:onConfigurationChanged实际对应的是Activity里...

经验教程

31

收藏

17
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部