策略模式用於算法的自由切換和擴展,分離算法的定義與實現。java
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)
}
複製代碼
策略模式須要不停的在各個算法間切換,形成不少邏輯判斷,咱們能夠配合使用一些其餘的模式去消除。設計