美文网首页
2018-01-12

2018-01-12

作者: 无尽迷茫 | 来源:发表于2018-01-12 13:47 被阅读0次

    java设计模式(二) 建造者模式

    miss2008

    关注

    2017-10-02 10:24 · 字数 531 · 阅读 172 ·  Java设计模式

    建造者模式一句话概括:

    将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建出不同的表示。

    --. 定义要点分析

    1,模式功能:最终目的是为了建造一个对象Product,在对象构建时才会使用建造者模式。

    2,复杂对象:我们要创建的对象是复杂的,所以内部细节会很繁琐,需要把对象各个组成部分封装处理。

                当对象构建过程简单时,别滥用这个设计模式。

    3,构建和表示分离:对象的构建细节和最终表示解耦,即需要一个建造者Builder,只负责对象的每个组成的

                内部实现,还需要有一个导演者Director,通过Builder把对象按步骤拼装起来。

    4,“相同”的构建过程,不同的表示:一个复杂对象,建造过程相同,但是建造的每一步的内部细节实现不同,

                产生出不同的对象表示。实际场景里,相同的构建方法,不同的组装顺序,产生不同的结果也会

                使用建造者模式,这个相同更多的体现在产品的组成相同,即Builder里的方法相同

    举例:安卓App的开发过程,App就是需要生产的产品,有不同的App如QQ和微信,各种App内部细节是不同的

        ,但是app需要在安卓系统中存在并运行,其组成是相同(界面,数据,缓存...)。

    --. 建造者模式基本类图如下:

    建造者模式类图.png

    --. 建造者的基本使用(以上面app开发为例)

    抽象建造者,规范app的组成

    public interface IAppBuilder {

        public void addView();

        public void addData();

        public void addCache();

        public App buildProduct();

    }

    抽象app产品,因为要制造不同的app

    public abstract class App {

        public String view;

        public String data;

        public String cache;

        public String getView() {return view;}

        public void setView(String view) { this.view = view;}

        public String getData() {return data;}

        public void setData(String data) {this.data = data;}

        public String getCache() {return cache;}

        public void setCache(String cache) {this.cache = cache;}

    }

    public class Qq extends App {}

    public class Weixin extends App {}

    具体构建者(只展示QQ构建者,微信类似)

    public class QqBuilder implements IAppBuilder {

        private final App app;

        public QqBuilder() {app = new Qq();}

        @Override

        public void addView() {app.setView("QQ界面");}

        @Override

        public void addData() {app.setData("QQ数据");}

        @Override

        public void addCache() {app.setCache("QQ缓存");}

        @Override

        public App buildProduct() {return app;}

    }

    导演

    public class Director {

        public IAppBuilder appBuilder;

        public Qq buildQq() {

            appBuilder = new QqBuilder();

            appBuilder.addView();

            appBuilder.addData();

            appBuilder.addCache();

            return (Qq) appBuilder.buildProduct();

        }

        public Weixin buildWeixin() {

            appBuilder = new WeixinBuilder();

            appBuilder.addView();

            appBuilder.addData();

            appBuilder.addCache();

            return (Weixin) appBuilder.buildProduct();

        }

    }

    --. 复杂的建造者模式

    在实际开发中,Director往往被忽视,大家习惯直接用Builder来进行对象的组装,这个Builder通常为链式调用,即每个组装方法里都返回自身(return this),这样既简化了结构,也使组装过程更清晰。

    Product product = new Builder().setA().setB().build();

    类图大致如下

    复杂的建造者模式.png

    去除Director,上面样例Builder改为如下

    public class QqBuilder implements IAppBuilder {

        private final App app;

        public QqBuilder() { app = new Qq();}

        @Override

        public IAppBuilder addView() {

            app.setView("QQ界面");

            return this;

        }

        @Override

        public IAppBuilder addData() {

            app.setData("QQ数据");

            return this;

        }

        @Override

        public IAppBuilder addCache() {

            app.setCache("QQ缓存");

            return this;

        }

        @Override

        public App buildProduct() {

            return app;

        }

    }

    --. 框架里的建造者模式(Retrofit为例)

    在常用框架里,会对建造者模式的结构进一步简化,把构建者直接放到生产的产品Product里,作为一个抽象内部类。

    Prodect product = new Product.Builder().setA().setB().build();

    框架建造者.png

    Retrofit是网络调度层框架,调用网络执行层框架Okhttp完成网络请求,封装线程切换,数据转换等功能,下面简化代码可以看到,在Builder里传入路径、Httpclient、响应方式、数据转换器等完成Retrofit的构建。

    public final class Retrofit {

        final okhttp3.Call.Factory callFactory;

        final HttpUrl baseUrl;

        final List<Converter.Factory> converterFactories;

        final List<CallAdapter.Factory> adapterFactories;

        final @Nullable

        Executor callbackExecutor;

        final boolean validateEagerly;

        Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,

                List<Converter.Factory> converterFactories, List<CallAdapter.Factory>

                adapterFactories,

                @Nullable Executor callbackExecutor, boolean validateEagerly) {

            this.callFactory = callFactory;

            this.baseUrl = baseUrl;

            // Defensive copy at call site.

            this.converterFactories = unmodifiableList(converterFactories);

            // Defensive copy at call site.

            this.adapterFactories = unmodifiableList(adapterFactories);       

            this.callbackExecutor = callbackExecutor;

            this.validateEagerly = validateEagerly;

        }

        public okhttp3.Call.Factory callFactory() {

            return callFactory;

        }

        public HttpUrl baseUrl() {

            return baseUrl;

        }

        ...

        /**

        * Build a new {@link Retrofit}.

        * <p>

        * Calling {@link #baseUrl} is required before calling {@link #build()}. All

        * other methods are optional.

        */

        public static final class Builder {

            private final Platform platform;

            private @Nullable okhttp3.Call.Factory callFactory;

            private HttpUrl baseUrl;

            private final List<Converter.Factory> converterFactories

                                      = new ArrayList<>();

            private final List<CallAdapter.Factory> adapterFactories

                                      = new ArrayList<>();

            private @Nullable Executor callbackExecutor;

            private boolean validateEagerly;

            public Builder() {

                this(Platform.get());

            }

            public Builder client(OkHttpClient client) {

                return callFactory(checkNotNull(client, "client == null"));

            }

            public Builder callFactory(okhttp3.Call.Factory factory) {

                this.callFactory = checkNotNull(factory, "factory == null");

                return this;

            }

            public Builder baseUrl(String baseUrl) {

                HttpUrl httpUrl = HttpUrl.parse(baseUrl);

                return baseUrl(httpUrl);

            }

            public Builder addConverterFactory(Converter.Factory factory) {

                converterFactories.add(checkNotNull(factory, "factory == null"));

                return this;

            }

            public Builder addCallAdapterFactory(CallAdapter.Factory factory) {

                adapterFactories.add(checkNotNull(factory, "factory == null"));

                return this;

            }

            public Builder callbackExecutor(Executor executor) {

                this.callbackExecutor = checkNotNull(executor, "executor == null");

                return this;

            }

            public Builder validateEagerly(boolean validateEagerly) {

                this.validateEagerly = validateEagerly;

                return this;

            }

            public Retrofit build() {

                return new Retrofit(callFactory, baseUrl, converterFactories

                        , adapterFactories,callbackExecutor, validateEagerly);

            }

        }

    }

    总结:

    建造者模式是一种对象构建的模式,它侧重对象组件的封装和装配顺序,在我们开发过程中,链式结构的用法在外形上更能体现这个模式,不过当产品组成部分过多时,还是使用Director更符合单一职责功能,Director也能起一层封装作用,避免高层代码接触内部细节。

    其他模式链接如下:

    java设计模式(一) 观察者模式

    java设计模式(三) 代理模式

    相关文章

      网友评论

          本文标题:2018-01-12

          本文链接:https://www.haomeiwen.com/subject/klkfoxtx.html