5分鐘學(xué)會(huì)Android設(shè)計(jì)模式之策略模式Strategy Pattern教程
5分鐘設(shè)計(jì)模式之策略模式(Strategy Pattern)
設(shè)計(jì)模式是軟件開發(fā)中的常用模式,但是實(shí)際上很多人只是了解其概念,而在實(shí)際開發(fā)中并不知道如何應(yīng)用。因此,我們可以結(jié)合實(shí)際開發(fā)案例來詳細(xì)講解策略模式。
如果您有任何疑問、對(duì)文章寫的不滿意、發(fā)現(xiàn)錯(cuò)誤或者有更好的方法,歡迎在評(píng)論、私信或郵件中提出,非常感謝您的支持。??
1、收到需求
假設(shè)我們需要自定義的 View 類,它需要實(shí)現(xiàn)不同的動(dòng)畫效果,包括平移、旋轉(zhuǎn)、縮放等等等等。我們可以使用策略模式來實(shí)現(xiàn)這個(gè)功能,使得每種動(dòng)畫效果都對(duì)應(yīng)一個(gè)策略類。
2、不使用策略模式
需要在 AnimatedView 類中實(shí)現(xiàn)所有的動(dòng)畫效果
class AnimatedView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
var animationType: String = "translate"
fun startAnimation() {
when (animationType) {
"translate" -> {
// 實(shí)現(xiàn)平移動(dòng)畫
}
"rotate" -> {
// 實(shí)現(xiàn)旋轉(zhuǎn)動(dòng)畫
}
"scale" -> {
// 實(shí)現(xiàn)縮放動(dòng)畫
}
else -> {
throw IllegalArgumentException("Invalid animation type")
}
}
invalidate()
}
}
調(diào)用如下,需要在 AnimatedView 對(duì)象中設(shè)置動(dòng)畫類型,然后調(diào)用 startAnimation 方法來開始動(dòng)畫:
animatedView.apply {
animationType = "translate"
}.startAnimation()
animatedView().apply {
animationType = "rotate"
}.startAnimation()
在這種實(shí)現(xiàn)方式中,如果需要增加或修改動(dòng)畫效果,我們需要修改 AnimatedView 類中的代碼,這樣會(huì)增加代碼的復(fù)雜度和維護(hù)成本。
3、使用策略模式
而使用策略模式,我們只需要增加或修改策略實(shí)現(xiàn)類即可,而不需要修改現(xiàn)有的代碼。因此,使用策略模式能夠更好地實(shí)現(xiàn)代碼的可擴(kuò)展性和可維護(hù)性。
我們將動(dòng)畫有多種實(shí)現(xiàn)方法(不同的行為)這些行為看成一個(gè)AnimationStrategy 策略接口
定義了一個(gè)應(yīng)用動(dòng)畫的策略
interface AnimationStrategy {
fun applyAnimation(view: View)
}
它只是一個(gè)接口,等待具體的動(dòng)畫實(shí)現(xiàn) ,而剛開始的通過設(shè)置animationType,在onDraw中通過if來判斷的方式
修改為了使用當(dāng)前的策略對(duì)象
private var animationStrategy: AnimationStrategy? = null
在onDraw中調(diào)用
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
if (animationStrategy != null) {
animationStrategy!!.applyAnimation(this)
}
}
我們?cè)匐S便寫幾個(gè)定義不同的策略實(shí)現(xiàn)類,這些實(shí)現(xiàn)類實(shí)現(xiàn)了 AnimationStrategy 接口,并且根據(jù)不同的需求,可以選擇不同的策略實(shí)現(xiàn)類來應(yīng)用不同的動(dòng)畫效果。
class TranslateAnimationStrategy : AnimationStrategy {
override fun applyAnimation(view: View) {
// 實(shí)現(xiàn)平移動(dòng)畫
}
}
class RotateAnimationStrategy : AnimationStrategy {
override fun applyAnimation(view: View) {
// 實(shí)現(xiàn)旋轉(zhuǎn)動(dòng)畫
}
}
class ScaleAnimationStrategy : AnimationStrategy {
override fun applyAnimation(view: View) {
// 實(shí)現(xiàn)縮放動(dòng)畫
}
}
使用方法如下,根據(jù)不同的需求來選擇不同的策略實(shí)現(xiàn)類
animatedView.apply {
animationStrategy = TranslateAnimationStrategy() // 執(zhí)行平移動(dòng)畫
//or
animationStrategy = RotateAnimationStrategy() // 執(zhí)行旋轉(zhuǎn)動(dòng)畫
//or
animationStrategy = ScaleAnimationStrategy()// 執(zhí)行縮放動(dòng)畫
}
而 AnimationStrategy 接口作為一個(gè)統(tǒng)一的接口,可以使得不同的策略實(shí)現(xiàn)類可以被統(tǒng)一地使用,從而實(shí)現(xiàn)了代碼的解耦和可擴(kuò)展性。
整合起來
class AnimatedView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
var animationStrategy: AnimationStrategy? = null
set(value) {
field = value
invalidate()
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
animationStrategy?.applyAnimation(this)
}
}
4、小結(jié)
策略模式是一種行為型設(shè)計(jì)模式,它允許在運(yùn)行時(shí)動(dòng)態(tài)地選擇算法或行為,從而使得算法或行為可以獨(dú)立于使用它們的客戶端而變化。在例子中動(dòng)畫的改變,并不需要修改AnimatedView
通常由一個(gè)接口或抽象類和多個(gè)實(shí)現(xiàn)類組成??蛻舳送ㄟ^調(diào)用接口或抽象類中的方法來執(zhí)行算法或行為,而具體的實(shí)現(xiàn)則由策略實(shí)現(xiàn)類來完成。在例子中AnimationStrategy為接口,各個(gè)動(dòng)畫為實(shí)現(xiàn)類。AnimatedView通過animationStrategy?.applyAnimation(this)來執(zhí)行
如此我們也可以看出
- 一個(gè)類需要在運(yùn)行時(shí)根據(jù)不同的情況采用不同的算法或行為。
- 一個(gè)類定義了許多行為,而且這些行為在類的方法中以多個(gè)條件語句的形式出現(xiàn),將這些行為“分解”到不同的策略類中,可以避免條件語句的復(fù)雜度。
- 算法的使用頻率不高,可以把它們封裝到策略類中,從而避免讓整個(gè)系統(tǒng)變得臃腫。
- 多個(gè)類只有在算法或行為上稍有不同的情況。
使用策略模式可以增加代碼的靈活性和可維護(hù)性,使得代碼更易于擴(kuò)展和修改。不過可不要亂用,畢竟多了很多個(gè)類,不是嘛。
結(jié)尾
設(shè)計(jì)模式是一個(gè)非常廣泛的話題,很多設(shè)計(jì)模式又有極高的相似度,剛接觸很容易混淆,因此很難知道在什么情況下應(yīng)該使用哪種設(shè)計(jì)模式。我將盡力提供在開發(fā)過程中遇到的最小單元的設(shè)計(jì)模式案例。更好地理解何時(shí)以及如何使用設(shè)計(jì)模式。
以上就是5分鐘學(xué)會(huì)Android設(shè)計(jì)模式之策略模式Strategy Pattern教程的詳細(xì)內(nèi)容,更多關(guān)于Android策略模式Strategy Pattern的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android setButtonDrawable()的兼容問題解決辦法
這篇文章主要介紹了Android setButtonDrawable()的兼容問題解決辦法的相關(guān)資料,需要的朋友可以參考下2017-03-03
Android webview實(shí)現(xiàn)拍照的方法
這篇文章主要介紹了Android webview實(shí)現(xiàn)拍照的方法的相關(guān)資料,希望通過本文能幫助到大家實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下2017-10-10
PC版與Android手機(jī)版帶斷點(diǎn)續(xù)傳的多線程下載
這篇文章主要介紹了PC版與Android手機(jī)版帶斷點(diǎn)續(xù)傳的多線程下載的相關(guān)資料,需要的朋友可以參考下2015-10-10
Android View教程之自定義驗(yàn)證碼輸入框效果
這篇文章主要給大家介紹了關(guān)于Android View教程之自定義驗(yàn)證碼輸入框效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
Android網(wǎng)絡(luò)連接判斷與相關(guān)處理
這篇文章主要為大家詳細(xì)介紹了Android網(wǎng)絡(luò)連接判斷操作,幫助大家判斷WIFI網(wǎng)絡(luò)是否可用,判斷MOBILE網(wǎng)絡(luò)是否可用,感興趣的小伙伴們可以參考一下2016-08-08
Android 自定義一套 Dialog通用提示框 (代碼庫)
這篇文章主要介紹了Android 自定義一套 Dialog通用提示框 (代碼庫),需要的朋友可以參考下2017-04-04
Android編程實(shí)現(xiàn)TextView字體顏色設(shè)置的方法小結(jié)
這篇文章主要介紹了Android編程實(shí)現(xiàn)TextView字體顏色設(shè)置的方法,結(jié)合實(shí)例形式總結(jié)分析了Android針對(duì)TextView字體顏色設(shè)置的相關(guān)步驟與注意事項(xiàng),具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-12-12

