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

作者: miss2008 | 来源:发表于2017-10-02 10:24 被阅读233次

建造者模式一句话概括:

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

--. 定义要点分析

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设计模式(三) 代理模式

相关文章

  • 设计模式

    Java 设计模式情景分析 ——单例模式 Java 设计模式情景分析——建造者模式 Java 设计模式情景分析——...

  • Android中涉及的模式

    我的Java设计模式-建造者模式 我的Java设计模式-观察者模式 重学设计模式之单例模式

  • Java设计模式教程

    Java设计模式教程 Java工厂设计模式 Java抽象工厂模式 Java单例模式 Java建造者(Builder...

  • java建造者模式

    其他设计模式java单例模式java建造者模式java策略模式java代理模式java观察者模式java适配器模式...

  • java单例模式

    其他设计模式java单例模式java建造者模式java策略模式java代理模式java观察者模式java适配器模式...

  • java外观模式

    其他设计模式java单例模式java建造者模式java策略模式java代理模式java观察者模式java适配器模式...

  • java适配器模式

    其他设计模式java单例模式java建造者模式java策略模式java代理模式java观察者模式java适配器模式...

  • java观察者模式

    其他设计模式java单例模式java建造者模式java策略模式java代理模式java观察者模式java适配器模式...

  • java代理模式

    其他设计模式java单例模式java建造者模式java策略模式java代理模式java观察者模式java适配器模式...

  • java策略模式

    其他设计模式java单例模式java建造者模式java策略模式java代理模式java观察者模式java适配器模式...

网友评论

    本文标题:java设计模式(二) 建造者模式

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