策略模式定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。在博文Android动画中介绍使用各种插值算法就属于策略模式的运用。
意 图:
定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
适 用环 境:
- 许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
- 需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时,可以使用策略模式。
- 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
- 一个类定义了多种行为, 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
类图:
Android 系统中使用策略模式的代码示例:
public interface TimeInterpolator {
/**
* 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);
}
// 插值函数
public interface Interpolator extends TimeInterpolator {
// A new interface, TimeInterpolator, was introduced for the new android.animation
// package. This older Interpolator interface extends TimeInterpolator so that users of
// the new Animator-based animations can use either the old Interpolator implementations or
// new classes that implement TimeInterpolator directly.
}
public abstract class Animation implements Cloneable {
--- ---
// Animation中设置不同策略的插值函数
public void setInterpolator(Interpolator i) {
mInterpolator = i;
}
--- ---
}
通过设置不同的Interpolator 可以实现不同的动画效果,如:
// 加速运动插值器
class AccelerateInterpolator extern Interpolator{
float mFactor = 1.0f;
AccelerateInterpolator(factor){
mFactor = factor;
}
float getInterpolation(float input){
if (mFactor == 1.0f) {
return input * input;
} else {
return (float)Math.pow(input, mDoubleFactor);
}
}
}
// 线性运动插值器
class LinearInterpolator extern Interpolator{
float getInterpolation(float input){
return input;
}
}
在Animation对象中,通过不同的策略设置不同的插值器,可实现不同的动画效果。