生成器模式
建造者模式、Builder
生成器模式 也叫建造者模式,可以理解成可以分步骤创建一个复杂的对象。在该模式中允许你使用相同的创建代码生成不同类型和形式的对象。
生成器的结构模式
- **生成器(Builder)**接口声明在所有类型生成器中通用的产品构造的步骤
- **具体的生成器(ConcreteBuilders)**提供构造过程的不同实现。 具体生成器也可以构造不遵循通用接口的产品。
- 产品 (Products) 是最终生成的对象。 由不同生成器构造的产品无需属于同一类层次结构或接口。
- 主管 (Director) 类定义调用构造步骤的顺序, 这样你就可以创建和复用特定的产品配置。
- 客户端 (Client) 必须将某个生成器对象与主管类关联。 一般情况下, 你只需通过主管类构造函数的参数进行一次性关联即可。 此后主管类就能使用生成器对象完成后续所有的构造任务。 但在客户端将生成器对象传递给主管类制造方法时还有另一种方式。 在这种情况下, 你在使用主管类生产产品时每次都可以使用不同的生成器。
案例分析
下面我们将结合一辆汽车的制造过程来模拟一个构建构成。针对汽车这种非常复杂的机械结构,我们需要将汽车各个零部件的组装过程抽取到不同的代码中,最终组成一个完成的产品。下面我们将简化这个过程,模拟一辆汽车的车型产品,命名,颜色喷漆,产品定价等信息。
核心类解释
- 抽象出一个汽车产品
Car
。
- 定义
Builder
接口,规定
Car
的构建步骤和过程。
-
CarBuilder
实现类。
-
CarDirectror
统一构建过程。
代码实现
Car.class
public class Car {/*** 车型 SUV MVP 轿车等*/private String type;/*** 汽车颜色*/private String color;/*** 奥迪 啥的*/private String name;/*** 售价*/private BigDecimal price;public String getType() {return type;}public void setType(String type) {this.type = type;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}public String getName() {return name;}public void setName(String name) {this.name = name;}public BigDecimal getPrice() {return price;}public void setPrice(BigDecimal price) {this.price = price;}@Overridepublic String toString() {return "Car{" +"type=\'" + type + \'\\\'\' +", color=\'" + color + \'\\\'\' +", name=\'" + name + \'\\\'\' +", price=" + price +\'}\';}}
Builder.class
public interface Builder {/*** 定义车型* @param type* @return*/Builder buildType(String type);/*** 定义产品名称* @param name* @return*/Builder buildName(String name);/*** 确定颜色喷漆* @param color* @return*/Builder buildColor(String color);/*** 定价* @param bigDecimal* @return*/Builder buildPrice(BigDecimal bigDecimal);/*** 返回* @return*/Car build();}
CarBuilder.class
public class CarBuilder implements Builder{private final Car car = new Car();@Overridepublic Builder buildColor(String color) {car.setColor(color);return this;}@Overridepublic Builder buildType(String type) {car.setType(type);return this;}@Overridepublic Builder buildName(String name) {car.setName(name);return this;}@Overridepublic Builder buildPrice(BigDecimal bigDecimal) {car.setPrice(bigDecimal);return this;}@Overridepublic Car build() {return car;}}
这里的处理方式只是做解释,其实还是可以进一步抽象
CarBuilder
到具体车型的
Builder
,并在次基础上添加一些验证的功能
CarDirector.class
public class CarDirector {public void mpvCarBuilder(Builder builder){builder.buildName("奥迪");builder.buildType("mpv");builder.buildColor("red");builder.buildPrice(new BigDecimal("400000.00"));}public void suvCarBuilder(Builder builder){builder.buildName("奥迪");builder.buildType("suv");builder.buildColor("black");builder.buildPrice(new BigDecimal("300000.00"));}}
Client.class
public class Client {@Testpublic void builderMvp(){CarDirector carDirector = new CarDirector();Builder builder = new CarBuilder();carDirector.mpvCarBuilder(builder);System.out.println(builder.build().toString());}@Testpublic void buildSuv(){CarDirector carDirector = new CarDirector();Builder builder = new CarBuilder();carDirector.suvCarBuilder(builder);System.out.println(builder.build().toString());}}
总结
在日常开发中我们能经常用到
Builder
设计模式,最常见的就是核心程序中的
StringBuilder
了,在开源框架中我们也经常能够看到,例如Mybatis中的
SqlSourceBuilder
、
XMLConfigBuilder
等等信息
为了灵活构造复杂对象,该对象会有多个成员变量,在外部调用的时候,不需要或者不方便一次性创建出所有的成员变量,在这种情况下,使用多个构造方法去构建对象,很难维护,这时候Builder设计模式解决这个问题,进行
buid()
方法中创建对象,并且将
builder
传入,该
builder
中,维护了传入对象的成员变量。