策略模式定义:
以编码角度来看,就是将算法处理逻辑单独封装成一个策略,根据问题类型的不同,选择对应的策略来处理,所以说策略模式中的策略也就是算法逻辑,当你将算法逻辑封装成方法(函数)或是具体的实现类的时候,这个方法或类就可以说是一个策略。那么具体怎么使用该模式,下面将以Android开发中属性动画的插值器的实现方式作为示例,来学习策略模式。
代码示例分析(Android属性动画插值器Interpolator)
public interface TimeInterpolator {
float getInterpolation(float input);
}
//插值器接口,没有变量和方法
public interface Interpolator extends TimeInterpolator {
}
//BaseInterpolator实现Interpolator接口
abstract public class BaseInterpolator implements Interpolator {
private @Config int mChangingConfiguration;
public @Config int getChangingConfiguration() {
return mChangingConfiguration;
}
void setChangingConfiguration(@Config int changingConfiguration) {
mChangingConfiguration = changingConfiguration;
}
}
//接着就是我们能常用的抽象类的具体实现类,以LinearInterpolator为例:
//看一下作用于动画匀速运动的LinearInterpolator插值器的源码:
@HasNativeInterpolator
public class LinearInterpolator extends BaseInterpolator implements NativeInterpolator {
public LinearInterpolator() {
}
public LinearInterpolator(Context context, AttributeSet attrs) {
}
public float getInterpolation(float input) {
return input;
}
/** @hide */
@Override
public long createNativeInterpolator() {
return NativeInterpolatorFactory.createLinearInterpolator();
}
}
//内置的插值器有多种,比如:DecelerateInterpolator(减速插值器)、CycleInterpolator(周期运动插值器)等,
//属性动画的常规用法如下:
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(textView,"translationX", 0,100);
objectAnimator.setDuration(5000);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.start();
这里的objectAnimator.setInterpolator(new LinearInterpolator())方法,将LinearInterpolator实例复制到objectAnimator实例中的 mInterpolator成员变量,而该成员变量是TimeInterpolator类型的,objectAnimator最终会在animateValue中调用getInterpolation方法。
void animateValue(float fraction) {
fraction = mInterpolator.getInterpolation(fraction);
mCurrentFraction = fraction;
int numValues = mValues.length;
for (int i = 0; i < numValues; ++i) {
mValues[i].calculateValue(fraction);
}
if (mUpdateListeners != null) {
int numListeners = mUpdateListeners.size();
for (int i = 0; i < numListeners; ++i) {
mUpdateListeners.get(i).onAnimationUpdate(this);
}
}
}
根据多态性,这里的getInterpolation()方法被调用时,会执行的是在对ObjectAnimator实例设置插值器时的LinearInterpolator实例的getInterpolation()方法逻辑代码,这样就可以实现给objectAnimator设置不同的插值器时,执行不同的算法逻辑,达到不同的动画效果。并且可以仿照LinearInterpolator实现自定义插值器,大概思路就是:
创建CustomInterpolator继承自BaseInterpolator 或是实现Interpolator接口
public class CustomInterpolator extends BaseInterpolator implements NativeInterpolator{
//这里主要重写该方法
public float getInterpolation(float input) {
//实现自定义算法逻辑
return input;
}
}
//通过该objectAnimator.setInterpolator(new CustomInterpolator());
//方法将自定义插值器CustomInterpolator设置到属性动画实例即可
自定义Interpolator实现方法也比较简单,到了这里就可以发现通过这种方法就可以对Interpolator进行扩展,对原有代码没有任何影响,便于程序的扩展。
总结
所以策略模式的整体思路如图:
具体代码实现思路:
//定义策略接口
public interface Strategy {
public int method();
}
//创建策略接口实现类(这里模拟实现两种不同策略)
public class StrategyImpl1 Strategy implements Strategy {
@Override
public int method() {
//这里实现不同的算法
return xxx;
}
}
public class StrategyImpl2 Strategy implements Strategy {
@Override
public int method() {
//这里实现不同的算法
return xxx;
}
}
//需要使用不同策略的实体类(使用策略者)
public class PolicyUser {
private Strategy strategy;
public PolicyUser(Strategy strategy){
this.strategy = strategy;
}
public int method(){
return strategy.method();
}
}
//具体策略使用者调用策略的一般情形
public class StrategyDemo {
public static void main(String[] args) {
PolicyUser policyUser = new PolicyUser(new StrategyImpl1());
policyUser.method();//这里执行的会是StrategyImpl1类中的method()方法
PolicyUser policyUser = new PolicyUser(new StrategyImpl2());
policyUser.method();//这里执行的会是StrategyImpl2类中的method()方法
}
}
即是将逻辑处理方法封装成方法,创建策略接口并定义策略方法,接着可以创建具体的实现类,又或是创建抽象类(因为这样在一个策略分为多个算法时更方便于后续扩展)。
在这里的策略一般做法都是将其封装成类(这样做比分装成方法更便于扩展),所以每当需要增加一种策略时就需定义一个策略类,所以其缺点也就是当有大量策略时会需要大量的策略算法实现类。所以应根据实际情况使用相应的策略,比如只需一两个条件判断就可以选择不同策略应对不同情况的时候,并且无需过多考虑扩展性的时候,就不必强行使用策略模式了。