设计模式——建造者模式(Builder Pattern)

182 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

建造者模式(Builder Pattern)

定义

建造者模式使用多个简单的对象一步一步构建成一个复杂的对象,也属于创建型模式 一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。

架构图解

建造者模式的 UML 图

使用场景&解决的问题

主要解决在软件系统中,需要构建一个负责的对象,这个复杂的对象由多个子对象组成,但子对象往往会经常变化,但是组合这些子对象的算法是相对稳定的,此时可使用建造者模式。即一些基本部件不会变,而其组合经常变化的时候。

实现细节

核心点:将变与不变分离开

优点&缺点

优点:

1.建造者独立,易扩展

2.便于控制细节风险

缺点:

1.产品必须要有共同点,范围有限制

2.如内部变化负责,会有很多建造类

代码实例

我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒中。冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。

1.创建一个表示食物条目和食物包装的接口

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

public interface Packing {
    public String pack();
}

2.创建实现Packing接口的实体类

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

3.创建实现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();
}

4.构建扩展了上述抽象类的实体类

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

5.创建一个Meal类,带有上面定义的Item对象

import java.util.ArrayList;
import java.util.List;
 
public 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());
      }        
   }    
}

6.创建一个MealBuilder类,实际的builder类负责创建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;
   }
}

经过上述步骤我们可以通过MealBuilder构建我们想要的Meal

注意事项

工厂模式的区别是:建造者模式更加关注与零件装配的顺序。