一 什么是建造者模式
建造者模式是一种创建型设计模式,
它的主要目的是将一个复杂对象的构建过程与其表示相分离,
从而可以创建具有不同表示形式的对象。
建造者模式非常适合当一个类的构造函数参数过多,或者有多个构造函数重载时使用。
二 建造者模式的结构
- 1、产品,要构建的复杂对象。产品类通常包含多个部分或属性。
- 2、抽象接口,定义了构建产品的抽象接口,包括构建产品的各个部分的方法。
- 3、接口实现类,实现抽象建造者接口,具体确定如何构建产品的各个部分,并负责返回最终构建的产品。
- 4、调用者,负责调用建造者的方法来构建产品,指导者并不了解具体的构建过程,只关心产品的构建顺序和方式。
三 建造者模式的优缺点
优点:
- 1、灵活:构建过程和表示分离,使用不同的部分能组成多个表示(产品)。
- 2、解耦:不必关心对象的创建细节。
- 3、代码复用性强:可以通过使用不同的建造者建成不同的产品。
缺点
- 复杂度高:建造者模式适用于创建复杂对象,当对象结构简单或参数较少时,使用建造者模式显得有些复杂。
四 适用场景
建造者模式适用于一个类的构造函数中的参数较多并且可选时;或者创建对象的步骤较多,并且需要不同的配置时。
五 具体实现
场景描述
假如我们正在制作汉堡(产品),其中每种汉堡可以选择不同的面包类型、肉类、芝士和蔬菜,也可以不选择全部;现在我们需要制作出豪华汉堡(芝麻面包+牛肉饼+芝士+生菜+番茄)以及简约汉堡(普通面包+鸡肉饼+生菜),由于需要建造的对象的组件不同,且组件的选择范围相同,我们可以使用建造者模式。
角色分析
- 首先,我们确定了豪华汉堡和简约汉堡为最终需要实现的产品;
- 其次,我们需要定义构建产品的抽象建造者,包括多个构成产品的组件的构建方法和一个返回产品的方法。
- 然后, 我们来定义抽象建造者对于不同的创建过程可以用不同的类进行实现
- 最后,我们通过调用者使用不同的组件来创建不同的产品。
代码实现
产品类
public class Burger {
private String bun; //面包类型
private String meat; // 肉类
private String cheese; // 芝士
private String vegetables; // 蔬菜
public void setBun(String bun) {
this.bun = bun;
}
public void setMeat(String meat) {
this.meat = meat;
}
public void setCheese(String cheese) {
this.cheese = cheese;
}
public void setVegetables(String vegetables) {
this.vegetables = vegetables;
}
@Override
public String toString() {
return "Burger{" +
"bun='" + bun + '\'' +
", meat='" + meat + '\'' +
", cheese='" + cheese + '\'' +
", vegetables='" + vegetables + '\'' +
'}';
}
}
抽象建造者
public abstract class BurgerBuilder {
protected Burger burger = new Burger();
public abstract void buildBun();
public abstract void buildMeat();
public abstract void buildCheese();
public abstract void buildVegetables();
public Burger getBurger(){
return burger;
}
}
豪华汉堡建造者
public class ExpensiveBurger extends BurgerBuilder{
@Override
public void buildBun() {
burger.setBun("芝麻面包");
}
@Override
public void buildMeat() {
burger.setMeat("牛肉饼");
}
@Override
public void buildCheese() {
burger.setCheese("芝士");
}
@Override
public void buildVegetables() {
burger.setVegetables("生菜+番茄");
}
}
简单汉堡建造者
public class SimpleBurger extends BurgerBuilder{
@Override
public void buildBun() {
burger.setBun("普通面包");
}
@Override
public void buildMeat() {
burger.setMeat("鸡肉饼");
}
@Override
public void buildCheese() {}
@Override
public void buildVegetables() {
burger.setVegetables("生菜");
}
}
调用者
public class BurgerDirector {
private BurgerBuilder burgerBuilder;
public Burger getBurger() {
return burgerBuilder.getBurger();
}
public void setBurgerBuilder(BurgerBuilder burgerBuilder) {
this.burgerBuilder = burgerBuilder;
}
public Burger construct() {
burgerBuilder.buildBun();
burgerBuilder.buildMeat();
burgerBuilder.buildCheese();
burgerBuilder.buildVegetables();
return burgerBuilder.getBurger();
}
}
测试类
public class Test {
public static void main(String[] args) {
BurgerDirector director = new BurgerDirector();
//指导建造豪华汉堡
director.setBurgerBuilder(new ExpensiveBurger());
director.construct();
Burger burger1 = director.getBurger();
System.out.println(burger1.toString());
//建造简约汉堡
director.setBurgerBuilder(new SimpleBurger());
director.construct();
Burger burger2 = director.getBurger();
System.out.println(burger2.toString());
}
}