一、引言
每天进步一点点,坚持才是最快的胜利 ~
今天来学习下方便我们创建对象的设计模式,“建造者模式” ~~
二、 什么是建造者模式
定义:建造者模式又叫生成器模式,是一种对象构建模式。它是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
主要作用:在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。
三、适用场景:
- 相同的方法,不同的执行顺序,产生不同的结果。
- 产品非常复杂,或者产品类中不同的调用顺序产生不同的结果。
- 初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。
四、优缺点
优点:
- 封装型好,客户端不必知道内部实现的细节。
- 建造者独立,容易扩展,符合 "开闭原则"。
- 便于控制细节风险。
缺点:
- 建造者的产品一般具有较多的共同点,组成的部分大多相似。如果产品之间的差异很大,就不适合使用建造者模式,适用范围受到一定的限制。
- 如果产品的内部变化比较复杂,可能会导致需要定义很多的具体建造者类来实现这种变化,会导致系统变得很庞大。
五、建造者模式实现思路图:
角色:
Product(产品类):一个具体的产品对象。
Builder(抽象建造者):创建一个Product对象的各个部件指定的接口/抽象类。
ConcreteBuilder(具体建造者):实现接口,构建和装配各个部件。
Director(指挥者):构建一个使用Builder接口的对象。它主要用来创建一个负责的对象,有两个作用:一是隔离了客户和对象的生产过程;二是负责控制产品对象的生产过程。
六、标准建造者实现
案例:
既然是建造者模式,我们就举个建房子的例子吧。假设建房的步骤:1.地基 2.钢筋工程 3.铺电线 4.粉刷。 要盖一座房子,首先要找一个建筑公司或者工程的承包商(指挥者)。承包商指挥工人(具体的建造者)过来造房子(产品),最后验收。
步骤1: 定义一个抽象的建造者方法
/**
* @Author WangYan
* @Date 2022/8/16 11:26
* @Version 1.0
* 抽象的建造者方法
*/
public abstract class Builder {
abstract void buildA();// 地基
abstract void buildB();// 钢筋工程
abstract void buildC();// 铺电线
abstract void buildD();// 粉刷
// 建造完成,获得产品
abstract Product getProduct();
}
步骤2:产品类
/**
* @Author WangYan
* @Date 2022/8/16 11:29
* @Version 1.0
* 具体的产品:房子
*/
@Data
public class Product {
private String buildA;
private String buildB;
private String buildC;
private String buildD;
}
步骤3:具体的建造工人
/**
* @Author WangYan
* @Date 2022/8/16 11:31
* @Version 1.0
* 具体的建造者 工人
*/
public class Worker extends Builder {
private Product product;
public Worker(){
product = new Product();
}
@Override
void buildA() {
product.setBuildA("地基");
System.out.println("地基建造完成!");
}
@Override
void buildB() {
product.setBuildB("钢筋工程");
System.out.println("钢筋工程建造完成!");
}
@Override
void buildC() {
product.setBuildC("铺电线");
System.out.println("铺电线建造完成!");
}
@Override
void buildD() {
product.setBuildD("粉刷");
System.out.println("粉刷建造完成!");
}
@Override
Product getProduct() {
return product;
}
}
步骤4:指挥者
/**
* @Author WangYan
* @Date 2022/8/16 11:35
* @Version 1.0
* 指挥者
*/
public class Direct {
public Product build(Builder builder){
builder.buildD();
builder.buildA();
builder.buildB();
builder.buildC();
return builder.getProduct();
}
}
/**
* @Author WangYan
* @Date 2022/8/16 11:37
* @Version 1.0
* Test测试
*/
public class Test {
public static void main(String[] args) {
// 指挥
Direct direct = new Direct();
// 指挥具体的工人完成产品
System.out.println(direct.build(new Worker()));
}
}
四、静态内部类的建造者实现
案例:
比如麦当劳的套餐,服务员(具体的建造者)可以随意搭配任意几种产品(零件)组成一款新套餐(产品),然后出售给客户。比标准建造者少了指挥者,主要是因为第二种方式把指挥者交给用户来操作,使得产品的创建更加灵活。
步骤1:抽象的建造者方法
/**
* @Author WangYan
* @Date 2022/6/18 16:56
* @Version 1.0
* 抽象的建造者方法
*/
public abstract class Builder {
/**
* 可以理解为实现产品的每一步方法
* @return
*/
abstract Builder ProductA(String msg);
abstract Builder ProductB(String msg);
abstract Builder ProductC(String msg);
abstract Builder ProductD(String msg);
// 获得产品
public abstract Product getProduct();
}
步骤2:产品类
/**
* @Author WangYan
* @Date 2022/6/18 16:57
* @Version 1.0
* 产品类
*/
@Data
public class Product {
/**
* 产品A
*/
private String productA;
/**
* 产品B
*/
private String productB;
/**
* 产品C
*/
private String productC;
/**
* 产品D
*/
private String productD;
}
步骤3:具体的建造者
/**
* @Author WangYan
* @Date 2022/6/18 17:02
* @Version 1.0
* 具体的建造者 服务员
*/
public class WorderA extends Builder {
private Product product;
public WorderA(){
this.product = new Product();
}
@Override
Builder ProductA(String msg) {
product.setProductA(msg);
return this;
}
@Override
Builder ProductB(String msg) {
product.setProductB(msg);
return this;
}
@Override
Builder ProductC(String msg) {
product.setProductC(msg);
return this;
}
@Override
Builder ProductD(String msg) {
product.setProductD(msg);
return this;
}
@Override
public Product getProduct() {
return this.product;
}
}
步骤4:客户端调用
/**
* @Author WangYan
* @Date 2022/6/18 17:07
* @Version 1.0
* 客户端调用
*/
public class Test {
public static void main(String[] args) {
WorderA worderA = new WorderA();
// 可以随意搭配
Product product = worderA
.ProductC("可乐")
.ProductB("汉堡")
.ProductA("薯条")
.getProduct();
System.out.println(product);
}
}
总结:
标准建造者和内部类建造者相比,内部类的方式少了 指挥者(Director),而是用户替代了指挥者,使得产品的创建更加灵活!!
拜拜~
有任何问题欢迎大家指出~
Thank You !