Android内功心法(1.2)-android常用設計モデルの工場モデル


下一篇:Android内功心法(1.1)-android常用設計モードの単例モードでは、古典的な単例書き方とjava 5以降の最適な書き方を含むいくつかの単例モードと現在の最高の単例モード実現方法について述べた.
今日は工場モードについてお話しします.工場は多くの共通インタフェースを持つクラスをインスタンス化する責任を負っている.ファクトリモードでは、どのクラスをインスタンス化するかを決定できます.毎回どのクラスをインスタンス化するかを事前に知る必要はありません.工場モデルの使用には、簡単な工場(静的工場)、工場方法、抽象的な工場、工場+戦略がたくさんあります.今日は一つ一つ説明します.
1、簡易工場
/** *           */
public  class Operation {

    private double numberA;//       
    private double numberB;//       

    public double getNumberA() {
        return numberA;
    }

    public void setNumberA(double numberA) {
        this.numberA = numberA;
    }

    public double getNumberB() {
        return numberB;
    }

    public void setNumberB(double numberB) {
        this.numberB = numberB;
    }

    /**          * @return              ,        */
    public double getResult(){
        return 0;
    }
}

これは単純な工場モデルのベースクラスであり、すべての拡張または処理が必要なクラスはそれに依存しなければならない.
/** *    */
public class OperationAdd extends Operation {

    /**       * @return */
    @Override
    public double getResult() {
        return getNumberA()+getNumberB();
    }
}

/** *    */
public class OperationSub extends Operation {

    /**       * @return */
    @Override
    public double getResult() {
        return getNumberA()-getNumberB();
    }
}

/** *    */
public class OperationMul extends Operation {

    /**       * @return */
    @Override
    public double getResult() {
        return getNumberA()*getNumberB();
    }
}

/** *    */
public class OperationDiv extends Operation {

    /**       * @return */
    @Override
    public double getResult() {
        if(getNumberB()==0)return 0;
        return getNumberA()/getNumberB();
    }
}

加減乗除は4つのクラスで、私はコードブロックに統一的に書いただけで、この4つのクラスが一緒にいるわけではありません.
加減乗除の4つのクラスは,単純工場のベースクラスを継承している.すなわち,2つのパラメータを持つget/setメソッドと演算結果メソッドのOperationクラスである.
/** *          */
public class OperationFactory {
    public static Operation createOperation(String operate) {

        Operation operation;
        switch (operate) {
            case "+":
                operation = new OperationAdd();
                break;
            case "-":
                operation = new OperationSub();
                break;
            case "*":
                operation = new OperationMul();
                break;
            case "/":
                operation = new OperationDiv();
                break;
            default:
                operation = null;
                break;
        }
        return operation;
    }
}

このクラスの役割は論理を処理することです.ユーザが入力した記号(+-*/)に基づいて対応する論理を処理する.
/** *            */
public class OperationTest {
    /**        : *       , *      ,  ,  。 *          ,       * *                     *           *            ,            * *             *       ,                 ,        *                     * */
    private Operation operation;

    public void testAdd() {//+
        operation = OperationFactory.createOperation("+");
        operation.setNumberA(1);
        operation.setNumberB(2);
        Log.e("test", "          (+):" + operation.getResult());
    }

    public void testDiv() {///
        operation = OperationFactory.createOperation("/");
        operation.setNumberA(1);
        operation.setNumberB(2);
        Log.e("test", "          (/):" + operation.getResult());
    }

    public void testMul() {//*
        operation = OperationFactory.createOperation("*");
        operation.setNumberA(1);
        operation.setNumberB(2);
        Log.e("test", "          (*):" + operation.getResult());
    }

    public void testSub() {//-
        operation = OperationFactory.createOperation("-");
        operation.setNumberA(1);
        operation.setNumberB(2);
        Log.e("test", "          (-):" + operation.getResult());
    }
}

この加減乗除した栗により、シンプルな工場モードの良さがわかります.単純なファクトリモードを使用しない場合は、4つの論理を実現し、大量のコードを繰り返す必要があります.後期の開拓もメンテナンスもやりにくい.単純なファクトリモードで処理したコードでは,論理がはっきりしていることがわかる.モジュール演算などの新しい機能を追加するには、次のコードを追加する必要があります.
/** *     */
public class OperationMi extends Operation {

    /**       * @return */
    @Override
    public double getResult() {
        return getNumberA()%getNumberB();
    }
}

これで、「新機能」が書き終わりました.新しい機能は元の機能に影響を与えず、工場のベースクラスを変更しなかった.
新しい機能を使うには、Operationのswitchメソッドに追加するだけです.
 case "%":
    operation = new OperationMi();
    break;

どうですか.開拓性がよく、デザインモデルの「最小限の原則」に従っているのではないでしょうか.クラス間ではまったく通信していない
これが単純工場または静的工場モードです.書くのが簡単で、使いやすいデザインです.
しかし、このデザインモデルにも欠点があります.古典的な24種類の設計モードの1つとしても否定されることが多い.その欠点は「開閉の原則」に従わなかったことだ.拡張オープンはできましたが、変更はオフになりませんでした.工場を追加するたびに、OperationFactoryクラスのcreateOperationメソッドにcaseメソッドを追加します.これでコードが変更されました.したがって、単純な工場モデルは設計モデルの「要求」に合致しないべきである.
では、単純工場はさらに最適化することができます.次のコードは、単純な工場とポリシーモデルを混合して運用します.簡単な工場の使い方をさらに最適化したと言える.
2、単純工場+戦略
単純ファクトリのコードを借りて、単純ファクトリのベースクラスをポリシーモードのベースクラスに変更します.
/* *         */
public abstract class Strategy {
    /**             */

    private double numberA;//       
    private double numberB;//       

    public double getNumberA() {
        return numberA;
    }

    public void setNumberA(double numberA) {
        this.numberA = numberA;
    }

    public double getNumberB() {
        return numberB;
    }

    public void setNumberB(double numberB) {
        this.numberB = numberB;
    }

    /** *      */
    public abstract double GetResultInterface(double a,double b);
}

抽象的なクラスであることがわかります.操作が簡単な工場のクラスは次のように変更されます.
public class ConcreteStrategy {
    /**    +       *                      *       ,         。 *         *                          * */
    private Strategy strategy;

    /** *              * * @param i     :     */
    public ConcreteStrategy(String i) {
        switch (i) {
            default:
            case "+":
                strategy=new ConcreteStrategyA("+");
                break;
            case "-":
                strategy=new ConcreteStrategyB("-");
                break;
            case "*":
                strategy=new ConcreteStrategyC("*");
                break;
            case "/":
                strategy=new ConcreteStrategyD("/");
                break;
        }
    }

    /** *       ,                 */
    public void contextInterface(double a,double b) {
        strategy.GetResultInterface(a,b);
    }
}

アルゴリズムロジック実装クラス
/* *    */
public class ConcreteStrategyA extends Strategy {

    private String status;

    public ConcreteStrategyA(String status) {
        this.status= status;
    }

    /** *   A    */
    @Override
    public double GetResultInterface(double a,double b) {
        if(status.equals("+"))
        return a+b;
        return 0;
    }
}

次に、ポリシーの実装クラスを示します.
public class StrategyTest {
    private ConcreteStrategy concreteStrategy;

    /**       * @param i */
    public void StrategyTest(String i) {
        concreteStrategy = new ConcreteStrategy(i);
    }

    /**     * @param money */
    public void getResult(double a,double b) {
        concreteStrategy.contextInterface(a,b);
    }
}

単純な工場+戦略モデルは、単純な工場をより柔軟にすることができます.複数のクラスを作成およびインスタンス化する必要はありません.結果を得るには、newがConcreteStrategyオブジェクトを1つ出すだけで、対応する計算モードを考えて、contextInterfaceメソッドを呼び出し、計算する値を入力すれば、所望の結果を得ることができます.
簡単な工場を比較してみましょう
        operation = OperationFactory.createOperation("-");
        operation.setNumberA(1);
        operation.setNumberB(2);
        operation.getResult();//    

単純な工場+ポリシー
concreteStrategy = new ConcreteStrategy("+");
concreteStrategy.contextInterface(1,2);//    

コードで一目瞭然です.単純ファクトリ+ポリシーモードのコードは単純単純ファクトリモードよりずっと簡単です.これがモードの組合せ運用によりコードを簡略化する方法である.
では、次はこのような工場が簡単な工場の欠点を補うことができます.
3、工場方法モデル
上の簡単な工場のコードを借りて書きます.
まず工場メソッドクラスのインタフェースを書きます
public interface IFactory {

    //        
    Operation createOperation();
}

アルゴリズムの具体的な工場クラスを書きます
 *       
 */
public class ConcreteFactoryA implements IFactory {

    //     

    @Override
    public Operation createOperation() {
        return new OperationAdd();
    }
}

public class ConcreteFactoryB implements IFactory {

    //     

    @Override
    public Operation createOperation() {
        return new OperationSub();
    }
}

public class ConcreteFactoryC implements IFactory {

    //     

    @Override
    public Operation createOperation() {
        return new OperationMul();
    }
}

public class ConcreteFactoryD implements IFactory {

    //     

    @Override
    public Operation createOperation() {
        return new OperationDiv();
    }
}

上の単純工場のベースクラスOperationや論理クラスOperationAddなどを加える
工場の方法類を構成しました.
使用方法:
private void testAdd() {
        IFactory iFactory = new ConcreteFactoryA();//       
        Operation operation = iFactory.createOperation();//          
        operation.setNumberA(1);
        operation.setNumberB(2);
        operation.getResult();
    }

こうなると.論理クラスを追加すると追加されます.
public class OperationMi extends Operation {

    /**       * @return */
    @Override
    public double getResult() {
        return getNumberA()%getNumberB();
    }
}

モールド演算のファクトリクラスを追加するには、次の手順に従います.
public class ConcreteFactoryE implements IFactory {

    //     

    @Override
    public Operation createOperation() {
        return new OperationMi();
    }
}

これで2つの設計モデルの原則が達成されたように見えます.「少なくとも原則を知っている」と「開閉原則」.
「少なくとも原則を知る」ことは簡単な工場で実現した.「開閉原則」は工場インタフェースと工場クラスを利用して実現した.
これにより,最後に新しい論理演算を追加してもコードを修正することなく,それに対応して新しい論理の具体的なファクトリクラスを追加する.
ファクトリメソッドモードは、iangdインタフェースを作成してサブクラスにインスタンス化するクラスを決定するために使用されるクラスを定義します.
もちろん,「単純ファクトリ+ポリシーモデル」を理解したプログラマーたちも自然に「ファクトリメソッド+ポリシー」の組合せコードを作ることができる.
通常、大きな変更に直面しています.多くの工場やメソッドクラスを追加する必要がある場合、1つのメソッド1つのクラスを追加することは明らかではありません.この時、私たちはもっと簡単で便利な方法が必要です.
3、抽象工場モデル
抽象工場の実現が面倒でコード量が多いので、わざわざ1章を出して抽象工場を書きます.抽象工場を見る必要があるプログラマーたちは私の次の連載を見ることができます.Android内功心法(1.2.1)-android常用設計モデルの工場モデル後続抽象工場モデル