文章目录
- 一、建造者模式概述
- 1、建造者模式介绍
- 2、建造者模式的四个角色
- 二、建造者模式示例
- 1、建造者模式示例1
一、建造者模式概述
1、建造者模式介绍
(1)介绍
- 建造者模式(Builder Pattern)又叫生成器模式,是一种对象构建模式,属于创建型模式。
- 建造者模式可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。
- 建造者模式使用多个简单的对象一步一步构建成一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。
(2)优缺点
- 优点:
- 建造者独立,易扩展。
- 便于控制细节风险。
- 可以使客户端不必知道产品内部组成的细节。
- 具体的建造者类之间是相互独立的,这有利于系统的扩展。
- 具体的建造者相互独立,因此可以对建造的过程逐步细化,而不会对其他模块产生任何影响。
- 缺点:
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
- 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。
(3)使用场景
- 隔离复杂对象的创建和使用,相同的方法,不同执行顺序,产生不同事件结果;
- 多个部件都可以装配到一个对象中,但产生的运行结果不相同;
- 产品类非常复杂或者产品类因为调用顺序不同而产生不同作用;
- 初始化一个对象时,参数过多,或者很多参数具有默认值;
- Builder模式不适合创建差异性很大的产品类;
- 产品内部变化复杂,会导致需要定义很多具体建造者类实现变化,增加项目中类的数量,增加系统的理解难度和运行成本;
- 需要生成的产品对象有复杂的内部结构,这些产品对象具备共性。
(4)注意事项
- 与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。
2、建造者模式的四个角色
(1)四个角色介绍
- Product(产品角色) :一个具体的产品对象。
- Builder(抽象建造者) :创建一个Product对象的各个部件指定的接口。
- ConcreteBuilder(具体建造者):实现接口,构建和装配各个部件。
- Director(指挥者):构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。它主要有两个作用,一是隔离了客户与对象的生产过程,二是负责控制产品对象的生产过程。
(2)四个角色原理类图
二、建造者模式示例
1、建造者模式示例1
比如我们现在需要烹饪白菜,白菜有不同的做法,炒白菜的大概步骤有买菜、洗菜、炒菜,而辣白菜的步骤有买菜、洗菜、腌菜,白菜汤的步骤有买菜、洗菜、煮菜。
(1)首先创建一个类Product代表成品菜,类中包含具体的做菜步骤
public class Product {
private String buyFood; //买菜
private String washFood; //洗菜
private String fireFood; //炒菜
private String saltFood; //腌菜
private String waterFood; //煮菜
/*省略getter/setter方法*/
}
(2)创建一个抽象建造者Builder 类,定义产品的创建方法和返回方法
public abstract class Builder {
/*产品实例*/
protected Product product = new Product();
/*抽象方法*/
public abstract void buildBuyFood();
public abstract void buildWashFood();
public abstract void buildFireFood();
public abstract void buildSaltFood();
public abstract void buildWaterFood();
/*返回方法*/
public Product getProduct(){
return product;
}
}
(3)创建一个具体建造者ConcreteBuilder 类,具体建造者类实现了抽象建造者类的抽象接口,构建和步骤等
public class ConcreteBuilder extends Builder {
@Override
public void buildBuyFood() {
System.out.println("去超市购买白菜");
}
@Override
public void buildWashFood() {
System.out.println("把白菜清洗干净");
}
@Override
public void buildFireFood() {
System.out.println("用火炒菜,做炒白菜");
}
@Override
public void buildSaltFood() {
System.out.println("用盐腌菜,做辣白菜");
}
@Override
public void buildWaterFood() {
System.out.println("用水煮菜,做白菜汤");
}
}
(4)创建一个指挥者类Director 类
public class Director {
private Builder builder;
/*构造方法的方式注入builder对象*/
public Director(Builder builder){
this.builder = builder;
}
/*set方法注入builder对象*/
public void setBuilder(Builder builder) {
this.builder = builder;
}
/*炒白菜*/
public Product constructFire() {
builder.buildBuyFood();
builder.buildWashFood();
builder.buildFireFood();
return builder.getProduct();
}
/*腌白菜*/
public Product constructSalt() {
builder.buildBuyFood();
builder.buildWashFood();
builder.buildSaltFood();
return builder.getProduct();
}
/*白菜汤*/
public Product constructWater() {
builder.buildBuyFood();
builder.buildWashFood();
builder.buildWaterFood();
return builder.getProduct();
}
}
(5)main方法测试类
public class Jzzms {
public static void main(String[] args) {
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
/*调用炒白菜*/
System.out.println("--------炒白菜的做法步骤--------");
director.constructFire();
/*调用腌白菜*/
System.out.println("--------腌白菜的做法步骤--------");
director.constructSalt();
/*调用煮白菜*/
System.out.println("--------白菜汤的做法步骤--------");
director.constructWater();
}
}
(6)输出结果
--------炒白菜的做法步骤--------
去超市购买白菜
把白菜清洗干净
用火炒菜,做炒白菜
--------腌白菜的做法步骤--------
去超市购买白菜
把白菜清洗干净
用盐腌菜,做辣白菜
--------白菜汤的做法步骤--------
去超市购买白菜
把白菜清洗干净
用水煮菜,做白菜汤
(7)分析
- 从上面的代码可以得到,用户只需要指定需要什么样的产品(做什么菜),而不用去管具体的完成步骤和细节;
- 建造制作过程由指挥者来控制,建造细节由一个抽象类来控制,对于实现建造细节的具体类来说,不会遗漏某一个步骤。
- 指挥者针对抽象建造者编程,客户端只需要知道具体建造者的类型,即可通过指挥者类调用建造者的相关方法,返回一个完整的产品对象。建造者负责控制产品的生成过程,并且隔离了客户与生产过程。