漫画:什么是 “建造者模式” ?
互联网全栈架构
共 6936字,需浏览 14分钟
· 2021-09-27
————— 第二天 —————
————————————
首先,我们来定义一个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);
欢迎关注微信公众号:互联网全栈架构,收取更多有价值的信息。
评论
周鸿祎是真牛逼
最近在各个视频平台,我的推荐信息流上一定会出现红衣教主周鸿祎的身影,俨然是新一代的顶流IP网红,还是自己贼有钱的那种。不得不说,周鸿祎是真牛逼,他是懂得学习的。年初的时候,他就发文:“如今已是网红时代,我现在已经拜了俞敏洪为师,在学习如何当网红,每天勤奋的发短视频”。“有时候也在劝很多亚布力大哥级
公子龙
1
Windows格式化对话框是一个使用了30年的 “临时解决方案”
戴夫-普卢默(Dave Plummer)是微软的资深工程师,曾创造了任务管理器、Windows 弹球、原生 ZIP 支持(微软出钱买断该功能后,他用这笔钱购买了一辆红色克尔维特)等传奇。近日他在自己的 X 账户上分享了创建 "格式化" 对话框的故事 —— 称其是一个使用了长达 30 年的 “临时解决
开源Linux
0
OpenAI的Sora竟然造假:生成的AI大片只有1%的AI,剩下的99%是人工!
点蓝色字关注“机器学习算法工程师”设为星标,干货直达!啊?Sora火爆短片《气球人》,也“造假”了???背后艺术家团队的最新揭秘,可谓一石激起千层浪:原来,视频画面并非完全由AI生成,其中有大量视觉效果需要人类后期实现。be like:这下网友不干了,合着大家伙儿跟OpenAI玩真心,OpenAI背
机器学习算法工程师
1
李彦宏:开源大模型不如闭源,后者会持续领先;周鸿祎:“开源不如闭源” 的言论是胡说八道
架构师大咖
架构师大咖,打造有价值的架构师交流平台。分享架构师干货、教程、课程、资讯。架构师大咖,每日推送。
公众号该公众号已被封禁0、李彦宏:开源大模型不如闭源,后者会持续领先当今
源码共读
0
宇宙的尽头是编制?985高校硕士拟聘遗体火化工疯传!
本文来源:大皖新闻、潇湘晨报、南都街谈、超级数学建模、创业邦4月22日,广州市民政局网站发布的《广州市民政局直属事业单位2023年第一次公开招聘工作人员拟聘用人员公示(第一批)》引发舆论关注。名单中有毕业于香港中文大学的刘某拥有研究生学历,专业为哲学(佛学研究),另外二人本科分别毕业于华南理工大学建
机器学习初学者
0
Go早期是如何在Google内部发展起来的
2007年Go诞生于Google,2009年Google正式对外宣布了Go语言的开源!时至今日,距离Go开源已经过去了近15个年头了[1]!Go在Google公司内部究竟是怎样的一个状态呢?前Google员工Yves Junqueira近期撰文从其个人所见所闻谈了Go在Google的历程[2]!这里
GoCN
0
美国司法部重判币安创始人CZ,他到底做错了什么?
注:4月24日,美国司法部表示币安创始人兼前首席执行官赵长鹏应在监狱服刑三年(36个月),根据给出的理由显示,美国司法部律师认为赵长鹏帮助币安违反联邦制裁和洗钱法,并称其必须付出更大的代价,所以应该提高刑期。就在审判前,CZ在写给负责此案件的法官理查德· A · 琼斯的一封信中,为自己的「错误决定」
区块链头条
3
【比特币减半后价格表现大揭秘】历史数据告诉你什么?
加密货币现状的十张图表Glassnode 和 Coinbase 发布了《加密货币市场指南》,这是一个季度系列,旨在提供对加密货币市场主要发展的详细分析。以下是报告中引起我们注意的10张图表:1.比特币主导地位从50%上升至52%通常由减半引发的山寨季会降低比特币的主导地位,使其更倾向于新的山寨币。这
区块链头条
0