一、作用
工匠若水-设计模式(创建型)之建造者模式(Builder Pattern)
用于构建复杂的对象,将构建的内部细节隐藏起来。使用者只需按照约定好的规则做相应的配置来完成构建,然后将配置好的对象表示出来即可。
把复杂对象的构建,拆解成几个小部分。当我们面临着一个复杂对象的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
我们参考AlertDialog,对于一个Dialog而言,它的基本构成是复杂的(有标题,内容,按钮及其对应的事件等等属性),但是在实际需求中,不同的界面,我们需要展示给用户的Dialog是不一样的(标题不一样,内容不一样,点击事件也不一样),这些各个部分都是在不断剧烈的变化,但是他们组合起来是相对稳定的(就是一个Dialog弹出展示在界面上)。
在这种情况下,我们可以尝试使用Builder模式,和普通的构造器生成对象不同,如果没有需求,我们可以忽略配置某些属性——对于Dialog,我可以不去定义title,也可以不去定义取消按钮的点击事件,他们内部都有默认的处理;此外,对于API的设计来讲,Builder模式更利于去扩展新的功能或者属性。
与工厂模式相比
建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的导演类。
- 工厂模式
将对象的全部创建过程封装在工厂类中,由工厂类向客户提供最终的产品 - 建造者模式
建造者一般只提供产品类中各个组件的建造,将具体建造过程交给导演类。导演类负责将各个组件按照特定规则组建为产品,然后将产品交付给客户端。
使用场景:
- 一个产品有复杂的内部结构
- 需生产的产品对象的属性相互依赖。建造者模式可以强制实行一种分步骤进行的建造过程。因此,如果产品对象的一个属性必须在另一个属性被赋值之后才可以被赋值,使用建造者模式是很好的设计思想。
二、概念
1.角色
-
产品类
-
抽象建造者
建造者一般只提供产品类中各个组件的建造 -
具体建造者
-
指挥者
将各个组件按照特定规则组建为产品
三、使用
1.详细的使用
- 产品类
public class ProgramMonkey {
private boolean isLiteratal;
private boolean isKnowMath;
private String language;
private boolean isKnowDesign;
public boolean isLiteratal() {
return isLiteratal;
}
public void setLiteratal(boolean literatal) {
isLiteratal = literatal;
}
public boolean isKnowMath() {
return isKnowMath;
}
public void setKnowMath(boolean knowMath) {
isKnowMath = knowMath;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public boolean isKnowDesign() {
return isKnowDesign;
}
public void setKnowDesign(boolean knowDesign) {
isKnowDesign = knowDesign;
}
@Override
public String toString() {
return "ProgramMonkey{" +
"isLiteratal=" + isLiteratal +
", isKnowMath=" + isKnowMath +
", language='" + language + '\'' +
", isKnowDesign=" + isKnowDesign +
'}';
}
}
- 抽象建造者
public abstract class Builder {
public abstract void buildIsLiteratal(boolean isLiteratal);
public abstract void buildIsKnowMath(boolean isKnowMath);
public abstract void buildwLanguage(String language);
public abstract void buildIsKnowDesign(boolean isKnowDesign);
public abstract ProgramMonkey getMonkey();
}
- 具体建造者
public class ConcreteBuilder extends Builder {
private ProgramMonkey mMonkey = new ProgramMonkey();
@Override
public void buildIsLiteratal(boolean isLiteratal) {
mMonkey.setLiteratal(isLiteratal);
}
@Override
public void buildIsKnowMath(boolean isKnowMath) {
mMonkey.setKnowMath(isKnowMath);
}
@Override
public void buildwLanguage(String language) {
mMonkey.setLanguage(language);
}
@Override
public void buildIsKnowDesign(boolean isKnowDesign) {
mMonkey.setKnowDesign(isKnowDesign);
}
@Override
public ProgramMonkey getMonkey() {
return mMonkey;
}
}
- 指挥者
public class Director {
Builder mBuilder = new ConcreteBuilder();
public ProgramMonkey getLowMonkey() {
mBuilder.buildIsLiteratal(true);
mBuilder.buildIsKnowDesign(true);
mBuilder.buildIsKnowMath(true);
mBuilder.buildwLanguage("Java");
return mBuilder.getMonkey();
}
public ProgramMonkey getHighMonkey() {
mBuilder.buildIsLiteratal(true);
mBuilder.buildIsKnowDesign(true);
mBuilder.buildIsKnowMath(true);
mBuilder.buildwLanguage("Android");
return mBuilder.getMonkey();
}
}
2.简化的使用
一般将抽象构建者、具体构建者、指挥者三者合为一体。
public class MyProgramMonkey {
private boolean isLiteratal;
private boolean isKnowMath;
private String language;
private boolean isKnowDesign;
public static class Builder {
/**
* 产品的各个组成部分有默认值,如果构建产品时不特殊指定,则使用默认值
*/
private boolean isLiteratal = false;
private boolean isKnowMath = false;
private String language = "Java";
private boolean isKnowDesign = false;
/**
* 具体部件的构建
*
* @param isLiteratal
* @return
*/
public Builder setIsLiterratal(boolean isLiteratal) {
this.isLiteratal = isLiteratal;
return this;
}
public Builder setIsKnowMath(boolean isKnowMath) {
this.isKnowMath = isKnowMath;
return this;
}
public Builder setLanguage(String language) {
this.language = language;
return this;
}
public Builder setIsKnowDesign(boolean isKnowDesign) {
this.isKnowDesign = isKnowDesign;
return this;
}
/**
* 按照特定的规则组装各个具体部件
*
* @return
*/
public MyProgramMonkey create() {
MyProgramMonkey monkey = new MyProgramMonkey();
monkey.isLiteratal = isLiteratal;
monkey.isKnowMath = isKnowMath;
monkey.language = language;
monkey.isKnowDesign = isKnowDesign;
return monkey;
}
}
}
3.在ImageLoader中的使用
public class ImageConfig {
String a = "a";
String b = "b";
boolean c=false;
public static class Builder{
String a = "a";
String b = "b";
boolean c=false;
/**
* 具体部件的构建
* @param a
* @return
*/
public Builder setA(String a) {
this.a = a;
return this;
}
public Builder setB(String b) {
this.b = b;
return this;
}
public Builder setC(boolean c) {
this.c = c;
return this;
}
/**
* 按照特定规则将各个组件组建为产品
* @return
*/
public ImageConfig create() {
ImageConfig imageConfig = new ImageConfig();
imageConfig.a = a;
imageConfig.b = b;
imageConfig.c = c;
return imageConfig;
}
}
}
public class ImageLoader {
private ImageConfig mImageConfig;
private ImageLoader() {
// nothing
}
public static ImageLoader getInstance() {
return SingletonHolder.instance;
}
private static class SingletonHolder {
private static final ImageLoader instance = new ImageLoader();
}
public void init(ImageConfig config) {
this.mImageConfig = config;
}
// 其他方法等
}
使用
@Test
public void test3() {
ImageConfig imageConfig = new ImageConfig.Builder().setA("A").setC(true).create();
ImageLoader.getInstance().init(imageConfig);
}
参考文献
工匠若水-设计模式(创建型)之建造者模式(Builder Pattern)
SheHuan-Builder(建造者)模式
网友评论