デザインモデルに悩んでいますか?戦略モデル

5565 ワード

ポリシー・モード
前言
多くの人がサードパーティのフレームワーク(例えばRetrofit)を読むとき、よく分からないか、骨が折れるのは、コードを書く思考が欠けているためで、コードの設計のモードを見て、今日、おかずは私が戦略のモードに対する理解を話します
紹介する
  • 専門説:一連のアルゴリズムを定義し、各アルゴリズムをカプセル化し、それらを互いに置き換えることができ、ポリシーモードはアルゴリズムをその顧客とは独立して
  • 変化させる.
  • 例の言い方:仮に、今日、私はルームメイトのために料理を煮て、おかずは私は豚肉を買いましたが、ルームメイトが楽しい时、肉を焼くのが好きで、私は肉を焼くのが好きです;悲しい时、豚肉の蒸し煮が好きで、私は豚肉の蒸し煮をします:1.悲しい(策略)->肉を焼く(アルゴリズム).楽しい(策略)->豚肉の蒸し煮(アルゴリズム)
  • 改善前のコード
    /**
     * Created by Jenchar on 2016/7/30.
     */
    public class Meat {
        public static final String HAPPY="  ";
        public static final String SAD="  ";
        public static final String REDMEAT="   ";
        public static final String BRAISEMEAT="   ";
    
        public static void main(String[] args) {
            Meat meat=new Meat();
            meat.chooseFood(SAD,BRAISEMEAT);
        }
        private void chooseFood(String fellings,String type) {
            if(fellings.equals(HAPPY)){
                codeRedMeat(type);
            }else{
                cookBraiseMeat(type);
            }
        }
    
        private void cookBraiseMeat(String meat) {
            System.out.println(" "+HAPPY+"   ,"+"     "+meat);
        }
    
        private void codeRedMeat(String meat) {
            System.out.println(" "+SAD+"   ,"+"     "+meat);
        }
    }
    
        :
          ,        
    

    分析:
    Meat類の明らかな問題は単一の職責ではない(簡単に言えば、一つの類には一つの機能しかない)ことであり、まず肉を焼くことと豚肉を蒸すことの職責を引き受け、もう一つの問題はif-elseの形式でどちらをするかを判断することである.おかずは、私が友达を捨てて神経症になって、興奮しているとき、豚肉を揚げるのが好きだと思っています.それでは、Meat類に豚肉を揚げる方法を追加し、chooseFood(String fellings、String type)方法に判断を追加する必要があります.コードは以下の通りです.
    /**
     * Created by Jenchar on 2016/7/30.
     */
    public class Meat {
        public static final String HAPPY="  ";
        public static final String SAD="  ";
        public static final String REDMEAT="   ";
        public static final String BRAISEMEAT="   ";
        /**
         *    
         */
        public static final String  EXCITED="  ";
        public static final String  FLYINGMEAT="   ";
    
        public static void main(String[] args) {
            Meat meat=new Meat();
            meat.chooseFood(EXCITED,FLYINGMEAT);
    
        }
        private void chooseFood(String fellings,String type) {
            if(fellings.equals(HAPPY)){
                codeRedMeat(type);
            }else if(fellings.equals(SAD)){
                cookBraiseMeat(type);
                /**
                 *    
                 */
            }else if(fellings.equals(EXCITED)){
                cookFlyingMeat(type);
            }
        }
    
        /**
         *   
         */
        private void cookFlyingMeat(String type) {
            System.out.println(" "+EXCITED+"   ,"+"     "+type);
        }
    
        private void cookBraiseMeat(String meat) {
            System.out.println(" "+HAPPY+"   ,"+"     "+meat);
        }
    
        private void codeRedMeat(String meat) {
            System.out.println(" "+SAD+"   ,"+"     "+meat);
        }
    }
        :
          ,        
    
    

    再分析:
    chooseFood(String fellings,String type)という方法を見てみると、コードが乱れているのではないでしょうか.if-else文が絡み合っていますか.おかずのルームメイトが、精神分裂でもう一つ食べたいと思っていたら、chooseFoodでif-elseを増やします.if-else文が多くなると、見間違えたり、書き間違えたりしやすくなります.また、コードが膨らんだり、小さなプロジェクト、小さなクラスは通れますが、大きなプロジェクトになると、必然的に乱れ、メンテナンスが難しくなります.だから、このような状況のため、私は1種の設計モードを導入し始めて、“策略モード”
    改善されたコード
    まずおかずは抽象的な肉作りインタフェースを定義し、CookStrategyと命名する必要があります.コードは以下の通りです.
    /**
     *      
     */
    public interface CookStrategy {
        /**
         *           
         * @param feelings
         */
        void cook(String feelings);
    }
    

    次に、肉を焼くか豚肉を蒸すかについて、おかずには独立した肉を作る戦略類があると思います.これらの類は上記のCookStrategyインタフェースを実現しています.コードは以下の通りです.CookRedMeat.java:
    /**
     *       
     */
    public class CookRedMeat implements CookStrategy{
        public static final String REDMEAT="   ";
        /**
         *           
         * @param feelings
         */
        @Override
        public void cook(String feelings) {
            System.out.println(" "+feelings+"   ,"+"     "+REDMEAT);
        }
    }
    
    

    CookBraiseMeat.java:
    /**
     *      
     */
    public class CookBraiseMeat implements CookStrategy {
        public static final String BRAISEMEAT="   ";
        @Override
         /**
         *           
         * @param feelings
         */
        public void cook(String feelings) {
              System.out.println(" "+feelings+"   ,"+"     "+BRAISEMEAT);
        }
    }
    
    

    最後に、もう一つのMeatクラスを作成します.
    public class Meat {
        public static final String HAPPY="  ";
        public static final String SAD="  ";
        /**
         *   CookStrategy  
         */
        private CookStrategy mCookStrategy;
        public static void main(String[] args) {
            Meat meat=new Meat();
            meat.setCookStrategy(new CookBraiseMeat());
            meat.cookFood(SAD);
        }
    
        /**
         *          mCookStrategy,          。
         * @param cookStrategy
         */
        private void setCookStrategy(CookStrategy cookStrategy) {
            mCookStrategy=cookStrategy;
        }
        private void cookFood(String feelings){
            mCookStrategy.cook(feelings);
        }
    
    }
    

    さいごぶんせき
    前後のコードを改善することで、次のことがわかります.
  • 前者:if-elseによって問題を解決し、コードが肥大化し、論理が複雑で、アップグレードとメンテナンスが困難で、構造がない
  • 後者:インタフェースを確立することによって、異なるポリシーを具体的なポリシー実装に構築し、異なるポリシー実装アルゴリズムの置換を実現することによって、拡張性、直感性をよりよく増加させる.

  • 結論と使用シーン
  • 同じタイプの問題に対して、多種の処理は、具体的には行に差がある(肉を焼く、豚肉を蒸す)
  • だけである.
  • 同じ抽象クラスに複数のサブクラスが出現し、if-elseまたはswitch-caseを用いてサブクラスを選択する(ルームメイトの気持ちで肉を作る)
  • 同じ種類の操作を安全に封入する必要がある場合(肉を焼いたり、豚肉を蒸したりする場合)
  • .
    私の友达が好きで、私と一绪に问题を讨论することができて、私も学习者で、大学と一绪に勉强することを望みます.