Android开发设计模式05

策略模式其实特别简单(听到这句话,大家是不是心里一下子放松了?)。
比如排序,官方告诉大家我这里有一个排序的接口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方法,注释。配置解析等等

--------------

建造者模式把构造和表示分离开,根据客户需求生产一个相应的对象。
本来呢,我们根据Builder接口实现不同的具体的ConcreteBuilder,就可生产不同的对象了。
但是,下面例子的只有一个Builder,所以也没有接口Builder,也没有其他的ConcreteBuilder。
但是我今天要讲的例子太简单,简单到都不觉得是建造者模式,但是又有建造者模式的感觉。

1. 意图
将一个复杂对象的构建和它的表示分离,使得同样的创建过程可以创建不同的表示。

2.结构图和代码
android中大量的使用对话框组件,它的调用方法就是构建,拼接,表示。

Builder通过setTitle(),setMessage(),setIcon()等方法在create()中构造出一个AlertDialogInstance对象。
然后客户可以把把AlertDialogInstance对象show出去。

针对这个例子,我有必要通过扩展一下,以正建造者模式之名。
如何扩展?
(1).创建其他的ConcreteBuilder
(2).创建其他的ElseDialog
(3).第1,2步决定了我们最好创建一个抽象的Builder
(4).创建一个Context,把builder注入进去,生产不同的Dialog(或者其他UI)对象。

3.效果
(1).创建型模式
(2).可以生产不同的Dialog,也可以生产其他的UI,生产的Product可以是差别很大的,所以也没必要为Product定义抽象父类。

--------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值