建造者模式
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
介绍
意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
优点: 1、建造者独立,易扩展。 2、便于控制细节风险。
缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。
使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。
注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。
demo:
入口类
package builder_method_mod;
import org.junit.Test;
/**
* 建造者模式
* 建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
*
* 一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
*
* 介绍
* 意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
*
* 主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
*
* 优点: 1、建造者独立,易扩展。 2、便于控制细节风险。
*
* 缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。
*
* 使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。
*
* 注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。
*/
public class Client {
@Test
public void test(){
Builder builder = new AmericanBuilder();//美国建筑师
ChineseBuilder builder1 = new ChineseBuilder();//中国建筑师
Director director = new Director(builder);//指导者,需要指定建筑师
Zoo zoo = director.construct();//开始构建,返回构建的产品
System.out.println(String.format("american 建造师建造的动物园: %s",zoo.toString()));//打印构建的结果
Director director1 = new Director(builder1);
Zoo zoo1 = director1.construct();
System.out.println(String.format("chinese 建造师建造的动物园: %s",zoo1.toString()));
}
}
抽象建造者
package builder_method_mod;
/**
* 抽象建造者
* 创建一个Product对象的各个部件指定的抽象接口。
*/
public abstract class Builder {
protected Zoo zoo = new Zoo();
public abstract void selectCat();
public abstract void selectDog();
public Zoo getResult(){
return zoo;
}
}
实例化建造者,美国建筑师
package builder_method_mod;
/**
* 具体建造者
* 实现抽象接口,构建和装配各个部件。
*/
public class AmericanBuilder extends Builder {
@Override
public void selectCat() {
zoo.setCat("咖啡猫");
}
@Override
public void selectDog() {
zoo.setDog("咖啡狗");
}
}
实例化建造者,中国建筑师
package builder_method_mod;
public class ChineseBuilder extends Builder{
@Override
public void selectCat() {
this.zoo.setCat("功夫猫");
}
@Override
public void selectDog() {
this.zoo.setDog("功夫狗");
}
}
指挥者
package builder_method_mod;
/**
* 指挥者
* 构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。
*/
public class Director {
private Builder builder;
public Director(Builder builder){
this.builder = builder;
}
public Zoo construct(){
//准备猫
builder.selectCat();
//准备狗
builder.selectDog();
return builder.getResult();
}
}
需要构建的产品
package builder_method_mod;
/**
* 产品角色 动物园
* 一个具体的产品对象。
*/
public class Zoo {
private String cat;
private String dog;
public String getCat() {
return cat;
}
public void setCat(String cat) {
this.cat = cat;
}
public String getDog() {
return dog;
}
public void setDog(String dog) {
this.dog = dog;
}
@Override
public String toString() {
return "Zoo{" +
"cat='" + cat + '\'' +
", dog='" + dog + '\'' +
'}';
}
}
在软件开发过程中有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成。例如,计算机是由 CPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装而成的,采购员不可能自己去组装计算机,而是将计算机的配置要求告诉计算机销售公司,计算机销售公司安排技术人员去组装计算机,然后再交给要买计算机的采购员。
生活中这样的例子很多,如游戏中的不同角色,其性别、个性、能力、脸型、体型、服装、发型等特性都有所差异;还有汽车中的方向盘、发动机、车架、轮胎等部件也多种多样;每封电子邮件的发件人、收件人、主题、内容、附件等内容也各不相同。
以上所有这些产品都是由多个部件构成的,各个部件可以灵活选择,但其创建步骤都大同小异。这类产品的创建无法用前面介绍的工厂模式描述,只有建造者模式可以很好地描述该类产品的创建。