建造者模式
- 建造者模式 (Builder)
- 1) 原理
- 2) 为什么需要建造者模式
- 3) 源码应用
建造者模式 (Builder)
1) 原理
Builder 模式,中文翻译为建造者模式或者构建者模式,也有人叫它生成器模式。
创建者模式主要包含以下四个角色:
- 1.产品(Product):表示将要被构建的复杂对象
- 2.抽象创建者(Abstract Builder):定义构建产品的接口,通常包含创建和获取产品的方法。
- 3.具体创建者(Concrete Builder):实现抽象创建者定义的接口,为产品的各个部分提供具体实现。
- 4.指挥者(Director):负责调用具体创建者来构建产品的各个部分,控制构建过程。
我们考虑一个文档编辑器的例子。假设我们需要创建一个复杂的HTML文档,它包含了标题、段落和图像等元素。我们可以使用创建者设计模式来构建HTML文档。
1.产品(Product)类 - HTML文档(HtmlDocument):
public class HtmlDocument {
private String header = "";
private String body = "";
private String footer = "";
public void addHeader(String header) {
this.header = header;
}
public void addBody(String body) {
this.body = body;
}
public void addFooter(String footer) {
this.footer = footer;
}
@Override
public String toString() {
return "<html><head>" + header + "</head><body>" + body + "</body>
<footer>" + footer + "</footer></html>";
}
}
2.抽象创建者(Abstract Builder)类 - HtmlDocumentBuilder:
public abstract class HtmlDocumentBuilder {
protected HtmlDocument document;
public HtmlDocument getDocument() {
return document;
}
public void createNewHtmlDocument() {
document = new HtmlDocument();
}
public abstract void buildHeader();
public abstract void buildBody();
public abstract void buildFooter();
}
3.具体创建者(Concrete Builder)类 - ArticleHtmlDocumentBuilder:
public class ArticleHtmlDocumentBuilder extends HtmlDocumentBuilder {
@Override
public void buildHeader() {
document.addHeader("Article Header");
}
@Override
public void buildBody() {
document.addBody("Article Body");
}
@Override
public void buildFooter() {
document.addFooter("Article Footer");
}
}
4.指挥者(Director)类 - HtmlDirector:
public class HtmlDirector {
private HtmlDocumentBuilder builder;
public HtmlDirector(HtmlDocumentBuilder builder) {
this.builder = builder;
}
public void constructDocument() {
builder.createNewHtmlDocument();
builder.buildHeader();
builder.buildBody();
builder.buildFooter();
}
public HtmlDocument getDocument() {
return builder.getDocument();
}
}
现在我们可以使用创建者设计模式来构建一个HTML文档对象:
public class Main {
public static void main(String[] args) {
HtmlDocumentBuilder articleBuilder = new ArticleHtmlDocumentBuilder();
HtmlDirector director = new HtmlDirector(articleBuilder);
director.constructDocument();
HtmlDocument document = director.getDocument();
System.out.println("Constructed HTML Document: \n" + document);
}
}
以上是一个创建者设计模式的标准写法,事实,我们在工作中往往不会写的这么复杂,为了创建一个对象,我们创建了很多辅助的类,总觉得不太合适,在这个案例中,我们可以使用内部类来简化代码,以下是修改后的代码:
public class HtmlDocument {
private String header = "";
private String body = "";
private String footer = "";
public void addHeader(String header) {
this.header = header;
}
public void addBody(String body) {
this.body = body;
}
public void addFooter(String footer) {
this.footer = footer;
}
@Override
public String toString() {
return "<html><head>" + header + "</head><body>" + body + "</body>
<footer>" + footer + "</footer></html>";
}
public static class Builder {
protected HtmlDocument document;
public Builder() {
document = new HtmlDocument();
}
public Builder addHeader(String header) {
document.addHeader(header);
return this;
}
public Builder addBody(String body) {
document.addBody(body);
return this;
}
public Builder addFooter(String footer) {
document.addFooter(footer);
return this;
}
public HtmlDocument build() {
return document;
}
}
}
2) 为什么需要建造者模式
1.根据复杂的配置项进行定制化构建
2.实现不可变对象。即一旦创建完成,对象的状态就不能改变。这有助于保证对象的线程安全和数据完整性
3) 源码应用
1.jdk中,如StringBuilder和StringBuffer,他们的实现不是完全按照标准的创建者设计模式设计,但也是一样的思想:
2.在ssm源码中很多类都使用创建者设计模式,如Spring中的BeanDefinitionBuilder
类,mybatis中的 SqlSessionFactoryBuilder
、XMLConfigBuilder
、 XMLMapperBuilder
、 XMLStatementBuilder
、CacheBuilder
等