Java设计模式-建造者模式(生成器模式)

一、简介

1.1 引入

在现实世界中,一个对象往往是由多个对象或多个步骤去完成,比如:购买披萨的过程,在购买披萨的过程中可能会有不同的流程

  1. 首先将披萨制作完成,然后把大块披萨切成小块,最后打包
  2. 首先将披萨制作完成,然后先打包,回家后自己切披萨
  3. 首先将披萨制作完成,如果是小块披萨,就不用切分,直接打包回家
    在这里插入图片描述

不同的客户有不同的需求,所以我们不能在构造方法中死板的、一次性的去满足不同用户的需求,而是要将披萨的购买过程分成若干个步骤,并将披萨的购买过程封装在另一个类中
在这里插入图片描述

1.2 定义

建造者模式:建造者模式又叫生成器模式,它是指将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一种对象创建型模式

  • 它将一个复杂的对象分解成多个对象,然后再将分解的对象重新组建

1.3 建造者模式和工厂模式的区别

  • 工厂模式注重的是产品的创建,不关心产品的组成部分,只要把产品生产出来即可
  • 建造者模式也会创建产品,但是建造者模式不仅要创建产品,还需要关心这个产品的组成细节和过程。每一个组成细节对应一个方法,这些方法的不同执行顺序会得到该对象的不同表示
  • 工厂模式只需要买到披萨即可,建造者模式不仅要买到披萨,还注重买披萨的过程。也就是说工厂模式注重结果,建造者模式注重细节

二、模式原理

2.1 模式组成

组成(角色)作用
Builder(抽象建造者)它是一个包含创建产品各个子部件的抽象方法的接口。通常还包含一个用于返回Product的方法getProduct()
ConcreteBuilder(具体建造者)实现Builder接口的类,实现各个部件的具体构造
Product(产品)它是具体建造者要构造的复杂对象,包含了产品的多个组成部件
Director(指挥者)该类需要含有一个Builder接口声明的变量,通过调用builder的getProduct()方法实现不同的创建顺序

2.2 UML类图

在这里插入图片描述

2.3 组成代码

  • Product类:包含多个组成部件
public class Product{
	private String part1;
	private String part2;
	private String part3;//这里的部件可以是任意类型
	//省略了部件part1,2,3的getter()和setter()方法
}
  • Builder接口:包含创建产品各个子部件的抽象方法
public interface Builder{
	void buildPart1();
	void buildPart2();
	void buildPart3();
	Product getProduct();
}
  • ConcreteBuilder:实现了Builder中的抽象方法
public class ConcreteBuilder implements Builder{
	private Product product;
	
	//Product聚合到ConcreteBuilder中
	public ConcreteBuilder(){
		product = new Product();
	}
	public void buildPart1(){
		System.out.println("完成部件1");
	}
	public void buildPart2(){
		System.out.println("完成部件2");
	}
	public void buildPart3(){
		System.out.println("完成部件3");
	}
	public Product getProduct(){
	//不同具体建造者的getProduct()方法中有不同的调用顺序
		buildPart1();	
		buildPart2();
		buildPart3();
		return product;
	}
}
  • Director:完成复杂对象的创建
public class Director{
	private Builder builder;
	public Director(Builder builder){
		this.builder = builder;
	}
	public Product construct(){
		//不同的具体建造者得到该对象的不同表示
		return builder.getProduct();
	}
}

三、实例

3.1 实例概况

  • 用户购买披萨,不同的用户可能有不同的购买流程
  • 利用建造者模式来实现不同用户的购买流程

3.2 步骤

  1. Builder建造者:创建PizzaBuilder抽象建造者
//买披萨的流程
public interface PizzaBuilder {
	void buildPart1();
	void buildPart2();
	void buildPart3();
	Pizza getProduct();
}
  1. ConcreteProcess具体建造者:创建两个不同的具体建造流程
//根据流程1来完成:按照 制作-切片-打包
public class ConcreteProcessA implements PizzaBuilder{
	private Pizza product;

	public ConcreteProcessA() {
		product = new Pizza();
	}

	public void buildPart1() {
		System.out.println("完成制作");
	}

	public void buildPart2() {
		System.out.println("完成切片");
	}

	public void buildPart3() {
		System.out.println("完成打包");
	}

	public Pizza getProduct() {
		System.out.println("根据流程1来完成:按照 制作-切片-打包");
		buildPart1();
		buildPart2();
		buildPart3();
		return product;
	}
}
//根据流程2来完成:按照 制作-打包-切片
public class ConcreteProcessB implements PizzaBuilder{
	private Pizza product;

	public ConcreteProcessB() {
		product = new Pizza();
	}

	public void buildPart1() {
		System.out.println("完成制作");
	}

	public void buildPart2() {
		System.out.println("完成切片");
	}

	public void buildPart3() {
		System.out.println("完成打包");
	}

	public Pizza getProduct() {
		System.out.println("根据流程2来完成:按照 制作-打包-切片");
		buildPart1();
		buildPart3();
		buildPart2();
		return product;
	}
}
  1. Product产品:创建Pizza产品类
//根据流程2来完成:按照 制作-打包-切片
public class ConcreteProcessB implements PizzaBuilder{
	private Pizza product;

	public ConcreteProcessB() {
		product = new Pizza();
	}

	public void buildPart1() {
		System.out.println("完成制作");
	}

	public void buildPart2() {
		System.out.println("完成切片");
	}

	public void buildPart3() {
		System.out.println("完成打包");
	}

	public Pizza getProduct() {
		System.out.println("根据流程2来完成:按照 制作-打包-切片");
		buildPart1();
		buildPart3();
		buildPart2();
		return product;
	}
}
  1. Director指挥者:创建指挥者
//指挥者,根据不同具体创建者实现产品的生产
public class Director {
	private PizzaBuilder builder;

	public Director(PizzaBuilder builder) {
		this.builder = builder;
	}

	//返回产品pizza
	public Pizza construct() {
		return builder.getProduct();
	}
}
  1. 外部调用,走不同的流程购买pizza
public class Client {
	public static void main(String[] args) {
		
	//根据流程1来完成:按照 制作-切片-打包
		//具体创建者 
		PizzaBuilder builder = new ConcreteProcessA();
		//指挥者
		Director director = new Director(builder);
		
		//指挥者调用construct方法,根据 不同的具体创建者 创建产品
		Pizza product = director.construct();
		
		System.out.println("-------------");
	//根据流程2来完成:按照 制作-打包-切片
		builder =  new ConcreteProcessB();
		director = new Director(builder);
		
		product = director.construct();
		
	}
}
//输出结果
根据流程1来完成:按照 制作-切片-打包
完成制作
完成切片
完成打包
-------------
根据流程2来完成:按照 制作-打包-切片
完成制作
完成打包
完成切片

3.3 UML类图

在这里插入图片描述

四、优缺点

4.1 优点

  • 建造者模式将对象的构造过程封装在具体建造者中,不同的具体建造者可以得到该对象的不同表示
  • 不同的具体建造者之间相互独立,可以比较方便的替换具体建造者或增加新的具体建造者
  • 可以更加精细有效的控制对象的构造过程。将复杂产品的创建步骤分解到不同的方法中,使得创建过程更加精细
  • 增加新的具体建造者时,不需要修改指挥者的代码,满足"开闭原则"

4.2 缺点

  • 建造者模式创建的产品,他们的组成部分相似,如果产品之间的差异性很大,就不适合使用建造者模式
  • 如果产品的内部变化较大,那么Builder和ConcreteBuilder也要同步修改,维护成本较大

五、应用场景

建造者模式主要是针对复杂对象的创建,如果创建简单对象的话通常使用工厂模式进行创建。两者可以结合使用

建造者模式主要适用于以下应用场景

  • 相同的方法,不同的执行顺序,产生不同的结果
  • 多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同
  • 产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用
  • 初始化一个对象特别复杂,参数多,而且很多参数都具有默认值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值