建造者模式简介
代码示例
jdk 中是使用 builder 模式
1、定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
用户只需指定需要建造的类型就可以得到它们,建造过程不需要了解。
类型:创建型。
适用市场:
1、一个对象有非常复杂的内部结构
2、想把复杂对象的创建和使用分离
优点:
封装性好,创建和使用分离
扩展型好、建造类之间独立、一定程度上解耦。
缺点:
会产生多余的Builder 对象
产品内部发生变化,建造者都需要修改,成本较大
建造者模式和工厂模式的区别
1、建造者模式更注重方法的创建顺序,而工厂模式更注重于创建产品。
2、创建对象力度不同。建造者模式创建的对象一般更复杂,工厂模式创建的产品都是一个样子。
3、关注点。工厂模式只需要关注把对象创建出来即可。建造者模式 不止是把产品创造出来,还需要关注 组成元素。
代码示例
/**
* @program: adpn-pattern->Computer
* @description: 电脑类
* @author: Jstar
* @create: 2019-11-20 12:42
**/
public class Computer {
private String computerName;
private String computerSoftware;
//主板
private String computerMotherBoard;
//电源
private String computerPowerSupply;
//键盘
private String computerKeyBoard;
public String getComputerName() {
return computerName;
}
public void setComputerName(String computerName) {
this.computerName = computerName;
}
public String getComputerSoftware() {
return computerSoftware;
}
public Computer setComputerSoftware(String computerSoftware) {
this.computerSoftware = computerSoftware;
}
public String getComputerMotherBoard() {
return computerMotherBoard;
}
public void setComputerMotherBoard(String computerMotherBoard) {
this.computerMotherBoard = computerMotherBoard;
}
public String getComputerPowerSupply() {
return computerPowerSupply;
}
public void setComputerPowerSupply(String computerPowerSupply) {
this.computerPowerSupply = computerPowerSupply;
}
public String getComputerKeyBoard() {
return computerKeyBoard;
}
public void setComputerKeyBoard(String computerKeyBoard) {
this.computerKeyBoard = computerKeyBoard;
}
@Override
public String toString() {
return "Computer{" +
"computerName='" + computerName + '\'' +
", computerSoftware='" + computerSoftware + '\'' +
", computerMotherBoard='" + computerMotherBoard + '\'' +
", computerPowerSupply='" + computerPowerSupply + '\'' +
", computerKeyBoard='" + computerKeyBoard + '\'' +
'}';
}
}
/**
* @program: adpn-pattern->ComputerBuilder
* @description: 电脑创建者
* @author: Jstar
* @create: 2019-11-20 12:49
**/
public abstract class ComputerBuilder {
public abstract void buildComputerName (String computerName);
public abstract void buildComputerSoftware (String computerSoftware);
public abstract void buildComputerMotherBoard (String computerMotherBoard);
public abstract void buildComputerPowerSupply (String computerPowerSupply);
public abstract void buildComputerKeyBoard (String computerKeyBoard);
public abstract Computer makeComputer();
}
/**
* @program: adpn-pattern->ThinkpadComputerBuilder
* @description: 实际的电脑建造者
* @author: Jstar
* @create: 2019-11-24 08:50
**/
public class AacturalComputerBuilder extends ComputerBuilder{
private Computer computer= new Computer();
@Override
public void buildComputerName(String computerName) {
computer.setComputerName(computerName);
}
@Override
public void buildComputerSoftware(String computerSoftware) {
computer.setComputerSoftware(computerSoftware);
}
@Override
public void buildComputerMotherBoard(String computerMotherBoard) {
computer.setComputerMotherBoard(computerMotherBoard);
}
@Override
public void buildComputerPowerSupply(String computerPowerSupply) {
computer.setComputerPowerSupply(computerPowerSupply);
}
@Override
public void buildComputerKeyBoard(String computerKeyBoard) {
computer.setComputerKeyBoard(computerKeyBoard);
}
@Override
public Computer makeComputer() {
return computer;
}
}
/**
* @program: adpn-pattern->MiddleUser
* @description: 中间人代理联系生产电脑
* @author: Jstar
* @create: 2019-11-24 09:08
**/
public class MiddleUser {
private ComputerBuilder computerBuilder;
public void setComputerBuilder(ComputerBuilder computerBuilder) {
this.computerBuilder = computerBuilder;
}
private String computerName;
private String computerSoftware;
//主板
private String computerMotherBoard;
//电源
private String computerPowerSupply;
//键盘
private String computerKeyBoard;
public Computer makeComputer(String computerName,String computerSoftware,String computerMotherBoard,
String computerPowerSupply ,String computerKeyBoard ){
this.computerBuilder.buildComputerName(computerName);
this.computerBuilder.buildComputerKeyBoard(computerKeyBoard);
this.computerBuilder.buildComputerMotherBoard(computerMotherBoard);
this.computerBuilder.buildComputerPowerSupply(computerPowerSupply);
this.computerBuilder.buildComputerSoftware(computerSoftware);
Computer computer = this.computerBuilder.makeComputer();
return computer;
}
}
/**
* @program: adpn-pattern->Test
* @description: 测试类
* @author: Jstar
* @create: 2019-11-24 08:55
**/
public class Test {
public static void main(String[] args) {
ComputerBuilder builder=new AacturalComputerBuilder();
MiddleUser middleUser = new MiddleUser();
middleUser.setComputerBuilder(builder);
Computer computer = middleUser.makeComputer("联想电脑", "联想软件", "联想主板",
"联想电源", "联想键盘");
System.out.println(computer);
}
}
看一下实例的UML图:
运行看一下结果:
一个实例的电脑已经创建了,这就是建造者的标准模式。
但是这种建造模式,传参的时候容易错位,导致错误,下面我们来做一个演进版。
/**
* @program: adpn-pattern->Computer
* @description: 演进版电脑类
* @author: Jstar
* @create: 2019-11-24 09:31
**/
public class Computer {
private String computerName;
private String computerSoftware;
private String computerMotherBoard;
private String computerPowerSupply;
private String computerKeyBoard;
public Computer(ComputerBuilder builder){
this.computerName=builder.computerName;
this.computerSoftware=builder.computerSoftware;
this.computerMotherBoard=builder.computerMotherBoard;
this.computerPowerSupply=builder.computerPowerSupply;
this.computerKeyBoard=builder.computerKeyBoard;
}
@Override
public String toString() {
return "Computer{" +
"computerName='" + computerName + '\'' +
", computerSoftware='" + computerSoftware + '\'' +
", computerMotherBoard='" + computerMotherBoard + '\'' +
", computerPowerSupply='" + computerPowerSupply + '\'' +
", computerKeyBoard='" + computerKeyBoard + '\'' +
'}';
}
public static class ComputerBuilder{
private String computerName;
private String computerSoftware;
private String computerMotherBoard;
private String computerPowerSupply;
private String computerKeyBoard;
public ComputerBuilder buildComputerName(String computerName) {
this.computerName = computerName;
return this;
}
public ComputerBuilder buildComputerSoftware(String computerSoftware) {
this.computerSoftware = computerSoftware;
return this;
}
public ComputerBuilder buildComputerMotherBoard(String computerMotherBoard) {
this.computerMotherBoard=computerMotherBoard;
return this;
}
public ComputerBuilder buildComputerPowerSupply(String computerPowerSupply) {
this.computerPowerSupply=computerPowerSupply;
return this;
}
public ComputerBuilder buildComputerKeyBoard(String computerKeyBoard) {
this.computerKeyBoard=computerKeyBoard;
return this;
}
public Computer build (){
return new Computer(this);
}
}
}
//测试类
public class NewTest {
public static void main(String[] args) {
Computer computer = new Computer.ComputerBuilder().buildComputerName("惠普电脑名称").buildComputerSoftware("软件").buildComputerPowerSupply("电源")
.buildComputerKeyBoard("键盘").buildComputerMotherBoard("主板").build();
System.out.println(computer);
}
}
查看一下uml图:
现在调用关系就很明了,也不容易存在误传值的情况。
运行结果:
jdk 中是使用 builder 模式
1、在StringBuilder和StringBuffer中都是 builder 模式:
2、Immutable 使用建造者模式
add() 方法返回的是 Builder 类本身。
运行结果:
[s1, s2, s3]
3、Mybatis 中 SqlSessionFactoryBuilder关于 建造者模式
首先是一些build()方法返回的都是SqlSessionFactory 对象
我们来看一下第三个方法:
var5 = this.build(parser.parse());
mybatis 是通过XMLConfigBuilder 进行装配一系列参数。