设计模式(2)策略模式 (模式讲解+应用)
博客新址,這里更有趣
目錄
策略模式
為什么使用策略模式?
策略模式應用實例
策略模式
策略模式:建立行為族,將不同的行為分別封裝,同時彼此可相互替代,算法的變化可以獨立于使用者。
優點:提高了可復用性,將行為和使用者解耦出來
缺點:增加了編寫代碼工作量
為什么使用策略模式
通過一個游戲的例子我們可以更好的說明這個問題,我們的游戲中有很多的人物,這個時候,我們定義一個基礎游戲角色類,然后不同的角色將會有不同的技能,所以其攻擊行為和防御行為在不同的角色中是不同的,其單位攻擊所造成的傷害和攻擊的特效也是不同的,如果按照傳統的方式,我們首先想到的寫法可能是這樣子的。
//基類,具有攻擊和防御行為,所有游戲角色繼承自這個基類 class People{People(){} //攻擊public void attck(){} //防御public void defense(){} } //法師角色class Master extends People{Master(){}public void attck(){造成魔法傷害}public void defense(){抵御魔法攻擊}} //劍客角色 class Swordsman extends People{Swordsman(){}public void attck(){造成物理傷害}public void defense(){抵御物理攻擊} }這樣子來看完全可行,我們需要什么角色實例的時候只需要new一個即可,但是我們的游戲中的角色往往是有很多的,而不只是簡單這幾種的。當我們為了改善游戲體驗進一步吸引用戶,所以需要對游戲中的角色的攻擊增加特效或者是對防御增加某種特殊防御,或者是該角色的攻擊方式和防御方式都發生了變化,這個時候我們就需要對每一個角色類進行查找,找到那些角色有這種攻擊方式和防御方式,然后打開對其進行修改,工作將變得很繁瑣,同時對原有的類進行修改也進一步增加了我們犯錯的幾率。如何改善這種狀況呢?這個時候我們需要考慮,這其中那些東西是變的,而那些東西是固定的,然后封裝變化的。這也正是設計的一個原則找出那些變化的將他們獨立出來,不要和那些不需要變化的混在一起。
所以我們想到將這些變化的行為,攻擊和防御進行封裝起來,將一些不會變化的比如,姓名,性別設置,更新方法與之孤立起來。將行為進行封裝,便于我們后期的需求變更時,對項目進行更新,那么我們想到的就是設置不同的行為類,然后通過委托的方式,在角色的內部發生其真實行為。那么我們可以寫出下面的代碼。
abstract class People{Attackable attckable;Denfenseable denfenseable;public void setAttckMethond(Attackable attckable){this.attckable = attckable;}public void setDefenseMethond(Denfenseable denfenseable){this.denfenseable = denfenseable;}public void attck(){attckable.invoke();}public void defense(){denfenseable.invoke();}public abstract void haveSex();More Methond..... } //法師 class Master extends People{Master(){}public void haveSex(){System.out.println("Come on");}} //劍客 class Swordsman extends People{Swordsman(){}public void haveSex(){System.out.println("ya mie die")} } //定義攻擊接口 public interface Attackable{public void invoke(); } // 定義防御接口 public interface Denfenseable{public void invoke(); } //實現了攻擊接口的秒殺全場攻擊 public class KillAll implements Attackable{public void invoke(){System.out.println("Kill All");} } //實現了防御接口的抵御任何攻擊接口 public class DenfenseAnyAttack implements Denfenseable{public void invoke(){System.out.println("Denfense All");} }將變化的攻擊和防御行為單獨拿出來作為接口,然后在基類中通過委托的形式,借助多態,來實現相應的攻擊,防御方式,同時設置了set方法,使得其擴展性進一步增強。當我們修改英雄的攻擊行為和防御行為只需要通過set方法即可,如果對攻擊和防御行為的表現形式進行修改,通過找到相應的行為類修改即可,借助委托,多態,實現了徹底的將對象和行為進行解耦。
依賴注入:通常我們可以通過set方法,構造函數來將我們所依賴的對象,通過接口或者是父類的形式注入進去。內部借助委托機制實現相應的功能。
策略模式應用實例
在我們開法,我們所使用的類庫中,有哪些是通過策略模式來實現的呢?
在Android的動畫中,Animation有一個方法為setInterpolator() 熟悉Android開發的一定知道其作用,用來設置一個插值器,其作用是用來控制動畫開始結束等一些特效,而其實現就是使用了策略模式。
有一個插值器的接口,然后各種不同類型的插值器通過實現接口來實現不同的動畫特效。實現Interpolator接口的類有
AccelerateDecelerateInterpolator 在動畫開始與介紹的地方速率改變比較慢,在中間的時候加速
AccelerateInterpolator 在動畫開始的地方速率改變比較慢,然后開始加速
AnticipateInterpolator 開始的時候向后然后向前甩
AnticipateOvershootInterpolator 開始的時候向后然后向前甩一定值后返回最后的值
BounceInterpolator 動畫結束的時候彈起
CycleInterpolator 動畫循環播放特定的次數,速率改變沿著正弦曲線
DecelerateInterpolator 在動畫開始的地方快然后慢
LinearInterpolator 以常量速率改變
OvershootInterpolator 向前甩一定值后再回到原來位置
舉一個例子
package android.view.animation;import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet;public class AccelerateInterpolator implements Interpolator {private final float mFactor;private final double mDoubleFactor;public AccelerateInterpolator() {mFactor = 1.0f;mDoubleFactor = 2.0;}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);}} }Animation源碼
public abstract class Animation implements Cloneable {Interpolator mInterpolator;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();}}}總結:通過對于源碼的分析,不難發現其和游戲角色設定的相似之處,實現一個接口,然后不同行為實現該接口,使用者通過set方法,以接口的形式,實現具體實例的依賴注入。從而實現相應的功能。
總結
以上是生活随笔為你收集整理的设计模式(2)策略模式 (模式讲解+应用)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [CS101] 转载:浅议Fibonac
- 下一篇: LAN远程重启server安全方法