假如一个对象由许多不同的属性构造,我们想要构造一个我们自己指定特定属性的对象,最简单的方法就是为每种情况提供一个构造函数,我们根据不要的构造函数来得到我们需要的包含了指定属性的对象。
举例子:
一张作品上可能有 图、标题、描述、签名、盖章这5个不同属性。如果构造这个作品的对象,存在以下不同的对象情况(即我们买来的作品可能有以下这么多种情况)
1、只有图
2、只有标题(这可能就是一幅书法吧?)
3、只有描述(同书法…)
4、只有签名(这可能是大明星大佬的限量版签名?)
5、只有盖章(同限量版盖章…)
6、只有图和标题
7、只有图和描述
8、只有图和签名
9、只有图和盖章
10、只有标题和描述
11、只有标题和签名
12、只有标题和盖章
13、只有描述和签名
…
这就是一个排列组合问题,每种情况如果各对应一个构造函数,那么我们要写的构造函数也太多了,这还只有5个属性而已就能造那么多构造函数?!。
于是乎,建造者模式应运而生,它可以单独的来对一个对象进行构造,将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。也就是说它来完成对象的构造过程,并且这个过程可以构造出上面我们所说的所有我们希望得到的对象。
建造模式是将复杂的内部创建封装在内部,对于外部调用的人来说,只需要传入建造者和建造工具,对于内部是如何建造成成品的,调用者无需关心。
上面所说的那个包含了5个属性的对象有点多,这里就拿3个属性的对象来说吧,看看使用构建者模式如何完成。
public class MainFunctionBean {
private int bitmapRes;
private String title;
private String descr;
private MainFunctionBean(Builder builder) {
this.title = builder.getTitle();
this.bitmapRes = builder.getBitmapRes();
this.descr = builder.getDescr();
}
public int getBitmapRes() {
return bitmapRes;
}
public String getTitle() {
return title;
}
public String getDescr() {
return descr;
}
public static class Builder {
private int bitmapRes;
private String title;
private String descr;
public Builder setBitmapRes(int bitmapRes) {
this.bitmapRes = bitmapRes;
return this;
}
public Builder setTitle(String title) {
this.title = title;
return this;
}
public Builder setDescr(String descr) {
this.descr = descr;
return this;
}
public int getBitmapRes() {
return bitmapRes;
}
public String getTitle() {
return title;
}
public String getDescr() {
return descr;
}
public MainFunctionBean build() {
return new MainFunctionBean(this);
}
}
}
这就是一个bean类有3个属性:图片资源、标题和描述,换做平时,早就直接set get +构造方法了事了,但现在不同,如果我们的构造方法存在多种可能,那就需要用建造者模式!(或者没有那么多种可能也可以用建造者模式啦!)
这里把建造者Build写成静态内部类了。
调用构造对象时:
MainFunctionBean news = new MainFunctionBean.Builder().setBitmapRes(R.drawable.btn_new)
.setTitle(CommonConfig.NEWS)
.setDescr(getString(R.string.news_description))
.build();
就是这么简单得到 MainFunctionBean的对象 news了,想set哪个参数就set哪个参数,不set某个参数也OK!
也可以这样得到 MainFunctionBean的对象 news
MainFunctionBean.Builder builder=new MainFunctionBean.Builder();
builder.setBitmapRes(R.drawable.btn_new)
.setTitle(CommonConfig.NEWS)
.setDescr(getString(R.string.news_description));
MainFunctionBean news=builder.build();
还可以这样:
MainFunctionBean.Builder builder=new MainFunctionBean.Builder();
builder.setBitmapRes(R.drawable.btn_new);
builder.setTitle(CommonConfig.NEWS);
builder.setDescr(getString(R.string.news_description));
MainFunctionBean news=builder.build();