Androidシステムプログラミング思想編:作成者モード


Androidシステムプログラミング思想編:作成者モード
作者:郭孝星メールボックス:[email protected]ブログ:http://blog.csdn.net/allenwells 略書:http://www.jianshu.com/users/66a47e04215b/latest_アートレス
作者について
郭孝星、有名なプログラマーではなく、コード潔癖症の患者さん、プログラミングが好きで、ギターが好きで、料理が好きで、すべての面白いものと人が好きです.
文章について
著者の文章はGithub、CSDN、略書に同時に掲載されます.文章の上部にも記事のGithubリンクが添付されます.もし文章の中に何か質問があったら、メールで私と交流してください.コミュニケーションの問題について、問題をはっきり説明してください.コードと日記を添付してください.文章に何か間違いがあったら、斧も歓迎します.もしあなたがこの文章があなたの役に立つと思ったら、star文章にも行ってください.文章の最新の動きに注目してください.また、皆さんにGithubに行って文章を読むように勧めます.一方で文章の作成は全部Githubで行われています.だからGithubの更新は一番タイムリーです.一方、GithubはMarkdownに対する支持がもっといいと感じています.文章のレンダリングももっと美しいです.
記事ディレクトリ:https://github.com/guoxiaoxing/android-open-source-project-analysis/blob/master/README.md
作成者モードは作成モードの一種であり、ユーザーが内部構築の詳細を知らない場合、より微細な制御対象の構造フローを可能にする.このモードは、複雑なオブジェクトを構成するプロセスとそのコンポーネントを結合するために、構築されたプロセスとコンポーネントの表現を分離する.
パターン定義
複雑なオブジェクトの構築は、同じ構築プロセスが異なる表現を作成することができるように、その表現から分離される.
パターンの役割
Product:      
Builder:  Builder ,      ,             
ConcreteBuilder:   Builder 
Director:      
使用シーン
1      ,       ,         。
2         ,            ,            。
3           ,   ,        。
長所
1                 ,               ,                    。
2              ,            ,                         ,                       。
3                 ,                   ,          ,               。
4                     ,              ,      ,  “    ”。
欠点
1                      ,       ,            ,           ,              。
2            ,                        ,         。
また、以下の場合は、モード簡略化処理を行うことができる.
抽象的な建築者の役割を省略します.システムの中で具体的な建築者だけが必要なら、抽象的な建築者は省略できます.指挥者の役割を省略します.具体的な建筑者が一つしかない场合、抽象的な建筑者の役割が省略されたら、指挥者の役割を省略して、Bulder役に指挥者と建筑者の二重の役割を演じさせます.
パターン実現
まず、完全な建設者モードの実現を見てみましょう.
抽象的な製品の役割
package com.guoxiaoxing.android.sdk.design.builder.whole;

/**
 *       ,            。
 * 

* For more information, you can visit https://github.com/guoxiaoxing or contact me by * [email protected] * * @author guoxiaoxing * @since 2017/3/23 10:13 */

public abstract class AbstractProduct { private String board; private String display; private String os; public void setBoard(String board) { this.board = board; } public void setDisplay(String display) { this.display = display; } public abstract void setOs(String os); }
具体的な製品の役割
package com.guoxiaoxing.android.sdk.design.builder.whole;

/**
 *       ,            
 * 

* For more information, you can visit https://github.com/guoxiaoxing or contact me by * [email protected] * * @author guoxiaoxing * @since 2017/3/23 10:06 */

public class RealProduct extends AbstractProduct { @Override public void setOs(String os) { os = "mac osx"; } /** * , , */ public static class RealProductParams { public String board; public String display; public String os; public void applyParams(RealProduct product) { product.setBoard(board); product.setDisplay(display); product.setOs(os); } } }
抽象クリエーターの役割
package com.guoxiaoxing.android.sdk.design.builder.whole;

/**
 *        ,      ,          。
 * 

* For more information, you can visit https://github.com/guoxiaoxing or contact me by * [email protected] * * @author guoxiaoxing * @since 2017/3/22 6:27 */

public abstract class AbstractBuilder { public abstract void setBoard(String board); public abstract void setDisplay(String display); public abstract void setOs(String os); }
具体的な建築者の役割
package com.guoxiaoxing.android.sdk.design.builder.whole;

/**
 *        ,        。         ,  build()        。
 * 

* For more information, you can visit https://github.com/guoxiaoxing or contact me by * [email protected] * * @author guoxiaoxing * @since 2017/3/23 10:11 */

public class RealBuilder extends AbstractBuilder { private RealProduct.RealProductParams productParams; public RealBuilder() { productParams = new RealProduct.RealProductParams(); } @Override public void setBoard(String board) { productParams.board = board; } @Override public void setDisplay(String display) { productParams.display = display; } @Override public void setOs(String os) { productParams.os = os; } public RealProduct build() { RealProduct product = new RealProduct(); productParams.applyParams(product); return product; } }
指揮者役
package com.guoxiaoxing.android.sdk.design.builder.whole;

/**
 *      ,             ,                。
 * 

* For more information, you can visit https://github.com/guoxiaoxing or contact me by * [email protected] * * @author guoxiaoxing * @since 2017/3/23 10:18 */

public class Direactor { private AbstractBuilder builder; public void setBuilder(AbstractBuilder builder) { builder = builder; } private void buildProduct(String board, String display, String os) { builder.setBoard(board); builder.setDisplay(display); builder.setOs(os); } }
日常プログラミングの中で、私達の建築者は通常一つしかないです.この時は簡単版の建築者モードを使ってもいいです.
package com.guoxiaoxing.android.sdk.design.builder.simple;

/**
 *                  ,          。              ,              
 *  ,            , Builder               。
 * 

* For more information, you can visit https://github.com/guoxiaoxing or contact me by * [email protected] * * @author guoxiaoxing * @since 2017/3/23 10:05 */

public class Product { public String board; public String display; public String os; class Builder { private Product product; public Builder() { product = new Product(); } private String board; private String display; private String os; public void setBoard(String board) { product.board = board; } public void setDisplay(String display) { product.display = display; } public void setOs(String os) { product.os = os; } } }
モデル実践
また見てみます.私たちが普段見た種類の倉庫にはどのような建築者モデルの具体的な実践がありますか?
最も一般的なのはAlertDialogでしょう.AlertDialogを作成する過程で
AlertDialog:Buiderクラスを内蔵し、パラメータ構築を完了します.
AlertController:AlertDialogのエージェントクラスは、具体的な構築プロセスを完了し、AlertParamsクラスを内蔵し、Buiderクラスから渡されるパラメータはいずれもAlertParamsに設定されます.
AlertDialog内部起動ロジック
Alert Controller内部起動ロジック
はい、AlertDialogの具体的な構築プロセスを見てみます.
1 Buiderを呼び出し、パラメータを構築します.
public class Demo{
    AlertDialog dialog = new AlertDialog.Builder(context)
        .setTitle("  ")
        .setMessage("  ")
        .create();
}
2 create()方法を呼び出して、AlertDialogの例を作成し、同時にAlertControllerの例を作成し、Buider内のパラメータはAlertParaamsに伝達された.
public class AlertDialog extends Dialog implements DialogInterface {

    protected AlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
        super(context, com.android.internal.R.style.Theme_Dialog_Alert);
        setCancelable(cancelable);
        setOnCancelListener(cancelListener);
        mAlert = new AlertController(context, this, getWindow());
    }

    public AlertDialog create() {
        final AlertDialog dialog = new AlertDialog(P.mContext);
        P.apply(dialog.mAlert);
        dialog.setCancelable(P.mCancelable);
        dialog.setOnCancelListener(P.mOnCancelListener);
        if (P.mOnKeyListener != null) {
            dialog.setOnKeyListener(P.mOnKeyListener);
        }
        return dialog;
    }

}
3 appy()メソッドを呼び出し、Dialogの作成、設定ボタンの傍受、文字などを実行します.
public static class AlertParams {

    public void apply(AlertController dialog) {
        if (mCustomTitleView != null) {
            dialog.setCustomTitle(mCustomTitleView);
        } else {
            if (mTitle != null) {
                dialog.setTitle(mTitle);
            }
            if (mIcon != null) {
                dialog.setIcon(mIcon);
            }
            if (mIconId >= 0) {
                dialog.setIcon(mIconId);
            }
        }
        if (mMessage != null) {
            dialog.setMessage(mMessage);
        }
        if (mPositiveButtonText != null) {
            dialog.setButton(DialogInterface.BUTTON_POSITIVE, mPositiveButtonText,
                    mPositiveButtonListener, null);
        }
        if (mNegativeButtonText != null) {
            dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mNegativeButtonText,
                    mNegativeButtonListener, null);
        }
        if (mNeutralButtonText != null) {
            dialog.setButton(DialogInterface.BUTTON_NEUTRAL, mNeutralButtonText,
                    mNeutralButtonListener, null);
        }
        if (mForceInverseBackground) {
            dialog.setInverseBackgroundForced(true);
        }
        // For a list, the client can either supply an array of items or an
        // adapter or a cursor
        if ((mItems != null) || (mCursor != null) || (mAdapter != null)) {
            createListView(dialog);
        }
        if (mView != null) {
            if (mViewSpacingSpecified) {
                dialog.setView(mView, mViewSpacingLeft, mViewSpacingTop, mViewSpacingRight,
                        mViewSpacingBottom);
            } else {
                dialog.setView(mView);
            }
        }

        /*
        dialog.setCancelable(mCancelable);
        dialog.setOnCancelListener(mOnCancelListener);
        if (mOnKeyListener != null) {
            dialog.setOnKeyListener(mOnKeyListener);
        }
        */
    }

}
以上はAlertDialog徳の作成過程であり、総合的にプロキシモードとクリエーターモードを使用していることが分かります.クリエート()メソッドが呼び出された時にオブジェクトが作成されました.
実際には、Bulderは、作成時にAlertParaamsの例を作成しただけで、AlertDialogを作成していません.このような書き方も怠惰な負荷の一つの表現であり、資源の節約に役立ちます.

public static class Builder {

    private final AlertController.AlertParams P;

    public Builder(@NonNull Context context, @StyleRes int themeResId) {
        P = new AlertController.AlertParams(new ContextThemeWrapper(
                context, resolveDialogTheme(context, themeResId)));
        mTheme = themeResId;
    }
}
以上はAndroidシステムの中で建設者のモードに対する応用で、この実践の中で抽象的な製品の役、指揮者の役がないことを発見することができて、これはAndroidが建築者のモードの1種の簡略化に対してで、後続の読むソースコードの過程の中でまた多くのこのような簡略化と融通がきかないことを発見して、決まりの標準によって実現するのではありません.これはまさにプログラミングの魅力です.土地によって、変化に富んでいます.
Android系统编程思想篇:建造者模式_第1张图片
Dialogのさらなる内容とWindowManagerなどの関連原理については、ここではもうこれ以上展開しません.後続のAndroidソース分析シリーズの文章の中でさらに詳しく分析します.