一. Builder 模式
二. 使用例子
三. Spring 中的 Builder 模式
Builder 模式, 构建者, 构造者模式, 在《图解设计模式》中归为 生成实例 一栏, 该模式用于组装具有复杂结构的实例;
当需要逐步获取对象的初始值时, 可以使用 Builder 模式;
一. Builder 模式角色
Builder: 建造者, Builder 角色负责定义用来生成实例的接口 API,Builder 角色中准备了用于生成实例的具体方法;
ConcreteBuilder: 具体的建造者, 负责实现 Builder 接口的的类, 定义了生成实例时实际调用的方法, 定义了获取最终生成结果的方法;
Director: 监工, 负责使用 Builder 角色的接口来生成实例, 不依赖于 ConcreteBuilder;
二. 使用例子
Demo: 比如有一段预约信息, 将其解析为 预约 对象; 预约信息如下:"Date, November 5, Headcount, 250, City, Shanghai, DollarsPerHead, 60,HasSite, false";
date 为预约日期, headCount 为预期来人数, city 为城市, DollarsPerHead 为人均预算, hasSite 为是否提供地址 (比如预约某场演出, 是否给表演者提供地点了);
类结构图:
预约信息 Reservation.java
- @Getter
- @Setter
- @ToString //lombok 的注解, 方便代码查看以及编写
- public class Reservation {
- //Date, November 5, Headcount, 250, City, Shanghai, DollarsPerHead, 60,HasSite, false
- private Date date;
- private int headCount;
- private String city;
- private double dollarsPerHead;
- private boolean hasSite;
- }
ReservationBuilder.java
- public interface ReservationBuilder {
- public ReservationBuilder futurize(Date date) ;
- public ReservationBuilder setCity(String city);
- public ReservationBuilder setDollarsPerHead(double dollarsPerHead);
- public ReservationBuilder setSite(boolean hasSite);
- public ReservationBuilder setHeadCount(int headCount);
- Reservation build();
- }
DefaultReservationBuilder.java
- public class DefaultReservationBuilder implements ReservationBuilder{
- private Date date;
- private int headCount;
- private String city;
- private double dollarsPerHead;
- private boolean hasSite;
- public ReservationBuilder futurize(Date date) {
- this.date=date;
- return this;
- }
- public ReservationBuilder setCity(String city) {
- this.city=city;
- return this;
- }
- public ReservationBuilder setDollarsPerHead(double dollarsPerHead) {
- this.dollarsPerHead=dollarsPerHead;
- return this;
- }
- public ReservationBuilder setSite(boolean hasSite) {
- this.hasSite=hasSite;
- return this;
- }
- public ReservationBuilder setHeadCount(int headCount) {
- this.headCount=headCount;
- return this;
- }
- public Reservation build() {
- Reservation reservation = new Reservation();
- reservation.setCity(this.city);
- reservation.setDate(this.date);
- reservation.setDollarsPerHead(this.dollarsPerHead);
- reservation.setHasSite(this.hasSite);
- reservation.setHeadCount(this.headCount);
- return reservation;
- }
- }
ReservationDirector.java
- public class ReservationDirector {
- private ReservationBuilder builder;
- public ReservationDirector(ReservationBuilder builder) {
- this.builder=builder;
- }
- public Reservation construct(String input) throws Exception {
- String[] strings = input.split(",\\s*");
- for(int i=0;i<strings.length-1;i++) {
- String type=strings[i];
- String val=strings[i+1];
- if("date".equalsIgnoreCase(type)) {
- int year = Calendar.getInstance().get(Calendar.YEAR);
- String res=year+ ""+val.substring(0, 3)+" "+val.substring(val.length()-2);
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy MMM dd", Locale.ENGLISH);
- Date date = sdf.parse(res);
- builder.futurize(date);
- }else if("headcount".equalsIgnoreCase(type)) {
- builder.setHeadCount(Integer.valueOf(val));
- }else if("city".equalsIgnoreCase(type)) {
- builder.setCity(val);
- }else if("dollarsperHead".equalsIgnoreCase(type)) {
- builder.setDollarsPerHead(Double.parseDouble(val));
- }else if("hassite".equalsIgnoreCase(type)) {
- builder.setSite(Boolean.parseBoolean(val));
- }
- }
- Reservation reservation = builder.build();
- return reservation;
- }
- }
测试方法:
- public static void main(String[] args) throws Exception {
- //Date, November 5, Headcount, 250, City, Shanghai, DollarsPerHead, 60,HasSite, false
- String input="Date, November 5, Headcount, 20, City, Shanghai, DollarsPerHead, 60,HasSite, false";
- ReservationBuilder builder=new DefaultReservationBuilder();
- ReservationDirector director=new ReservationDirector(builder);
- Reservation reservation = director.construct(input);
- System.out.println(reservation);
- }
测试输出:
三. Spring 中的 Builder 模式
Spring 中 RequestMappingInfo 中内部接口 Builder , 内部静态类 DefaultBuilder 等, 就是采用了 Builer 模式, RequestMappingInfo 就是监工 Director 对象; 类结构图:
- public interface Builder {
- /* Set the path patterns*/
- Builder paths(String... paths);
- /* Set the request method conditions*/
- Builder methods(RequestMethod... methods);
- /* Set the request param conditions*/
- Builder params(String... params);
- /*Set the header conditions*/
- Builder headers(String... headers);
- /* Set the consumes conditions*/
- Builder consumes(String... consumes);
- /* Set the produces conditions*/
- Builder produces(String... produces);
- /* Set the mapping name*/
- Builder mappingName(String name);
- /* Set a custom condition to use*/
- Builder customCondition(RequestCondition<?> condition);
- /* Provide additional configuration needed for request mapping purposes*/
- Builder options(BuilderConfiguration options);
- /** Build the RequestMappingInfo*/
- RequestMappingInfo build();
- }
创建 RequestMappingInfo 对象地方: 作用就是解析 RequestMapping 注解生成对应 RequestMappingInfo 对象;
Builder 方法大部分返回值为 Builder 类型, 作用是为了链式执行, 看起来生成 RequestMappingInfo 对象代码只有一句简洁;
来源: https://www.cnblogs.com/lvbinbin2yujie/p/10350847.html