【设计模式】第三章:建造者模式详解及应用案例

系列文章

【设计模式】七大设计原则
【设计模式】第一章:单例模式
【设计模式】第二章:工厂模式
【设计模式】第三章:建造者模式
【设计模式】第四章:原型模式
【设计模式】第五章:适配器模式
【设计模式】第六章:装饰器模式
【设计模式】第七章:代理模式
【设计模式】第八章:桥接模式
【设计模式】第九章:外观模式 / 门面模式
【设计模式】第十章:组合模式
【设计模式】第十一章:享元模式
【设计模式】第十二章:观察者模式
【设计模式】第十三章:模板方法模式
【设计模式】第十四章:策略模式
【设计模式】第十五章:责任链模式
【设计模式】第十六章:迭代器模式
【设计模式】第十七章:状态模式
【设计模式】第十八章:备忘录模式
【设计模式】第十九章:访问者模式
【设计模式】第二十章:解释器模式
【设计模式】第二十一章:命令模式
【设计模式】第二十二章:中介者模式



一、定义

摘自百度百科:建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式是将一个复杂对象的构建与其分离开,使之可以通过同样构建过程来创建不同的内容。


二、角色分类

建造者模式共有四种角色,他们分别为:

具体产品

最终被创建的对象

抽象建造者

描述产品对象的各个组成部分的建造方法

具体建造者

根据业务的不同,负责对象各部分的建造过程

使用者

负责创建对象的各个部分,保证对象按顺序或各部分完整创建


三、实现方式

本文会根据写法不同分为以下两种方式来为大家介绍:

  • 基本写法
  • 链式写法(我更倾向于这种写法)

1. 基本写法

比如:如果你想要自己DIY一辆车,这时候车可以按你的需求来组装(抽象建造者),而零件是由你来决定组装什么牌子的(具体建造者),而这辆车由你来组装(使用者),但是无论怎么组装它都是一辆车(具体产品)

具体产品

@Data
@ToString
public class Car {

	/**
	 * 发动机
	 */
	private String engine;

	/**
	 * 轮子
	 */
	private String wheel;

	/**
	 * 气缸
	 */
	 private String cylinder;

	/**
	 * 车的颜色
	 */
	private String color;
}

抽象建造者

public interface Builder {
	Object build();
}

具体建造者

public class CarBuilder implements Builder {

	private Car car = new Car();

	public CarBuilder engine(String engine){
		car.setEngine(engine);
		return this;
	}

	public CarBuilder wheel(String wheel){
		car.setWheel(wheel);
		return this;
	}

	public CarBuilder cylinder(String cylinder){
		car.setCylinder(cylinder);
		return this;
	}

	pulic CarBuilder color(String color){
		car.setColor(color);
		return this;
	}

	@Override
	public Car build(){
		return this.car;
	}
}

使用者

public class Test {

	public static void main(String[] args) {
		CarBuilder builder = new CarBuilder();
		builder.engine("发动机1");
		builder.wheel("轮子1");
		builder.cylinder("气缸1");
		builder.color("黑色");
		Car car = builder.build();
		System.out.println(car);
	}
}

执行结果

这种写法便是建造者的基本模式,但是一个一个设置进去太麻烦了,那么有没有更简单的写法呢?接下来我们介绍一下链式写法的建造者模式。

2. 链式写法

具体产品

@Data
@ToString
public class Car {

	/**
	 * 发动机
	 */
	private String engine;

	/**
	 * 轮子
	 */
	private String wheel;

	/**
	 * 气缸
	 */
	 private String cylinder;

	/**
	 * 车的颜色
	 */
	private String color;
}

抽象建造者

public interface Builder {
	Object build();
}

具体建造者

public class CarBuilder implements Builder {

	private Car car = new Car();

	public CarBuilder engine(String engine){
		car.setEngine(engine);
	}

	public CarBuilder wheel(String wheel){
		car.setWheel(wheel);
	}

	public CarBuilder cylinder(String cylinder){
		car.setCylinder(cylinder);
	}

	pulic CarBuilder color(String color){
		car.setColor(color);
	}

	@Override
	public Car build(){
		return this.car;
	}
}

使用者

public class Test {

	public static void main(String[] args) {
		Car car = new CarBuilder()
					.engine("发动机2")
					.wheel("轮子2")
					.cylinder("气缸2")
					.color("白色")
					.build();
		System.out.println(car);
	}
}

执行结果


四、优缺点

优点:

  • 创建与使用分离,建造类之间互相独立,实现了解耦

缺点:

  • 当类比较多的时候,需要创建很多建造类,在一定程度上增加了系统理解难度
  • 当产品内部进行了修改的话,建造类也要修改,当建造类多的时候会增加维护难度

五、应用场景

以下部分内容摘自菜鸟教程

意图: 将一个复杂的构建与其表示相分离,使得同样的构建过程可以有不同的表示
主要解决: 主要解决在软件系统种,有时会面临着“一个复杂对象”的创建工作,其通常由各部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分常面临着剧烈的变化,但是将他们组合在一起的算法却相对稳定。
何时使用: 一些基本部件不会变,而其组合经常变化的时候。
如何解决: 将变与不变分离开。
关键代码: 建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系
应用实例:
去肯德基,汉堡、可乐、薯条、炸鸡是不变的,而其组合是经常变化的,生成出所谓的“套餐”
Java中的StringBuilder
优点:

  1. 建造者独立,易扩展。
  2. 便于控制细节风险。

缺点:

  1. 产品必须有共同点,范围有限制。
  2. 如内部变化复杂,会有很多的建造类。

使用场景:

  • 需要生成的对象具有复杂的内部结构。
  • 需要生成的对象内部属性本身相互依赖。

注意事项: 与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

建造者模式适用于复杂产品的创建过程,比如一个产品会因为业务需求经常变化组成这个产品的各个零件,但是整体组合方式较为稳定的场景下

  • 适用于更注重同一个方法执行顺序不同产生不同结果的场景下
  • 适用于不同零件装配到一个对象产生不同对象的场景下
  • 适用于初始化对象参数多且很多参数有默认值的场景下

六、小结

建造者模式适合于复杂对象的创建,且更注重执行顺序的情况,遇到这种情况我们可以选择建造者模式来将共同的创建过程提取出来,进行自定义的建造,这样的写法更为灵活。


推荐

关注博客和公众号获取最新文章

Bummon’s BlogBummon’s Home公众号

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bummon.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值