您的位置:

构建者模式

构建者模式(Builder Pattern)是一种创建型设计模式。该模式通过一步步构建的方式创建复杂对象。在本篇文章中,我们将从以下几个方面对构建者模式进行详细的阐述:

一、基本定义

构建者模式的主要思想是将一个复杂对象的构建过程与它的表示分离,从而同样的构建过程可以变换不同的表示。该模式将对象的构建过程简单化,用户无需知道类的内部结构,即可获取到复杂的对象。


public interface Item {
    public String name();
    public Packing packing();
    public float price();
}

二、角色说明

下面介绍构建者模式中的几个角色:

  • Product(产品):被构建的复杂对象。
  • Builder(构建者):抽象的接口或者抽象类,定义了复杂对象的构建过程。
  • ConcreteBuilder(具体的构建者):实现Builder接口,负责具体的构建过程。
  • Director(指挥者):负责调用Builder接口并构造复杂对象,包含一个Builder引用。

三、使用场景

构建者模式通常应用于以下几种情况:

  • 需要生产的产品具有复杂的内部结构。
  • 需要生产的产品的构建过程有多种可能性。
  • 需要在不同的情况下构建不同的表示。
  • 需要隐藏复杂对象的创建过程,使得客户端可以直接操作最终的产品。

四、优缺点

构建者模式的优点包括:

  • 将对象的构建过程与表示分离,使得同样的构建过程可以得到不同的表示。
  • 隐藏了复杂对象的创建过程,使得客户端可以直接操作最终的产品。

构建者模式的缺点包括:

  • 需要定义多个Builder类,增加了系统的复杂度。
  • 建造者模式的创建对象是有顺序的,所以一旦顺序出错的话,程序将出错。

五、代码实现

下面展示一个例子,我们创建一个汉堡店,提供各种不同口味的汉堡,顾客可以自己选择口感和配料,店铺会根据顾客的口味构建汉堡,并将最终的汉堡呈现给顾客。

1. Item接口

我们定义一个Item接口,表示可能购买的食品。


public interface Item {
   public String name();
   public Packing packing();
   public float price();
}

2. Packing接口

我们再定义一个Packing接口,表示购物袋等包装材料。


public interface Packing {
   public String pack();
}

3. 容器实现类

我们通过创建实现Packing接口的类 来包装Item接口。


public class Wrapper implements Packing {

   @Override
   public String pack() {
      return "Wrapper";
   }
}
public class Bottle implements Packing {

   @Override
   public String pack() {
      return "Bottle";
   }
}

4. 汉堡实现类

我们创建一个实现Item接口的抽象类,以便于提供默认的功能


public abstract class Burger implements Item {

   @Override
   public Packing packing() {
      return new Wrapper();
   }

   @Override
   public abstract float price();
}
public abstract class ColdDrink implements Item {

    @Override
    public Packing packing() {
       return new Bottle();
    }

    @Override
    public abstract float price();
}

5. 食品实现类

我们创建扩展Burger和ColdDrink的实体类。


public class VegBurger extends Burger {

    @Override
    public float price() {
       return 25.0f;
    }

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

    @Override
    public float price() {
        return 50.5f;
    }

    @Override
    public String name() {
       return "Chicken Burger";
    }
}
public class Coke extends ColdDrink {

    @Override
    public float price() {
       return 30.0f;
    }

    @Override
    public String name() {
       return "Coke";
    }
}
public class Pepsi extends ColdDrink {

    @Override
    public float price() {
        return 35.0f;
    }

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

6. Meal类

我们创建一个Meal类,其中包含各种Item,并提供一个计算金额的方法。


import java.util.ArrayList;
import java.util.List;

public class Meal {
   private List
    items = new ArrayList
    ();

   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());
      }
   }
}

    
   

7. MealBuilder类

我们创建一个MealBuilder类,用于创建不同类型的Meal对象。


public 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;
    }
}

8. Demo类

我们创建一个Demo类,展示使用MealBuilder的过程。


public class Demo {
    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());
    }
}

六、总结

构建者模式的优点是将对象的构建过程与表示分离,使得同样的构建过程可以得到不同的表示;隐藏了复杂对象的创建过程,用户无需知道类的内部结构,即可获取到复杂的对象。而缺点在于需要定义多个Builder类,建造者模式的创建对象是有顺序的,所以一旦顺序出错的话,程序将出错。