Android設計モード(四)戦略モード


戦略モードはアルゴリズムの自由切換と拡張のために用いられ,分離アルゴリズムの定義と実装を行った.
  • 利点:異なる挙動ポリシーを単独でカプセル化し、クラスと論理的に結合し、すなわちオブジェクトの挙動を動的に変えることができる
  • .
  • 原則:コード内の変化部分を抽出してインターフェースを実現し、様々な実装クラス、すなわちアルゴリズムを提供する.呼び出し側がこのインターフェースを使用する必要がある場合、これらの実装クラスを動的に選択することができます.アルゴリズムの変化は、アルゴリズムを使用するスケジューラとは独立しており、これにより、オブジェクトの動的変更挙動を簡単に拡張し、変更することができ、OCP原則に適合する
  • .
    Androidでのストラテジーモードの応用にはWebViewデザイン、AnimationでのInterpolatorデザインがあります.
    例えば電気商の応用の中の商品の価格は計算します.
    fun main(args: Array) {
        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)
        }
    }
    ポリシーモードにおけるコンテキスト環境Price StrategyContectの役割は、クライアントとポリシークラスの結合を分離することであり、具体的なポリシー行動に関心を持たなくてもよい.上記の例では、Price StrategyContectの役割は、スケジュールポリシークラスの実行と結果の取得だけであり、クライアントとポリシークラスを完全に分離する役割を果たしていない.
    単純工場モードにより、具体的な戦略対象の作成を呼び出し側と隔離し、戦略列挙または戦略類の配置注入により、Price StrategyContectの具体的な戦略類を融合させ、コードを簡略化することができる.
    簡易工場
    abstract class PriceStrategyFactory {
        companion object {
            inline operator fun  invoke(): PriceStrategy? {
                var strategy: PriceStrategy? = null
                try {
                    strategy = T::class.java.newInstance() as PriceStrategy
                } catch (e: Exception) {
                    e.printStackTrace()
                }
                return strategy
            }
        }
    }
    列挙
    fun main(args: Array) {
        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では高次関数を用いて置換することができる.
    fun main(args: Array) {
        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)
    }
    戦略モードは各アルゴリズム間で切り換わる必要があり、多くの論理判断をもたらし、他のいくつかのモードを組み合わせて除去することができます.