简介
建造者模式(Builder Pattern)将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示,属于创建型设计模式。
通用模板
-
创建产品类:要创建的产品类对象。
// 产品类 public class Product { // 产品组成部件1 public String part1; // 产品组成部件2 public String part2; @Override public String toString() { return "Product{" + "part1='" + part1 + '\'' + ", part2='" + part2 + '\'' + '}'; } }
-
创建建造者接口:建造者的抽象类,规范产品对象的各个组成部分的创建,一般由子类实现具体的创建过程。
// 构造者接口 public interface IBuilder { // 返回构建好的产品 Product build(); }
-
创造具体建造者类:具体的Builder类,根据不同的业务逻辑,具体化对象的各个组成部分的创建。
// 具体建造者类 public class Builder implements IBuilder{ // 要建造的产品 private Product product = new Product(); // 组合产品的部件1 public Builder withPart1(String part1){ product.part1 = part1; return this; } // 组合产品的部件2 public Builder withPart2(String part2){ product.part2 = part2; return this; } // 建造最终的产品 public Product build() { return product; } }
模板测试
- 代码
public class Client { public static void main(String[] args) { Builder builder = new Builder(); Product product = builder.withPart1("part1").withPart2("part2").build(); System.out.println(product); } }
- 结果
Product{part1='part1', part2='part2'}
应用场景
建造者模式在日常生活中是很常见的。比如我们在买车的时候会有低配、标配和高配,也有可能会增配、减配。这个选择的过程,就是在运用建造者模式。 从定义来看,建造者模式和工厂模式是非常相似的,和工厂模式一样,具备创建与表示分离的特性。建造者模式唯一区别于工厂模式的是针对复杂对象的创建。也就是说,如果创建简单对象,通常都是使用工厂模式进行创建;而如果创建复杂对象,就可以考虑使用建造者模式。 当需要创建的产品具备复杂创建过程时,可以抽取出共性创建过程,然后交由具体实现类自定义创建流程,使得同样的创建行为可以生产出不同的产品,分离了创建与表示,使创建产品的灵活性大大增加。建造者模式主要适用于以下应用场景。
(1)相同的方法,不同的执行顺序,产生不同的结果。
(2)多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
(3)产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。
(4)初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。
“生搬硬套”实战
场景描述
构建一个汉堡套餐。
代码开发
-
创建产品(这里指的是汉堡)类:
// 汉堡套餐类 public class Meal { public String burger; public String drink; public boolean fries; // 打印套餐详情 @Override public String toString() { return "Meal{" + "burger='" + burger + '\'' + ", drink='" + drink + '\'' + ", fries=" + fries + '}'; } }
-
创建建造者接口:
// 构造者接口 public interface IBuilder { // 返回构建好的产品 Meal build(); }
-
创造具体建造者(这里指的是汉堡套餐)类:
// 汉堡套餐类 public class MealBuilder implements IBuilder{ private Meal meal = new Meal(); public MealBuilder withBurger(String burger) { meal.burger = burger; return this; } public MealBuilder withDrink(String drink) { meal.drink = drink; return this; } public MealBuilder withFries(boolean fries) { meal.fries = fries; return this; } public Meal build() { return meal; } }
至此,我们就通过“生搬硬套”建造者模式的模板设计出一套建造一个汉堡套餐代码,接下来我们进行测试:
- 测试代码
public class Client {
public static void main(String[] args) {
MealBuilder builder = new MealBuilder();
Meal meal = builder.withBurger("Big Mac")
.withDrink("Coke")
.withFries(true)
.build();
System.out.println(meal);
}
}
- 结果
Meal{burger='Big Mac', drink='Coke', fries=true}
总结
对于用户而言,使用建造者模式只需指定需要创建的类型就可以获得对象,创建过程及细节不需要了解。根据建造者模式的定义,可以简单地理解为两层含义。
(1)构建与表示分离:构建代表对象创建,表示代表对象行为、方法,也就是将对象的创建与行为进行分离(对应到Java代码,其实就是使用接口规定行为,然后由具体的实现类进行构建)。
(2)创建不同的表示:也就是具备同样的行为,但是却由于构建的行为顺序不同或其他原因可以创建出不同的表示。