05-建造者模式

建造者模式

建造者(Builder)模式又称生成器模式,可以实现分步骤创建复杂对象,使用相同的创建代码生成不同类型和形式的对象。

建造者模式和工厂模式的关注点不同,建造者模式关注的是对象的组装过程,而工厂模式更注重的是对象的创建过程。两者可以结合使用。

模式的结构与实现

建造者模式的主要角色:

  • 产品角色(Product):包含多个组成部件的复杂对象,由具体创建者来创建其各个零部件。
  • 抽象建造者(Builder):包含创建产品各个子部件的抽象方法和接口,通常还包含一个返回复杂产品的方法getResult()。
  • 具体建造者(Concrete Builder):实现Builder接口,完成复杂产品的各个部件的具体创建方法。
  • 指挥者(Director):调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品信息。

UML类图

实例

需求:在肯德基中,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。
实现代码步骤如下:

  1. 创建产品类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    public class Product {
    private String coke;//可乐
    private String hamburger;//汉堡
    private String fries;//薯条
    private String chickenWings;//鸡翅

    public void setCoke(String coke) {
    this.coke = coke;
    }

    public void setHamburger(String hamburger) {
    this.hamburger = hamburger;
    }

    public void setFries(String fries) {
    this.fries = fries;
    }

    public void setChickenWings(String chickenWings) {
    this.chickenWings = chickenWings;
    }

    public void show(){
    System.out.println("你的选择如下:");
    if(coke!=null&&coke.trim()!=""){
    System.out.println("可乐");
    }
    if(hamburger!=null&&hamburger.trim()!=""){
    System.out.println("汉堡");
    }
    if(fries!=null&&fries.trim()!=""){
    System.out.println("薯条");
    }
    if(chickenWings!=null&&chickenWings.trim()!=""){
    System.out.println("鸡翅");
    }
    }
    }
  2. 创建抽象建造者
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public abstract class Builder {
    Product product = new Product();

    /**
    * 建造产品方法
    */
    abstract void buildProduct();

    Product getResult() {
    return product;
    }
    }
  3. 创建具体建造者,这里只有两个套餐所以有两个具体建造者
    1
    2
    3
    4
    5
    6
    7
    8
    public class ConcreteBuilder1 extends Builder {
    @Override
    void buildProduct(){
    product.setCoke("可口可乐");
    product.setHamburger("汉堡");
    product.setChickenWings("鸡翅");
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    public class ConcreteBuilder2 extends Builder{
    @Override
    void buildProduct(){
    product.setCoke("可口可乐");
    product.setHamburger("汉堡");
    product.setFries("薯条");
    }
    }
  4. 创建指挥者
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class Director {
    private Builder builder;

    void setBuilder(Builder builder) {
    this.builder = builder;
    }

    Product construct() {
    builder.buildProduct();
    return builder.getResult();
    }
    }
  5. client根据调用工厂类静态方法,通过不通参数创建不同的产品实例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Client {
    public static void main(String[] args) {
    Director director = new Director();
    ConcreteBuilder1 concreteBuilder = new ConcreteBuilder1();//不同套餐输出不同
    director.setBuilder(concreteBuilder);
    Product construct = director.construct();
    construct.show();
    }
    }
  6. 结果输出
1
2
3
4
你的选择如下:
可乐
汉堡
鸡翅

总结

优点

  • 封装性好,构建与表示分离。
  • 扩展性好,各个具体建造者互相独立。
  • 客户端不需要知道产品内部组成细节,建造者可以对产品创建过程逐渐细化。

缺点

  • 产品的组成部分必须相同,限制了适用范围。
  • 如果产品内部发生变化,需要建造者同步修改,维护成本高。

应用场景

  1. 相同的方法,不同执行顺序,产生不同结果。
  2. 构造复杂对象。

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!