建造者模式描述是:封装一个产品的构造过程,并允许按步骤构造,是在创建一个对象时使用的。我觉得这种模式还是挺常用的,比如Lombok插件的@Builder。下面就来学习下这个模式的细节。
场景描述
假设我们现在要创建一个度假计划,客人可以选择宾馆以及各种门票、餐厅定位,甚至可以选择登记参加特殊的活动。我们正常的构造方式很可能像下面一样:
|
|
可见这种方式要写好多个构造函数,显得笨重,看看建造者模式如何解决这个问题。
代码示例
创建Builder类
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354public class VocationBuilder {private String beginDate;private String endDate;private String hotel;private String restaurant;private List<String> tickets;/*** 指定假期开始时间*/public VocationBuilder setBeginDate(String date) {this.beginDate = date;return this;}/*** 指定假期结束时间*/public VocationBuilder setEndDate(String date) {this.endDate = endDate;return this;}/*** 指定入住酒店*/public VocationBuilder setHotel(String hotel) {this.hotel = hotel;return this;}/*** 指定就餐餐厅*/public VocationBuilder setRestaurant(String restaurant) {this.restaurant = restaurant;return this;}/*** 指定景点门票*/public VocationBuilder setTicket(List<String> tickets) {this.tickets = tickets;return this;}/*** 建造出Vocation对象的方法*/public Vocation build() {return new Vocation(beginDate, endDate, hotel, restaurant, tickets);}}创建Vocation实体类
12345678910111213141516171819202122232425262728293031323334public class Vocation {private String beginDate;private String endDate;private String hotel;private String restaurant;private List<String> tickets;public Vocation(String beginDate, String endDate, String hotel, String restaurant, List<String> tickets) {this.beginDate = beginDate;this.endDate = endDate;this.hotel = hotel;this.restaurant = restaurant;this.tickets = tickets;}/*** 创建builder的静态方法*/public static VocationBuilder builder() {return new VocationBuilder();}public String toString() {StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("BeginDate: ").append(beginDate).append("\n").append("EndDate: ").append(endDate).append("\n").append("Hotel: ").append(hotel).append("\n").append("Restaurant: ").append(restaurant);return stringBuilder.toString();}}测试
123456789101112public class Test {public static void main(String[] args) {Vocation vocation = Vocation.builder().setBeginDate("2020/01/01").setEndDate("2018/01/04").setHotel("wanda").setRestaurant("yao").setTicket(new ArrayList<>()).build();System.out.println(vocation);}}
建造者模式实例化对象时优雅多了,其核心内容就是额外多加了一个对应的Builder类,同时在每个set方法中将Builder自身返回,这样可以使用Fluent的方式来构造对象了。建造者模式相对而言还是比较简单的,本章节就到这里了。