策略模式其实特别简单(听到这句话,大家是不是心里一下子放松了?)。
比如排序,官方告诉大家我这里有一个排序的接口ISort的sort()方法,然后民间各尽其能,实现这个排序的方法:冒泡,快速,堆等等。
这些方法就是“不同的策略”。
然后,某个模块下,需要一个排序方法,但是暂时不能指定具体的sort方法(出于扩展的考虑),就需要使用ISort接口了。
最后,具体什么场景下,传入什么具体的sort方法,实现灵活的排序。
这就是策略模式!
下面,我们分析Android中的动画是如何使用策略模式的。
1. 意图
定义一系列的算法,把它们一个个封装起来,并且使它们可互相替换。
策略模式使得算法可独立于使用它的客户而变化。
2. 结构图和代码
Animation不同动画的实现,主要是依靠Interpolator的不同实现而变。
定义接口Interpolator:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
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为例,实现具体的策略,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
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类是怎么做的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
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();
}
}
}
|
策略模式其实就是多态的一个淋漓精致的体现。
3. 效果
(1).行为型模式
(2).消除了一些if...else...的条件语句
(3).客户可以对实现进行选择,但是客户必须要了解这个不同策略的实现(这句话好像是废话,总而言之,客户需要学习成本)
(4).代码注释中提到了缺省实现,可以让客户不了解策略,也能实现默认的策略
(5).注入的方式有多种:构造函数,set方法,注释。配置解析等等
本贴原址:http://www.cnblogs.com/qianxudetianxia/archive/2013/04/19/3030235.html