设计模式(4/23) - 建造者(Builder)模式

14 阅读3分钟

建造者(Builder)模式

1 概述

  • 建造者模式是一种创建型设计模式,它允许你创建复杂对象的步骤与表示方式相分离。
  • 建造者模式是一种创建型设计模式,它的主要目的是将一个复杂对象的构建过程与其表示相分离,从而可以创建具有不同表示形式的对象。

2 优缺点及应用场景

2.1 优点

  • 1)更好的控制:建造者模式提供了一种更好的控制复杂对象创建的方式。
  • 2)分离复杂构造代码:将复杂对象的创建过程封装在一个类中,客户端无需了解构建细节。
  • 3)易于扩展:可以通过实现不同的建造者来创建不同的表示。

2.2 缺点

  • 1)可能产生大量的代码:每一个具体的 Builder 都需要实现所有步骤,可能会导致代码量增加。
  • 2)不适合变化大的产品:如果产品的组成部分经常变化,建造者模式可能会增加系统的复杂性。

2.3 应用场景

  • 1)需要生成的对象具有复杂的内部结构。
  • 2)需要生成的对象内部属性相互依赖。
  • 3)AlertDialog、Okhttp、Glide 等等。

3 结构

  • 1)产品(Product):要构建的复杂对象。产品类通常包含多个部分或属性。
  • 2)抽象建造者(Builder):定义了构建产品的抽象接口,包括构建产品的各个部分的方法。
  • 3)具体建造者(Concrete Builder):实现抽象建造者接口,具体确定如何构建产品的各个部分,并负责返回最终构建的产品。
  • 4)指导者(Director):负责调用建造者的方法来构建产品,指导者并不了解具体的构建过程,只关心产品的构建顺序和方式。

4 实现

4.1 UML 类图

建造者模式.jpg

4.2 代码示例

// 创建一个表示食物条目
interface Item {
  public String name();

  public Packing packing();

  public float price();
}

// 创建一个表示食物包装的接口
interface Packing {
  public String pack();
}

// 创建实现 Packing 接口的实体类:包装纸
class Wrapper implements Packing {
  @Override
  public String pack() {
    return "Wrapper";
  }
}

// 创建实现 Packing 接口的实体类:瓶子
class Bottle implements Packing {
  @Override
  public String pack() {
    return "Bottle";
  }
}

// 创建实现 Item 接口的抽象类,该类提供了默认的功能:汉堡
abstract class Burger implements Item {
  @Override
  public Packing packing() {
    return new Wrapper();
  }

  @Override
  public abstract float price();
}

// 创建实现 Item 接口的抽象类,该类提供了默认的功能:冷饮
abstract class ColdDrink implements Item {
  @Override
  public Packing packing() {
    return new Bottle();
  }

  @Override
  public abstract float price();
}

// 创建扩展了 Burger 的实体类:蔬菜汉堡
class VegBurger extends Burger {
  @Override
  public float price() {
    return 25.0f;
  }

  @Override
  public String name() {
    return "Veg Burger";
  }
}

// 创建扩展了 Burger 的实体类:肌肉汉堡
class ChickenBurger extends Burger {
  @Override
  public float price() {
    return 50.5f;
  }

  @Override
  public String name() {
    return "Chicken Burger";
  }
}

// 创建扩展了 ColdDrink 的实体类:可口可乐
class Coke extends ColdDrink {
  @Override
  public float price() {
    return 30.0f;
  }

  @Override
  public String name() {
    return "Coke";
  }
}

// 创建扩展了 ColdDrink 的实体类:百事可乐
class Pepsi extends ColdDrink {
  @Override
  public float price() {
    return 35.0f;
  }

  @Override
  public String name() {
    return "Pepsi";
  }
}

// 创建一个 Meal 类,带有上面定义的 Item 对象
class Meal {
  private List<Item> items = new ArrayList<Item>();

  public void addItem(Item item) {
    items.add(item);
  }

  public float getCost() {
    float cost = 0.0f;
    for (Item item : items) {
      cost += item.price();
    }
    return cost;
  }

  public void showItems() {
    for (Item item : items) {
      System.out.print("Item : " + item.name());
      System.out.print(", Packing : " + item.packing().pack());
      System.out.println(", Price : " + item.price());
    }
  }
}

// 创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象
class MealBuilder {
  public Meal prepareVegMeal() {
    Meal meal = new Meal();
    meal.addItem(new VegBurger());
    meal.addItem(new Coke());
    return meal;
  }

  public Meal prepareNonVegMeal() {
    Meal meal = new Meal();
    meal.addItem(new ChickenBurger());
    meal.addItem(new Pepsi());
    return meal;
  }
}

// 使用示例
public class BuilderPatternDemo {
  public static void main(String[] args) {
    MealBuilder mealBuilder = new MealBuilder();

    Meal vegMeal = mealBuilder.prepareVegMeal();
    System.out.println("Veg Meal");
    vegMeal.showItems();
    System.out.println("Total Cost: " + vegMeal.getCost());

    Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
    System.out.println("\n\nNon-Veg Meal");
    nonVegMeal.showItems();
    System.out.println("Total Cost: " + nonVegMeal.getCost());
  }
}
  • 执行程序,输出结果:
Veg Meal
Item : Veg Burger, Packing : Wrapper, Price : 25.0
Item : Coke, Packing : Bottle, Price : 30.0
Total Cost: 55.0


Non-Veg Meal
Item : Chicken Burger, Packing : Wrapper, Price : 50.5
Item : Pepsi, Packing : Bottle, Price : 35.0
Total Cost: 85.5

5 总结

  • 建造者模式通过将一个复杂对象的构建过程分解为多个简单的步骤,使得构建过程与表示分离。它适用于需要生成复杂对象的场景,并且允许使用相同的构建过程创建不同的表示。尽管建造者模式增加了代码量,但它提供了更好的控制和灵活性。