Android設(shè)計模式之策略模式

設(shè)計模式.png

此文章全是文字宴凉,但是不長誊锭,看上去有點枯燥,還請保持耐心弥锄。

策略模式,很多人會忘記的一個模式,但是是我們平時開發(fā)中用到的最多的籽暇,我個人而言温治,我認(rèn)為多態(tài)的使用,就是策略模式的最好應(yīng)用戒悠。

定義

策略模式定義了一系列的算法熬荆,并將每一個算法封裝起來,而且使它們還可以互相替換绸狐。策略模式讓算法獨立于使用它的客戶而獨立變化卤恳。

通過建立抽象,將不同的策略構(gòu)建成一個具體的策略實現(xiàn)寒矿,通過不同的策略實現(xiàn)算法替換突琳。在簡化邏輯、結(jié)構(gòu)的同時符相,增強了系統(tǒng)的可讀性拆融、穩(wěn)定性、可擴展性啊终,這對于較為復(fù)雜的業(yè)務(wù)邏輯顯得更為直觀镜豹,擴展也更為方便。

使用場景

在軟件開發(fā)中常常遇到這樣的情況:實現(xiàn)某一個功能可以有多種算法或者策略蓝牲,我們根據(jù)事件情況選擇不同的算法或者策略來完成該功能趟脂。例如,排序算法例衍,可以使用插入排序散怖、歸并排序、冒泡排序等肄渗。

這對這種情況镇眷,一個常規(guī)的方法是將多種算法寫在一個類中。例如翎嫡,需要提供多種排序算法欠动。可以將這些算法寫到一個 類中惑申,每一個方法對應(yīng)一個具體的排序算法具伍;當(dāng)然,也可以將這些排序算法封裝到一個統(tǒng)一的方法中圈驼,通過 if….else… 或者 case 等條件判斷語句來選擇具體的算法人芽。這兩種實現(xiàn)方式都可以稱為硬編碼。然而绩脆,當(dāng)很多個算法集中在一個類中時萤厅,這個類就會變得臃腫橄抹,這個類的維護成本也會變高,在維護時也更容易引發(fā)錯誤惕味。如果我們需要增加一種新的排序算法楼誓,需要修改封裝算法類的源代碼。這就明顯違反了我們前面博客中所說的 SOLID 原則中的 開閉原則和單一職責(zé)原則名挥。

如果將這些算法或者策略抽象出來疟羹,提供一個統(tǒng)一的接口,不同的算法或者策略有不同的實現(xiàn)類禀倔,這樣在程序客戶端就可以通過注入不同的實現(xiàn)對象來實現(xiàn)算法或者策略的動態(tài)替換榄融,這種模式的可擴展性、可維護性也就更高救湖,也就是我們接下來要說的策略模式愧杯。

使用場景總結(jié)

  • 針對同一類型問題的多種處理方式,僅僅是具體行為有差別時捎谨。
  • 需要安全地封裝多種同一類型的操作時民效。
  • 出現(xiàn)同一抽象類有多個子類,而又需要使用if-else 或者 switch-case 來選擇具體子類時涛救。

如何實現(xiàn)

1.定義接口A畏邢,想好封裝
2.implement A接口 實現(xiàn)B
3.多態(tài)使用(這么一說,我仿佛在說 java基礎(chǔ)之多態(tài))

    class B implement A{
    }


    class M{
        A a;
        
        public void setFunc(A b){
            a = b;
        }
    }

源碼應(yīng)用

其實這個是個很簡單的設(shè)計模式检吆,應(yīng)用很多舒萎,我們來看看Android源碼中有什么經(jīng)典應(yīng)用吧。

TimeInterpolator 時間插值器

我們來看一個插值器源碼

/** 
 * An interpolator where the rate of change is constant 
 * 
 */  
@HasNativeInterpolator  
public class LinearInterpolator implements Interpolator, NativeInterpolatorFactory {  
  
    public LinearInterpolator() {  
    }  
      
    public LinearInterpolator(Context context, AttributeSet attrs) {  
    }  
      
    public float getInterpolation(float input) {  
        return input;  
    }  
  
    /** @hide */  
    @Override  
    public long createNativeInterpolator() {  
        return NativeInterpolatorFactoryHelper.createLinearInterpolator();  
    }  
} 

每個動畫都有自己的默認(rèn)插值器, 而通過抽象出插值器接口(最新版本的源碼又改了)蹭沛,然后我們可以通過setInterpolator去改變它
這樣大大增加了類的功能上的擴展性

animtorAlpha.setInterpolator(new LinearInterpolator());

當(dāng)我們調(diào)用ssetInterpolator時臂寝,發(fā)生了哪些事情呢?

public class ValueAnimator extends Animator{
    //插值器也有自己的默認(rèn)初始值
    private TimeInterpolator mInterpolator = sDefaultInterpolator;
    
        // The time interpolator to be used if none is set on the animation
    private static final TimeInterpolator sDefaultInterpolator =
            new AccelerateDecelerateInterpolator();

    //設(shè)置插值器
    @Override
    public void setInterpolator(TimeInterpolator value) {
        if (value != null) {
            mInterpolator = value;
        } else {
            mInterpolator = new LinearInterpolator();
        }
    }
}

當(dāng)我們調(diào)用時摊灭,直接替換了TimeInterpolator咆贬。無需干其他事情,我們自己寫多種復(fù)用的自定義view啊帚呼,window啊掏缎,都可以借鑒這樣的寫法。

小小總結(jié)

總結(jié)
策略模式主要用來分離算法煤杀,在相同的行為抽象下有不同的具體實現(xiàn)策略眷蜈。這個模式很好地演示了開閉原則,也就是定義抽象沈自,注入不同的實現(xiàn)酌儒,從而達(dá)到很好的可擴展性。

優(yōu)點

  • 結(jié)構(gòu)清晰明了枯途,使用簡單直觀忌怎;
  • 耦合度相對而言較低籍滴,擴展方便;
  • 操作封裝也更為徹底呆躲,數(shù)據(jù)更為安全异逐。

缺點:

  • 隨著策略的增加捶索,子類也會變得繁多插掂。

謝謝大家閱讀,如有幫助腥例,來個喜歡或者關(guān)注吧辅甥!


本文作者:Anderson/Jerey_Jobs

簡書地址:[Anderson大碼渣][1]

github地址:[Jerey_Jobs][2]
[1]: http://www.reibang.com/users/016a5ba708a0/latest_articles
[2]: https://github.com/Jerey-Jobs

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市燎竖,隨后出現(xiàn)的幾起案子璃弄,更是在濱河造成了極大的恐慌,老刑警劉巖构回,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夏块,死亡現(xiàn)場離奇詭異,居然都是意外死亡纤掸,警方通過查閱死者的電腦和手機脐供,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來借跪,“玉大人政己,你說我怎么就攤上這事√统睿” “怎么了歇由?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長果港。 經(jīng)常有香客問我沦泌,道長,這世上最難降的妖魔是什么辛掠? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任谢谦,我火速辦了婚禮,結(jié)果婚禮上公浪,老公的妹妹穿的比我還像新娘他宛。我一直安慰自己,他們只是感情好欠气,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布厅各。 她就那樣靜靜地躺著,像睡著了一般预柒。 火紅的嫁衣襯著肌膚如雪队塘。 梳的紋絲不亂的頭發(fā)上袁梗,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音憔古,去河邊找鬼遮怜。 笑死,一個胖子當(dāng)著我的面吹牛鸿市,可吹牛的內(nèi)容都是我干的锯梁。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼焰情,長吁一口氣:“原來是場噩夢啊……” “哼陌凳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起内舟,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤合敦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后验游,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體充岛,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年耕蝉,在試婚紗的時候發(fā)現(xiàn)自己被綠了崔梗。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡赔硫,死狀恐怖炒俱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情爪膊,我是刑警寧澤权悟,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站推盛,受9級特大地震影響峦阁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜耘成,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一榔昔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瘪菌,春花似錦撒会、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至默穴,卻和暖如春怔檩,著一層夾襖步出監(jiān)牢的瞬間褪秀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工薛训, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留媒吗,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓乙埃,卻偏偏與公主長得像闸英,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子膊爪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容