設計模式之策略模式

策略模式其實特別簡單(聽到這句話,你們是否是內心一會兒放鬆了?)。
好比排序,官方告訴你們我這裏有一個排序的接口ISort的sort()方法,而後民間各盡其能,實現這個排序的方法:冒泡,快速,堆等等。
這些方法就是「不一樣的策略」。
而後,某個模塊下,須要一個排序方法,可是暫時不能指定具體的sort方法(出於擴展的考慮),就須要使用ISort接口了。
最後,具體什麼場景下,傳入什麼具體的sort方法,實現靈活的排序。
這就是策略模式!
下面,咱們分析Android中的動畫是如何使用策略模式的。html

1. 意圖
定義一系列的算法,把它們一個個封裝起來,而且使它們可互相替換。
策略模式使得算法可獨立於使用它的客戶而變化。java

2. 結構圖和代碼
Animation不一樣動畫的實現,主要是依靠Interpolator的不一樣實現而變。

定義接口Interpolator:android

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類是怎麼作的:app

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();
          }
      }
 
}

  策略模式其實就是多態的一個淋漓精緻的體現。less

3. 效果
(1).行爲型模式
(2).消除了一些if...else...的條件語句
(3).客戶能夠對實現進行選擇,可是客戶必需要了解這個不一樣策略的實現(這句話好像是廢話,總而言之,客戶須要學習成本)
(4).代碼註釋中提到了缺省實現,可讓客戶不瞭解策略,也能實現默認的策略
(5).注入的方式有多種:構造函數,set方法,註釋。配置解析等等函數

 

本貼原址:http://www.cnblogs.com/qianxudetianxia/archive/2013/04/19/3030235.html學習

相關文章
相關標籤/搜索