其实网上讲设计模式的帖子已经很多了,为什么我还要写呢。主要是让自己加深一下自己的理解和记忆。
前言
建造者模式又被称呼为生成器模式,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。用户在不知道建造的细节和过程就可以构造出对象。建造者模式,顾名思义就是像建筑一样,一层一层的建造出产品。
1.简介
-
建造者(Builder)模式的定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
-
该模式的主要优点如下:
封装性好,构建和表示分离。
扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。 -
其缺点如下:
产品的组成部分必须相同,这限制了其使用范围。
如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。
建造者(Builder)模式和工厂模式的关注点不同:建造者模式注重零部件的组装过程,而工厂方法模式更注重零部件的创建过程,但两者可以结合使用
1.使用方式1
建造者模式有抽象建造者,具体建造者,指挥者,产品等四个要素构成。
建造者(Builder)模式的主要角色如下。
- 产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
- 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
- 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
- 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。
1.其具体的结构图如下
代码实现如下:
抽象建造者
public abstract class AbstractProductBuilder {
protected Product product = new Product();
abstract void buildPartA();
abstract void buildPartB();
abstract void buildPartC();
public Product getResult() {
return product;
}
}
具体建造者
public class ProductABuilder extends AbstractProductBuilder {
@Override
void buildPartA() {
product.setPartA("构造A部分");
}
@Override
void buildPartB() {
product.setPartB("构造B部分");
}
@Override
void buildPartC() {
product.setPartC("构造C部分");
}
}
产品
public class Product {
private String partA;
private String partB;
private String partC;
protected String getPartA() {
return partA;
}
protected void setPartA(String partA) {
this.partA = partA;
}
protected String getPartB() {
return partB;
}
@Override
public String toString() {
return "Product{" +
"partA='" + partA + '\'' +
", partB='" + partB + '\'' +
", partC='" + partC + '\'' +
'}';
}
protected void setPartB(String partB) {
this.partB = partB;
}
protected String getPartC() {
return partC;
}
protected void setPartC(String partC) {
this.partC = partC;
}
}
指挥者
public class Director {
private AbstractProductBuilder abstractProductBuilder;
public Director(AbstractProductBuilder abstractProductBuilder) {
this.abstractProductBuilder = abstractProductBuilder;
}
public Product contruct() {
abstractProductBuilder.buildPartB();
abstractProductBuilder.buildPartA();
abstractProductBuilder.buildPartC();
return abstractProductBuilder.getResult();
}
}
使用
public static void main(String[] args) {
AbstractProductBuilder abstractProductBuilder = new ProductABuilder();
Director director = new Director(abstractProductBuilder);
System.out.println(director.contruct().toString());
}
建造者模式主要是想要使得构造与表示分离,比如说我的属性很复杂,当我想要初始化的时候,我只想要部分交给用户去初始化,一些我自己来初始化,或者是我想要产生只想要单例 都可以通过建造者模式去进行实现
举个🌰,我想要获得单例的对象上面的代码进行改造:
public abstract class AbstractProductBuilder {
// 加上静态属性 这样只会进行初始化一次,相当于饿汉式
protected static Product product = new Product();
abstract void buildPartA();
abstract void buildPartB();
abstract void buildPartC();
public Product getResult() {
return product;
}
}
上面的使用是经典的抽象建造者,具体建造者,指挥者,产品四个角色的实现。
2.使用方式
还有一种就是放弃掉指挥者这个角色,如果构建属性完全由使用者去搭配。(当我们去设计一个东西给别人使用的时候,首先我们可以构建出我们默认的一个对象,用户只要输入一些简单的属性入参就可以去使用,也应当提供一个用户可以自己搭配的属性的入参去使用的方法)
代码如下:
具体建造者
public class ProductABuilder extends AbstractProductBuilder {
public ProductABuilder builder() {
return new ProductABuilder();
}
@Override
void buildPartA() {
product.setPartA("构造A部分");
}
@Override
void buildPartB() {
product.setPartB("构造B部分");
}
@Override
void buildPartC() {
product.setPartC("构造C部分");
}
}
抽象建造者
public abstract class AbstractProductBuilder {
protected static Product product = new Product();
abstract AbstractProductBuilder buildPartA();
abstract AbstractProductBuilder buildPartB();
abstract AbstractProductBuilder buildPartC();
public Product getResult() {
return product;
}
}
总结
再一次强调一下建造者模式的优缺点
该模式的主要优点如下:
封装性好,构建和表示分离。
扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。(可以通过指挥者进行一个封装)
其缺点如下:
产品的组成部分必须相同,这限制了其使用范围。
如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。