设计模式-建造者模式

178 阅读5分钟

文章结构:意义是什么,解决了什么,实例,解释,图解

意义:

什么是建造者模式,(Builder Pattern) 就是使用多个对象一步步的构建成一个复杂的对象,同样这种设置模式是属于创建型模式,其核心思想就是将一个复杂的构建与其分离,使得同样的构建过程创建不同的表示

解决了:

主要是解决了在系统系统中,面临一个复杂对象的创建工作,通常由各个部分的子对象用一定的算法构成,由于需求的变化,这个复杂对象通常面临着剧烈的变法,这是就需要建造者模式使用相对稳定的算法将其组合在一起;

优点;

相互之间比较独立,便于控制细微地方的风险

缺点;

产品需要有共同点,且有范围控制,并且内部变化复杂,会有很多的建造类,就像是两个国家发生战争,和今天地球转不转没有什么特别的联系,这种就没办法使用建造者模式

实例

步骤一:创建一个表示食物包装的接口和一个打包方式的接口

//商品接口
public interface Item {
   public String name();
   public Packing packing();
   public float price();
}
//打包方式接口
public interface Packing {
   public String pack();
}

步骤二:创建实现Packing 接口的实体类

//创建包装实体类,并实现打包接口
public class Wrapper implements Packing {

   @Override
   public String pack() {
      return "Wrapper";
   }
}
//创建一个装入瓶子的类并实现打包接口
public class Bottle implements Packing {

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

步骤三:创建实现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();
}

步骤四:创建Burge(汉堡)和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";
   }
}

步骤5:创建一个Meal(一餐)类,带有上面定义的Item(商品)对象

//创建一餐饭的实体类,实体类内部有一个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;
   }
}

步骤七:BuiderPatternDemo使用MealBuilder来掩饰建造者模式

//该Demo 使用了一餐饭的构造器 
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());
   }
}

解释:

梳理调用流程-反向推理流程 BuilderPatternDemo,创建一个Mealbuilder建造起,准备了一餐蔬菜水果,也就是调用了MealBuiler的perpareBegMeal;perpareBegMeal方法 创建了一餐饭,并将蔬菜汉堡和可口可乐添加进入这一餐饭内部;
BuilderPatternDemo,接下来调用了showItems()方法,该方法是属于,一餐饭Meal内部的方法,可以展示你购买的细节,也就是Item类的实现类(汉堡和饮品)的字段 BuilderPatternDemo,接下来又调用了Meal方法的getCost方法,该方法计算了在准备套餐需要支付的价格也就是,在调用(perparBegMeal)方法时添加引入Item集合内部的商品的实现类的价格;

图解

从图解我们可以看出来整个,调用流程->
一餐的建造起,在建造一餐饭时,使用了Item(商品)的特性,而商品内部有汉堡,而汉堡和冷饮的抽象类实现了Item是一个商品,此时已经赋予他们是商品的特性,而汉堡和冷饮的具体实现类,又集成了汉堡和冷饮抽象类,有了他们俩的抽象方法,在此同时 汉堡和冷饮内部又分别又打包方式,也就是最开始的打包接口,和两个实现类。

此时一个商品内部该封装的元素都已经封装完毕:

一餐内部有Meal:ITEM集合 并提供金钱和细节的方法
商品接口Item: 内部有 名字 打包 价格 接口
打包接口Pack: 打包接口
商品的实现抽象了类: 汉堡抽象类 冷饮抽象类
打包接口实现类:汉堡打包 冷饮打包两个类
汉堡抽象类,和冷饮抽象类 的实现类:提供价钱 和名字方法
一餐的构造器:在准备一餐时,创建一餐的实例,调用add方法将Item商品的接口的抽象类的集成类汉堡和冷饮加入该一餐的对象里面;
此时意味着该一餐对象,也就是有了汉堡和冷饮的视频,而汉堡和冷饮的上级抽象类不同,但实现的接口Item相同都是属于商品,并且都有价格和商品名称的方法,所以可以在一餐里面查看 商品价格 和 一餐的详细设计 image.png