定义
建造者(Builder)模式的定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式或者生成器模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的
优点
- 封装性好,构建和表示分离。
- 扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
- 客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。
缺点
- 产品的组成部分必须相同,这限制了其使用范围。
- 如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。
具体实现
一、指挥者模式
角色
- 产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
- 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
- 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
- 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
示例
public class BuilderTest {
static class Product {
private String product1;
private String product2;
private String product3;
public String getProduct1() {
return product1;
}
public void setProduct1(String product1) {
this.product1 = product1;
}
public String getProduct2() {
return product2;
}
public void setProduct2(String product2) {
this.product2 = product2;
}
public String getProduct3() {
return product3;
}
public void setProduct3(String product3) {
this.product3 = product3;
}
/**
* 产品展示
*/
public void productShow(){
System.out.println(product1 + "," + product2 + "," + product3);
}
}
static abstract class Builder {
// 构建产品1
abstract void build1();
// 构建产品2
abstract void build2();
// 构建产品3
abstract void build3();
// 构建完成
abstract Product budilComplete();
}
static class SpecificBuilder extends Builder {
private Product product;
SpecificBuilder(Product product){
this.product = product;
}
@Override
void build1() {
product.setProduct1("完成产品1构建");
}
@Override
void build2() {
product.setProduct2("完成产品2构建");
}
@Override
void build3() {
product.setProduct3("完成产品3构建");
}
@Override
Product budilComplete() {
return product;
}
}
static class Director {
public Product create(){
SpecificBuilder specificBuilder = new SpecificBuilder(new Product());
specificBuilder.build1();
specificBuilder.build2();
specificBuilder.build3();
return specificBuilder.budilComplete();
}
}
public static void main(String[] args) {
Director director = new Director();
Product product = director.create();
product.productShow();
}
}
二、内部类模式
public class BuilderTest {
static class Product {
private String product1;
private String product2;
private String product3;
Product(Builder builder) {
this.product1 = builder.product1;
this.product2 = builder.product2;
this.product3 = builder.product3;
}
void getProduct(){
System.out.println(product1 + "," + product2 + "," + product3);
}
static class Builder {
private String product1;
private String product2;
private String product3;
public Builder budil1(String product1) {
this.product1 = product1;
return this;
}
Builder budil2(String product2) {
this.product2 = product2;
return this;
}
Builder budil3(String product3) {
this.product3 = product3;
return this;
}
Product build(){
return new Product(this);
}
}
}
public static void main(String[] args) {
Product product = new Product.Builder()
.budil1("创建产品1")
.budil2("创建产品2")
.budil3("创建产品3")
.build();
product.getProduct();
}
}
三、自由组合模式
public class FreeBuilderTest {
static class Product{
private String productA;
private String productB;
private String productC;
public String getProductA() {
return productA;
}
public void setProductA(String productA) {
this.productA = productA;
}
public String getProductB() {
return productB;
}
public void setProductB(String productB) {
this.productB = productB;
}
public String getProductC() {
return productC;
}
public void setProductC(String productC) {
this.productC = productC;
}
@Override
public String toString(){
return productA + productB + productC;
}
}
static abstract class Builder {
abstract Builder createA(String ms);
abstract Builder createB(String ms);
abstract Builder createC(String ms);
abstract Product build();
}
static class ConcreteBuilder extends Builder{
private Product product;
ConcreteBuilder(){
this.product = new Product();
}
@Override
Builder createA(String msg) {
product.setProductA(msg);
return this;
}
@Override
Builder createB(String msg) {
product.setProductB(msg);
return this;
}
@Override
Builder createC(String msg) {
product.setProductC(msg);
return this;
}
@Override
Product build() {
return product;
}
}
public static void main(String[] args) {
Product product = new ConcreteBuilder()
.createA("拿烟")
.createB("点火")
.createC("抽烟")
.build();
System.out.println(product.toString());
}
}
第二、三种方式是日常工作种常用到的两种方式,相较于第一种方式少了指挥者,代码扩展性更好。第二种相较于第三种写法上不需要建那么多类,代码更清晰。