前言
定义:
定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
使用场景:
- 针对同一类型问题的多种处理方式,仅仅是具体行为有差别时;
- 需要安全地封装多种同一类型的操作时;
- 出现同一抽象类有多个子类,而又需要使用if-else或者switch-case来选择具体子类时;
UML类图:
实现示例
这里我们以乘坐不同的交通工具计算费用
来举例:
- 乘坐地铁,6公里内(3元),6~12公里(4元),其他都算6元;
- 乘坐公交车,一条线路,上车都是3元;
- 乘坐Taxi,10公里内10元,超出每公里3元;
我们使用策略模式来实现:
- 首先,定义计算价格策略接口,
IStrategy
;
interface IStrategy {
fun calculatePrice(km: Int): Int
}
- 公交车价格计算策略,
BusStrategy
;
class BusStrategy : IStrategy {
override fun calculatePrice(km: Int): Int {
return 3
}
}
- 地铁价格计算策略,
SubwayStrategy
;
class SubwayStrategy : IStrategy {
override fun calculatePrice(km: Int): Int {
if (km <= 6) {
return 3
}
if (km <= 12) {
return 4
}
return 6
}
}
- Taxi价格计算策略,
TaxiStrategy
;
class TaxiStrategy : IStrategy {
override fun calculatePrice(km: Int): Int {
if (km < 10) {
return 10
}
return (km - 10) * 3 + 10
}
}
- 测试类;
object Test {
@JvmStatic
fun main(args: Array<String>) {
//公交车计算
val busStrategy = ContextStrategy(BusStrategy())
println(busStrategy.calculatePrice(10))
//Taxi计算
val taxiStrategy = ContextStrategy(TaxiStrategy()) //只需要替换具体实现,满足里氏替换原则
println(taxiStrategy.calculatePrice(10))
}
}
Android源码中的策略模式
动画Interpolator(差值器)
我们分析下源码:我们常用的LinearInterpolator(线性差值器)
、AccelerateInterpolator(加速差值器)
、DecelerateInterpolator(减速差值器)
继承BaseInterpolator
,BaseInterpolator
实现Interpolator
接口,而Interpolator
又继承于TimeInterpolator
接口,相关源码如下:
public class LinearInterpolator extends BaseInterpolator implements NativeInterpolator {
public LinearInterpolator() {
}
public LinearInterpolator(Context context, AttributeSet attrs) {
}
public float getInterpolation(float input) {
return input;
}
@Override
public long createNativeInterpolator() {
return NativeInterpolatorFactory.createLinearInterpolator();
}
}
abstract public class BaseInterpolator implements Interpolator {
private @Config int mChangingConfiguration;
/**
* @hide
*/
public @Config int getChangingConfiguration() {
return mChangingConfiguration;
}
/**
* @hide
*/
void setChangingConfiguration(@Config int changingConfiguration) {
mChangingConfiguration = changingConfiguration;
}
}
public interface Interpolator extends TimeInterpolator {
package android.animation;
public interface TimeInterpolator {
float getInterpolation(float input);
}
我们在看下ValueAnimator
中设置差值器以及调用getInterpolation方法的源码
:
public class ValueAnimator extends Animator implements AnimationHandler.AnimationFrameCallback {
.....
@Override
public void setInterpolator(TimeInterpolator value) {
if (value != null) {
mInterpolator = value;
} else {
mInterpolator = new LinearInterpolator();
}
}
}
获取差值器的值不断更新动画
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);
}
}
}
....
结合策略模式UML我们来整理下Interpolator
相关的UML图:
是不是就是就是很典型的策略模式
;
总结
策略模式主要用来分离算法,在相同的行为抽象下有不同的具体实现策略。
这个模式很好地演示了开闭原则,也就是定义抽象,注入不同的实现,而从达到很好的可扩展性。
优点:
- 结构清晰明了、使用简单直观;
- 耦合度较低,扩展方便;
- 操作封装彻底,数据更为安全;
缺点:
- 随着策略的增加,子类也变得繁多。
结语
如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )