创建者模式
概念
这玩意儿也叫做Builder模式
,就是用来创建对象的嘛。如果只是单纯的new一个对象出来,然后给对象字段赋值的话,即进行简单的对象创建任务的话,确实不需要,我们大多数的场景也是这样的,不过嘛,这里还是为了学习而学习,等到你创建一个对象真的要进行很多步骤的时候,就可以考虑使用该设计模式了。
创建者模式由以下4个角色参与:
- 产品:也就是我们的对象嘛
- 抽象创建者:定义创建产品的接口,通常包含创建和获取产品的方法
- 具体的创建者:抽象创建者的实现类
- 指挥者:负责调用具体创建者来构建产品的各个部分,控制构建流程
代码示例
背景
假设现在我们要创建一个复杂的html文档,我们来看一下使用创建者模式应该怎么做:
/**
* 产品类
*/
@Data
public class HtmlDocument {
private String header;
private String body;
private String footer;
}
/**
* 抽象创建者
*/
public abstract class HtmlDocumentAbstractBuilder {
protected HtmlDocument htmlDocument;
public HtmlDocument getHtmlDocument(){
return this.htmlDocument;
}
public void createHtmlDocument(){
this.htmlDocument = new HtmlDocument();
}
public abstract void buildHeader();
public abstract void buildBody();
public abstract void buildFooter();
}
/**
* 具体创建者
*/
public class ArticleHtmlDocumentBuilder extends HtmlDocumentAbstractBuilder{
@Override
public void buildHeader() {
htmlDocument.setHeader("article header");
}
@Override
public void buildBody() {
htmlDocument.setBody("article body");
}
@Override
public void buildFooter() {
htmlDocument.setFooter("article footer");
}
}
/**
* 指挥者
*/
public class HtmlDirector {
private final HtmlDocumentAbstractBuilder builder;
public HtmlDirector(HtmlDocumentAbstractBuilder builder){
this.builder = builder;
}
public void constructDocument() {
builder.createHtmlDocument();
builder.buildHeader();
builder.buildBody();
builder.buildFooter();
}
public HtmlDocument getDocument() {
return builder.getHtmlDocument();
}
}
为了创建一个对象,写这么多的类,合适嘛?上述只是展示了一下标椎的流程,实际上,平时开发中,我们可以通常采用内部类的做法简化上述代码:
@Data
public class HTMLDocument {
private String header;
private String body;
private String footer;
public static class Builder {
private final HTMLDocument htmlDocument;
public Builder() {
this.htmlDocument = new HTMLDocument();
}
public Builder header(String header){
htmlDocument.setHeader(header);
return this;
}
public Builder body(String body){
htmlDocument.setBody(body);
return this;
}
public Builder footer(String footer){
htmlDocument.setFooter(footer);
return this;
}
public HTMLDocument build(){
return htmlDocument;
}
}
}
好了,其实,你熟悉lombok
的话,我们还可以这样做:
@Data
@Builder
public class HTMLDocument {
private String header;
private String body;
private String footer;
}
编译后的部分代码如下:
public class HTMLDocument {
private String header;
private String body;
private String footer;
HTMLDocument(String header, String body, String footer) {
this.header = header;
this.body = body;
this.footer = footer;
}
public static HTMLDocumentBuilder builder() {
return new HTMLDocumentBuilder();
}
public String getHeader() {
return this.header;
}
public String getBody() {
return this.body;
}
public String getFooter() {
return this.footer;
}
public void setHeader(String header) {
this.header = header;
}
public void setBody(String body) {
this.body = body;
}
public void setFooter(String footer) {
this.footer = footer;
}
public static class HTMLDocumentBuilder {
private String header;
private String body;
private String footer;
HTMLDocumentBuilder() {
}
public HTMLDocumentBuilder header(String header) {
this.header = header;
return this;
}
public HTMLDocumentBuilder body(String body) {
this.body = body;
return this;
}
public HTMLDocumentBuilder footer(String footer) {
this.footer = footer;
return this;
}
public HTMLDocument build() {
return new HTMLDocument(this.header, this.body, this.footer);
}
}
}
其实差不多的,好好体会一下。
总结
这玩意儿其实不难,看了上面的例子你也会恍然大悟,原来曾经使用的有些东西API就是创建者设计模式哇,而且你还学会了怎么写一个链式调用的方法了吧,哈哈。
还是那句话,为了学习而使用,OK的,但是如果说本身就没有这种复杂构建需求的话,写个私有方法,或者工具类那不是也行的嘛?
不要不设计,也不要过度设计。
2025/01/01
writeBy kaiven