𝑰’𝒎 𝒉𝒉𝒈, 𝑰 𝒂𝒎 𝒂 𝒈𝒓𝒂𝒅𝒖𝒂𝒕𝒆 𝒔𝒕𝒖𝒅𝒆𝒏𝒕 𝒇𝒓𝒐𝒎 𝑵𝒂𝒏𝒋𝒊𝒏𝒈, 𝑪𝒉𝒊𝒏𝒂.
- 🏫 𝑺𝒉𝒄𝒐𝒐𝒍: 𝑯𝒐𝒉𝒂𝒊 𝑼𝒏𝒊𝒗𝒆𝒓𝒔𝒊𝒕𝒚
- 🌱 𝑳𝒆𝒂𝒓𝒏𝒊𝒏𝒈: 𝑰’𝒎 𝒄𝒖𝒓𝒓𝒆𝒏𝒕𝒍𝒚 𝒍𝒆𝒂𝒓𝒏𝒊𝒏𝒈 𝒅𝒆𝒔𝒊𝒈𝒏 𝒑𝒂𝒕𝒕𝒆𝒓𝒏, 𝑳𝒆𝒆𝒕𝒄𝒐𝒅𝒆, 𝒅𝒊𝒔𝒕𝒓𝒊𝒃𝒖𝒕𝒆𝒅 𝒔𝒚𝒔𝒕𝒆𝒎, 𝒎𝒊𝒅𝒅𝒍𝒆𝒘𝒂𝒓𝒆 𝒂𝒏𝒅 𝒔𝒐 𝒐𝒏.
- 💓 𝑯𝒐𝒘 𝒕𝒐 𝒓𝒆𝒂𝒄𝒉 𝒎𝒆:𝑽𝑿
- 📚 𝑴𝒚 𝒃𝒍𝒐𝒈: 𝒉𝒕𝒕𝒑𝒔://𝒉𝒉𝒈𝒚𝒚𝒅𝒔.𝒃𝒍𝒐𝒈.𝒄𝒔𝒅𝒏.𝒏𝒆𝒕/
- 💼 𝑷𝒓𝒐𝒇𝒆𝒔𝒔𝒊𝒐𝒏𝒂𝒍 𝒔𝒌𝒊𝒍𝒍𝒔:𝒎𝒚 𝒅𝒓𝒆𝒂𝒎
1-1:定义
The intent of the Builder design pattern is to separate the construction of a complex object from its representation. By doing so, the same construction process can create different representations.
建造者设计模式是为了把复杂对象的创建从它的表示中分离出来,这样的话,同样的构造过程能够创建出不同的表示。
1-2:传统建造者模式
还是老样子,先给demo,再分析他的好坏。
- Bike
package com.company.design.builder.traditional; public class Bike { private String componentA; private String componentB; private String componentC; public Bike() { } public void setComponentA(String componentA) { this.componentA = componentA; } public void setComponentB(String componentB) { this.componentB = componentB; } public void setComponentC(String componentC) { this.componentC = componentC; } @Override public String toString() { return "Bike{" + "componentA='" + componentA + '\'' + ", componentB='" + componentB + '\'' + ", componentC='" + componentC + '\'' + '}'; } }
- Builder
package com.company.design.builder.traditional; public abstract class Builder { protected abstract void buildComponentA(); protected abstract void buildComponentB(); protected abstract void buildComponentC(); protected abstract Bike createBike(); }
- HaloBuilder
package com.company.design.builder.traditional; public class HaloBuilder extends Builder { private Bike haloBike = new Bike(); @Override protected void buildComponentA() { this.haloBike.setComponentA("halo componentA"); } @Override protected void buildComponentB() { this.haloBike.setComponentB("halo componentB"); } @Override protected void buildComponentC() { this.haloBike.setComponentC("halo componentC"); } @Override protected Bike createBike() { return this.haloBike; } }
- OfOBuilder
package com.company.design.builder.traditional; public class OfOBuilder extends Builder { private Bike ofoBike = new Bike(); @Override protected void buildComponentA() { this.ofoBike.setComponentA("ofo componentA"); } @Override protected void buildComponentB() { this.ofoBike.setComponentB("ofo componentB"); } @Override protected void buildComponentC() { this.ofoBike.setComponentC("ofo componentC"); } @Override protected Bike createBike() { return this.ofoBike; } }
- Director
package com.company.design.builder.traditional; public class Director { private Builder haloBikeBuilder = new HaloBuilder(); private Builder OfOBikeBuilder = new OfOBuilder(); public Bike getHaloBike() { this.haloBikeBuilder.buildComponentA(); this.haloBikeBuilder.buildComponentB(); return haloBikeBuilder.createBike(); } public Bike getOfOBike() { this.OfOBikeBuilder.buildComponentA(); this.OfOBikeBuilder.buildComponentC(); return OfOBikeBuilder.createBike(); } }
- Client
package com.company.design.builder.traditional; public class Client { public static void main(String[] args) { Director director = new Director(); Bike haloBike = director.getHaloBike(); Bike ofOBike = director.getOfOBike(); System.out.println(haloBike); System.out.println(ofOBike); } }
简单分析一下这里的代码:一句话概括指挥者director指挥builder去执行build 产品操作。
- director把builder的建造流程进行了封装,也就是说本来builder四散在外面一个产品一个builder,director将他们汇聚起来了,实际的建造过程还是builder去做的,那么director是负责制造的顺序,哪些要调用,哪些不要,可以自由选择。
- 关于builder的写法:我感觉我这样写的话,其实也没啥问题,意思是一个意思吧,只是顺序交给了builder去定,而不是director定顺序。
- director public Bike geHaloBike() { return haloBikeBuilder.createBike(); } - Halobuilder @Override protected Bike createBike() { this.haloBike.setComponentA("halo componentA"); this.haloBike.setComponentB("halo componentB"); return this.haloBike; }
1-3:简化的建造者-链式写法的由来?
先上代码,再分析:
package com.company.design.builder.simple;
public class Bike {
private String componentA;
private String componentB;
private String componentC;
private Bike(Builder builder) {
this.componentA = builder.componentA;
this.componentB = builder.componentB;
this.componentC = builder.componentC;
}
public static final class Builder {
private String componentA;
private String componentB;
private String componentC;
public Builder() {
}
public Builder setComponentA(String componentA) {
this.componentA = componentA;
return this;
}
public Builder setComponentB(String componentB) {
this.componentB = componentB;
return this;
}
public Builder setComponentC(String componentC) {
this.componentC = componentC;
return this;
}
public Bike build() {
return new Bike(this);
}
}
@Override
public String toString() {
return "Bike{" +
"componentA='" + componentA + '\'' +
", componentB='" + componentB + '\'' +
", componentC='" + componentC + '\'' +
'}';
}
}
package com.company.design.builder.simple;
public class Client {
public static void main(String[] args) {
Bike bike = new Bike.Builder()
.setComponentA("componentA")
.setComponentB("componentB")
.setComponentC("componentC")
.build();
System.out.println(bike.toString());
}
}
只用了一个类和一个静态内部类,就完成了,很简洁有没有,准确的来说,这里就是把director要做的事情,让客户去写了,对吧?你想怎么构造顺序,你就可以构造出来,其他没有什么区别。
1-4:传统建造者模式的优缺点
搜集了各方面资料总结了下面几点;
- 优点:
- 封装了建造的过程,具体的产品是怎么构造的,什么顺序,你并不知道,拿来就用了。
- 建造者之间相互独立,不受影响。
- 不需要通过构造方法去实例化对象,从冗长的构造方法中解脱出来,在构造方法中如果你不需要某个参数,你还得把null传递进去,要么就是写多个参数不同的构造方法。
- 缺点
- 很明显哈,代码是原来两倍多了,代码变的复杂了。(这可能是最主要的原因)
- 对每一个产品都得用一个builder来做。(简化后的建造者模式)
1-5:建造者模式使用场景
简言之,当方法执行顺序不同的时候,会得到不同的产品(结果)的时候,就是建造者模式登场的时候,建造者模式关注的是什么?是构造的顺序,顺序!顺序!
1-6:建造者模式和工厂方法模式的区别
同样是创建型,创建产品的,他们区别在哪?
工厂模式只要出来产品就行,什么顺序不顺序它不管,通过工厂模式创建出来的东西都是一样的,而建造者模式,构建顺序不同,出来的东西也不同。 看下面的例子,你就懂了。
1-7:jdk中的建造者模式-StringBuilder
// 它的产品
char[] value;
@Override
public StringBuilder append(char c) {
super.append(c);
return this;
}
// 建造出来的产品
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
很明显用的是简易的建造者模式,需要加多少char进去,你说了算,也就是我们经常可以调用append,不停地往里面加的原因,原来是用了建造者模式,这样就清晰了!
1-8:参考链接
- https://stackoverflow.com/questions/757743/what-is-the-difference-between-builder-design-pattern-and-factory-design-pattern
- https://howtodoinjava.com/design-patterns/creational/builder-pattern-in-java/
- https://www.jianshu.com/p/3d1c9ffb0a28
- https://segmentfault.com/a/1190000040244002