Android設計模式- 策略模式

策略模式用於算法的自由切換和擴展,分離算法的定義與實現。java

  • 好處:將不一樣的行爲策略(Strategy)進行獨立封裝,與類在邏輯上解耦,便可以動態改變對象的行爲
  • 原則:抽取代碼中變化的部分來實現一個接口,並提供多種實現類,即算法。調用方須要使用這個接口的時候,能夠動態的選擇這些實現類。算法的變化獨立於使用算法的調用者,從而能夠輕鬆的擴展與改變策略,實現對象的動態改變行爲,符合OCP原則

Android中策略模式的應用有WebView設計,Animation中的Interpolator設計.....算法

例如電商應用中的商品價格計算bash

fun main(args: Array<String>) {
    val price   = 4500.0
    val mContext = PriceStrategyContext(NormalPriceStrategy())
    mContext.strategyMethod(price)
    mContext.setStrategy(GoldPriceStrategy())
    mContext.strategyMethod(price)
}


interface PriceStrategy {
    /**
     * 計價方法
     */
    fun calculate(price: Double): Double
}

class NormalPriceStrategy : PriceStrategy {
    override fun calculate(price: Double): Double {
        println("普通用戶的計價策略方法被訪問")
        return  price
    }
}

class GoldPriceStrategy : PriceStrategy {
    override fun calculate(price: Double): Double {
        println("黃金會員的計價策略方法被訪問")
        return 0.95 * price
    }
}

class DiamondPriceStrategy : PriceStrategy {
    override fun calculate(price: Double): Double {
        println("鑽石會員的計價策略方法被訪問")
        return 0.9 * price
    }
}


/**
 * 上下文環境,定義了 PriceStrategy 接口引用,在建立 PriceStrategyContext 實例時傳入具體的策略類,
 * 具體策略類調用策略方法。客戶端建立 PriceStrategyContext 對象負責調用策略方法。
 */
class PriceStrategyContext() {
    private var mPriceStrategy: PriceStrategy? = null

    constructor(mPriceStrategy: PriceStrategy) : this() {
        this.mPriceStrategy = mPriceStrategy
    }

    fun setStrategy(strategy: PriceStrategy?): PriceStrategyContext {
        mPriceStrategy = strategy!!
        return this
    }

    //持有算法方法
    fun strategyMethod(price: Double) {
        mPriceStrategy!!.calculate(price)
    }
}
複製代碼

策略模式中的上下文環境 PriceStrategyContext 的職責是隔離客戶端與策略類的耦合,無須關注具體的策略行爲。上面示例中, PriceStrategyContext 的做用只是負責調度策略類的執行並獲取結果,並無徹底起到隔離客戶端與策略類的做用。markdown

經過簡單工廠模式將具體策略對象的建立與調用方進行隔離,也可經過策略枚舉或者策略類的配置注入,將PriceStrategyContext中的具體策略類融合在一塊兒,簡化代碼。ide

##簡單工廠函數

abstract class PriceStrategyFactory {
    companion object {
        inline operator fun <reified T : PriceStrategy> invoke(): PriceStrategy? {
            var strategy: PriceStrategy? = null
            try {
                strategy = T::class.java.newInstance() as PriceStrategy
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return strategy
        }
    }
}
複製代碼

##枚舉this

fun main(args: Array<String>) {
    PriceStrategy.GOLD.calculate(4500.0)
}

enum class PriceStrategy(var type: String) {
    //
    NORMAL("normal") {
        override fun calculate(price: Double): Double {
            println("普通用戶的計價策略方法被訪問")
            return price
        }
    },
    GOLD("gold") {
        override fun calculate(price: Double): Double {
            println("黃金會員的計價策略方法被訪問")
            return price * 0.95
        }
    },
    DIAMOND("diamond") {
        override fun calculate(price: Double): Double {
            println("鑽石會員的計價策略方法被訪問")
            return price * 0.9
        }
    };
    
    fun setType(type: String): PriceStrategy {
        this.type = type
        return this
    }

    abstract fun calculate(price: Double): Double

	}
複製代碼

##高階函數抽象算法 策略類僅僅是針對算法行爲的一種抽象,Kotlin 中能夠使用高階函數替代。spa

fun main(args: Array<String>) {
    PriceStrategyContext(4500.0, NormalPriceStrategy).calculate()
}

// 策略用val聲明成lambda表達式
val NormalPriceStrategy = { price: Double -> price }
val GoldPriceStrategy = { price: Double -> price * 0.95 }
val DiamondPriceStrategy = { price: Double -> price * 0.9 }

class PriceStrategyContext(private val price: Double, private val priceStrategy: (Double) -> Double) {
    // 
    fun calculate() = priceStrategy(price)
}
複製代碼

策略模式須要不停的在各個算法間切換,形成不少邏輯判斷,咱們能夠配合使用一些其餘的模式去消除。設計

相關文章
相關標籤/搜索