一.定义
将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示
二.使用场景
- 1.一个对象有非常复杂的内部结构(有很多属性)
- 2.想把复杂对象的创建和使用分离
三.优缺点
1.优点
- 1.封装性好,创建和使用分离
- 2.扩展性好、建造类之间分离、一定程度上解耦
2.缺点
- 1.产生多余的Builder对象
- 2.产品结构发生变化,建造者都要修改,成本较大
四.角色
- 产品 : 具体的产品类
- 产品建造者 : 构造产品的类
五.实例
package com.shixinke.practise.design.pattern.content.creation.builder;
import java.math.BigDecimal;
/**
* 商品实体(数据库实体)
* @author shixinke
*/
public class Item {
/**
* 商品ID
*/
private Long itemId;
/**
* 商品名称
*/
private String itemName;
/**
* 商品标识名称
*/
private String itemMarketName;
/**
* 商品原价
*/
private BigDecimal originalPrice;
/**
* 市场价
*/
private BigDecimal marketPrice;
/**
* 在售状态
*/
private Short saleStatus;
/**
* 创建时间
*/
private Integer createTime;
/**
* 更新时间
*/
private Integer updateTime;
public Long getItemId() {
return itemId;
}
public String getItemName() {
return itemName;
}
public String getItemMarketName() {
return itemMarketName;
}
public BigDecimal getOriginalPrice() {
return originalPrice;
}
public BigDecimal getMarketPrice() {
return marketPrice;
}
public Short getSaleStatus() {
return saleStatus;
}
public Integer getCreateTime() {
return createTime;
}
public Integer getUpdateTime() {
return updateTime;
}
@Override
public String toString() {
return "Item{" +
"itemId=" + itemId +
", itemName='" + itemName + '\'' +
", itemMarketName='" + itemMarketName + '\'' +
", originalPrice=" + originalPrice +
", marketPrice=" + marketPrice +
", saleStatus=" + saleStatus +
", createTime=" + createTime +
", updateTime=" + updateTime +
'}';
}
/**
* 调用建造者方法
* @return
*/
public static Builder builder() {
return new Builder();
}
/**
* Item建造者类
*/
public static class Builder {
//建立一个指向产品类的实例(这里也可以把产品类的所有属性都放置于此)
private Item item;
private Builder() {
//初始化实例对象
item = new Item();
}
/*
* 设置属性
*/
public Builder setItemId(Long itemId) {
item.itemId = itemId;
return this;
}
public Builder setItemName(String itemName) {
item.itemName = itemName;
return this;
}
public Builder setItemMarketName(String itemMarketName) {
item.itemMarketName = itemMarketName;
return this;
}
public Builder setOriginalPrice(BigDecimal originalPrice) {
item.originalPrice = originalPrice;
return this;
}
public Builder setMarketPrice(BigDecimal marketPrice) {
item.marketPrice = marketPrice;
return this;
}
public Builder setSaleStatus(Short saleStatus) {
item.saleStatus = saleStatus;
return this;
}
public Builder setCreateTime(Integer createTime) {
item.createTime = createTime;
return this;
}
public Builder setUpdateTime(Integer updateTime) {
item.updateTime = updateTime;
return this;
}
/**
* 最终建造的方法
*/
public Item build() {
return item;
}
}
}
- 一般将建造者放置于产品类的内部,作为一个静态内部类来调用
六.建造者模式在源码中的应用
1.建造者模式在JDK中的使用
(1)StringBuilder
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
/*
* 类似于设置各种属性
*/
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
public StringBuilder append(StringBuffer sb) {
super.append(sb);
return this;
}
@Override
public StringBuilder append(CharSequence s) {
super.append(s);
return this;
}
/*
* 相当于build方法
*/
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
}
(2)StringBuffer
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
/*
* 类似于设置各种属性
*/
@Override
public synchronized StringBuffer append(Object obj) {
toStringCache = null;
super.append(String.valueOf(obj));
return this;
}
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
public synchronized StringBuffer append(StringBuffer sb) {
toStringCache = null;
super.append(sb);
return this;
}
@Override
synchronized StringBuffer append(AbstractStringBuilder asb) {
toStringCache = null;
super.append(asb);
return this;
}
/**
* 类似于build方法
*/
@Override
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
}
2.建造者模式在Spring中的应用
public final class BeanDefinitionBuilder {
public static BeanDefinitionBuilder genericBeanDefinition() {
return new BeanDefinitionBuilder(new GenericBeanDefinition());
}
public BeanDefinitionBuilder setParentName(String parentName) {
this.beanDefinition.setParentName(parentName);
return this;
}
public BeanDefinitionBuilder setFactoryMethod(String factoryMethod) {
this.beanDefinition.setFactoryMethodName(factoryMethod);
return this;
}
public BeanDefinitionBuilder setFactoryMethodOnBean(String factoryMethod, String factoryBean) {
this.beanDefinition.setFactoryMethodName(factoryMethod);
this.beanDefinition.setFactoryBeanName(factoryBean);
return this;
}
}