【设计模式】- Builder(构建者)模式

简介

当我们在构建一个复杂的对象时,想要把对象的构建和表现分离开来,那么就可以使用Builder模式。比如:构建一台汽车,组成汽车的部件有很多,像轮胎,发动机,座位等。当具备所以的零部件后,我们组装好汽车。那么汽车能干什么,有怎样的表现,显然,汽车能够以一定速度行驶。那么怎么才能让汽车行驶呢?点火->给油->发动机输出动力等等。这个是汽车能够行驶起来需要做的。所以在构建复杂对象过程,为了使构建和表现过程分离,那么可以使用Builder模式。使得构建过程和表现过程都可以自由扩展。

why

为什么构建复杂对象,要用Builder模式呢?我创建一个对象,然后向里面设置属性不也可以吗?为什么非要多出一个Builder类来实现,不是多增加代码吗?

这种想法没有什么不对,但是从代码的清晰堵和扩展性,维护性上看,其实还是有很大不同的,可能对于不是非常复杂的对象,没有什么感觉,当你构建的对象越来越复杂,你会发现它的好处。

其实很大讲设计模式,都会列出几条使用场景,当我不太喜欢,规则是死的,其实我们更应该从单一职责,扩展性,可维护性,解耦合,封闭性,替换难易等来考虑怎么书写代码。

UML

Builder模式.png

举例


public class ExtWebAgent {
    private WebSettings mWebSettings;
    private ExtWebViewClient mWebViewClient;
    private ExtWebChromeClient mWebChromeClient;
    private ExtWebView mWebView;
    private Context mContext;
    private IExtJavascriptInterface mJavascriptInterface;
    private IExtWebViewProgress mExtWebViewProgress;
    private String mJifName;
    IExtCallBack mScrollChangeListener;
    private ExtWebAgent(Builder builder, boolean isCache) {this(builder);}
    public ExtWebAgent(Builder builder) {
        mContext = builder.context;
        mWebView = builder.webView;
        mWebChromeClient = builder.webChromeClient;
        mWebViewClient = builder.webViewClient;
        mJavascriptInterface = builder.javascriptInterface;
        mJifName = builder.jifName;
        mWebView.configWebViewClient(mWebViewClient);
        mWebView.configWebChromeClient(mWebChromeClient
                .addExtWebViewProgress(mExtWebViewProgress)
        mWebView.configOnScrollChanged(mScrollChangeListener);
        if (null != mJavascriptInterface) {
            mWebView.configJavascriptInterface(mJavascriptInterface, mJifName);
            mJavascriptInterface.bindWebView(mWebView);
        }
        mWebView.setDownloadListener(ExtWebDownLoadListener.instance());
        mWebSettings = mWebView.getSettings();
    }
    public static Builder builder(Context context, IExtWebCallback callback) {
        return new Builder(context, callback);
    }
    public static class Builder {
        ExtWebViewClient webViewClient;
        ExtWebChromeClient webChromeClient;
        ExtWebView webView;
        Context context;
        IExtJavascriptInterface javascriptInterface;
        String jifName = "native";
        String cacheBuilderId = "";
        Builder(Context context, IExtWebCallback callback) {
            if (!(context instanceof Activity || context instanceof Application))
                throw new IllegalArgumentException("context is not Activity or Application");
            this.context = context;
            webChromeClient = new ExtWebChromeClient(cacheBuilderId);
            javascriptInterface = new ExtJavaScriptInterfaceIml(cacheBuilderId);
            webViewClient = new ExtWebViewClient(cacheBuilderId);
        }
        public Builder setWebViewClient(ExtWebViewClient wvc) {
            webViewClient = null == wvc ? webViewClient : wvc;
            return this;
        }
        public Builder setChromeClient(ExtWebChromeClient wcc) {
            webChromeClient = null == wcc ? webChromeClient : wcc;
            return this;
        }
        public Builder addJavascriptInterface(IExtJavascriptInterface jif) {
            addJavascriptInterface(jif, jifName);
            return this;
        }
        public Builder addJavascriptInterface(IExtJavascriptInterface jif, String jifName) {
            this.jifName = TextUtils.isEmpty(jifName) ? this.jifName : jifName;
            javascriptInterface = null == jif ? javascriptInterface : jif;
            return this;
        }
        public Builder bindActAndFrag(String key, IExtWebCallback callback) {
            if (null == callback) {
                throw new IllegalArgumentException("callback is null");
            }
            ExtWebViewCallbackManager.instance().bindActAndFrag(key, callback);
            return this;
        }
        public Builder setWebView(ExtWebView wv) {
            webView = wv;
            context = wv.getContext();
            return this;
        }
        public ExtWebAgent build() {
            return new ExtWebAgent(this);
        }
    }
}

源码中的Builder模式

AlertDialog.Builder就是典型的Builder模式。这里不贴代码了,来个UML图。


Builder模式 - AlertDialog.png

AlertDialog.Builder负责组装,构建。AlertDialog持有AlertController对象,Dialog相关的操作,UI的更新都可以通过它来控制,这样相当于把Dialog的具体表现抽离出来,AlertDialog继承于Dialog,里面负责一些事件,状态等任务。

常用的第三方框架

像Retrofit,okhttp等里面都用到的Builder模式,其用法和上面举例的一样。这个模式暂时没有想到其它变种写法。

自己的一点理解

其实Builder模式,简单点描述就是一个具体对象里面包含了一个用于收集构建对象所需要的材料,当收集好后,将其组装起来,形成具有一定表现的对象。至于这个对象怎样表现出具有的功能,那么就是对象自己实现了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容