专栏首页程序员小灰漫画:什么是 “建造者模式” ?

漫画:什么是 “建造者模式” ?

————— 第二天 —————

————————————

首先,我们来定义一个Product类:

public class Product {
    ArrayList<String> parts = new ArrayList<String>();

    public void add(String part) {
        parts.add(part);
    }

    public void show() {
        System.out.println(parts);
    }
}

接下来,我们定义抽象的Builder类:

public abstract class Builder {
    public abstract void buildPartA();
    public abstract void buildPartB();
    public abstract Product getResult() ;
}

然后,是具体的Builder实现类:

public class ConcreteBuilder extends Builder {
    private Product product = new Product();
    public Product getResult() {
        return product;
    }
    @Override
    public void buildPartA() {
        product.add("构建产品的上半部分");
    }

    @Override
    public void buildPartB() {
        product.add("构建产品的下半部分");
    }
}

在Builder类之外,则是Director类来控制Builder的生产过程:

public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public void construct() {
        builder.buildPartA();
        builder.buildPartB();
    }
}

最后,是客户端的测试代码:

Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
director.construct();
Product product = builder.getResult();
product.show();

我们来看一下运行的结果:

[构建产品的上半部分, 构建产品的下半部分]
// 默认采用Builder进行建造
public OkHttpClient() {
  this(new Builder());
}

// 由builder配置分发器、代理、协议以及自定义拦截器等
OkHttpClient(Builder builder) {
  this.dispatcher = builder.dispatcher;
  this.proxy = builder.proxy;
  this.protocols = builder.protocols;
  /** 省略大段代码 */
  boolean isTLS = false;
  for (ConnectionSpec spec : connectionSpecs) {
    isTLS = isTLS || spec.isTls();
  }
  /** 省略大段代码. */
  if (interceptors.contains(null)) {
    throw new IllegalStateException("Null interceptor: " + interceptors);
  }
  if (networkInterceptors.contains(null)) {
    throw new IllegalStateException("Null network interceptor: " + networkInterceptors);
  }
}
public static final class Builder {

  public Builder() {
// 分发器、协议、代理的默认参数
    dispatcher = new Dispatcher();
    protocols = DEFAULT_PROTOCOLS;
    proxySelector = ProxySelector.getDefault();
    if (proxySelector == null) {
      proxySelector = new NullProxySelector();
    }
  }

  Builder(OkHttpClient okHttpClient) {
    // 反向配置分发器、代理、协议
    this.dispatcher = okHttpClient.dispatcher; 
    this.proxy = okHttpClient.proxy; 
    this.protocols = okHttpClient.protocols;
// 新增所有自定义拦截器和自定义网络拦截器
    this.interceptors.addAll(okHttpClient.interceptors);
    this.networkInterceptors.addAll(okHttpClient.networkInterceptors);
  }

  // 配置代理
  public Builder proxy(@Nullable Proxy proxy) {
    this.proxy = proxy;
    return this;
  }
  // 向拦截器链中增加自定义拦截器
  public Builder addInterceptor(Interceptor interceptor) {
    if (interceptor == null) throw new IllegalArgumentException("interceptor == null");
    interceptors.add(interceptor);
    return this;
  }
  // 最后是build()方法,生成OkHttpClient对象
  public OkHttpClient build() {
    return new OkHttpClient(this);
  }
}
/**将指定的字符串追加到此字符序列*/
@Override
public StringBuilder append(CharSequence s) {
    super.append(s);// 实现过程略
    return this;
}
/**将此字符序列用其反转形式取代*/
@Override
public StringBuilder reverse() {
    super.reverse();// 实现过程略
    return this;
}

下面让我们来编写一下测试代码:

StringBuilder sb = new StringBuilder("若为自由故");
sb.append("只要主义真");
sb.reverse();
System.out.println(sb);
StringBuilder sb1 = new StringBuilder("若为自由故");
sb1.reverse();
sb1.append("只要主义真");
System.out.println(sb1);

测试结果如下:

System.out: 真义主要只故由自为若
System.out: 故由自为若只要主义真

建造者模式与简单工程模式的区别,在于建造者模式多出一个Builder类,使得创建对象的灵活性大大增加,适用于如下场景:

(1)创建一个对象,多个同样的方法的调用顺序不同,产生的结果不同

(2)创建一个对象,特别复杂,参数多,而且很多参数都有默认值

System.out.println("Hello World");

短短一行代码,背后有什么样的机制呢?

Java的编译原理,是将Hello.java编译成能被VM理解的Hello.class,然后再转化为能被不同硬件设备理解的bytecode进而执行的。

著名的字节码增强框架ASM,就是在Hello.java编译成Hello.class时可以读取并分析类信息、改变类行为、增强类功能甚至生成新的类的bytecode分析和操作框架。

我们来看一下相关的代码,代码当中的mv,来自ASM框架的MethodVisitor接口。

// 访问System类的类型为PrintSystem类型的静态变量out
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
// 访问常量池中的数据"Hello World"
mv.visitLdcInsn("Hello World");
// 调用PrintStream类的println()方法并把刚才获取到的对象当做String类型的参数传入
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);

本文分享自微信公众号 - 程序员小灰(chengxuyuanxiaohui),作者:东风玖哥,小灰

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-08-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 漫画:什么是 “代理模式” ?

    在上面的代码中,代理类和业务类继承了相同的接口,并且重写了添加/删除学生的方法。

    小灰
  • 漫画:什么是 “设计模式” ?

    这本书是软件研发领域重要的里程碑,合著此书的四位作者 Erich Gamma,Richard Helm,Ralph Johnson ,John Vlisside...

    小灰
  • 漫画:什么是 “原型模式” ?

    假如有一天,小灰被外星人抓走了,外星人要拿小灰做实验,想了解小灰在吃得好、睡得好、玩得开心的场景下,与现实中小灰的生存状态有什么区别。

    小灰
  • 漫谈建造者模式

    解决构造器赋值的最简单的方式就是用setter函数来给成员变量赋值,以替代冗长的构造函数。

    WindCoder
  • 漫画:什么是 “模因” ?

    他是一位武功高手,生平最得意的武功是降龙十八掌,可是他的儿女资质不佳,没有人能领悟这套武功,因此他的生平绝学眼看就要失传了。

    小灰
  • 漫画:什么是 “抽象工厂模式” ?

    所谓“工厂模式”,是三种常见设计模式的统称,它们分别是简单工厂模式、工厂方法模式、抽象工厂模式。

    小灰
  • 漫画:什么是 “抽象工厂模式” ?

    所谓“工厂模式”,是三种常见设计模式的统称,它们分别是简单工厂模式、工厂方法模式、抽象工厂模式。

    程序员的时光001
  • 漫画设计模式:什么是 “装饰器模式” ?

    在我们上面的例子中,Component接口相当于汽车接口,所有的被包装类、包装类,都继承于这个接口。

    肉眼品世界
  • 漫画设计模式:什么是 “装饰器模式” ?

    在我们上面的例子中,Component接口相当于汽车接口,所有的被包装类、包装类,都继承于这个接口。

    小灰
  • 漫画设计模式:什么是 “职责链模式” ?

    有一天,公司新来的产品经理有一个新需求,但她不知道这个需求应该由谁来负责。于是,她首先找到了小A:

    小灰
  • 漫画:什么是单例模式?(整合版)

    ————— 第二天 ————— 单例模式第一版: public class Singleton { private Singleton() {} ...

    程序猿DD
  • 漫画:什么是分布式锁?

    利用Memcached的add命令。此命令是原子性操作,只有在key不存在的情况下,才能add成功,也就意味着线程得到了锁。

    后端技术探索
  • 漫话:什么是单例模式?

    周末了,临近五一劳动节,女朋友还没有想好要去哪里玩,还在看着各种攻略。我则在旁边一边看书默默的心疼着我的钱包。突然女朋友开始发问:

    乔戈里
  • 【设计模式】1分钟给你整明白什么是Builder建造者模式

    我在Employee类中定义了一个静态内部类EmployeeBuilder,负责将Employee字段拆分,静态内部类每个方法都负责给相应的字段赋值,最后定义一...

    行百里er
  • 设计模式-建造者模式(造房子哪有这么简单)

    废话不多说,引出需求。 需求:建造房子,建造过程包括打地基、砌墙和封顶。房子各式各样,包括平房和别墅,编程模拟实现。

    唔仄lo咚锵
  • 【设计模式】第四篇:建造者模式也没那么难

    在生活中有很多场景与我们今天要说的 “建造者模式” 是非常匹配的,打个比方一台计算机是由 CPU、内存、显卡、内存、鼠标、键盘、显示器等等内容组合而成的,我们想...

    BWH_Steven
  • 触漫“蒙眼狂奔”?UGC平台天然就爱不良内容吗?

    快看漫画、触漫等头部漫画企业最近被推上舆论的风口浪尖,不良内容、诱导消费成为被诟病的核心问题,其中一家媒体连续发布多篇文章指出触漫存在不良内容,该文认为触漫是U...

    罗超频道
  • AI 复活已故漫画家手冢治虫,出版新作续写传奇

    场景描述:被誉为漫画之神的日本漫画家手冢治虫,已经离世 30 年,成为了很多人永远的回忆。去年,日本半导体公司 Kioxia 发起了一个项目「TEZUKA202...

    HyperAI超神经
  • AI复活已故漫画家手冢治虫,出版新作融入无人机、自动驾驶、人脸识别

    如果漫画家手冢治虫还活着,会在漫画中描绘出什么样的未来?AI 是否能够帮他呈现?

    新智元

扫码关注云+社区

领取腾讯云代金券