2018.3.24 设计模式之建造者模式理解(一)
一、什么是建造者模式?
建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的Test结合起来得到的。
建造者模式通常包括下面几个角色:
1、Builder:给出一个抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。
2、ConcreteBuilder:实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建。 在建造过程完成后,提供产品的实例。
3、Director:调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。
4、Product:要创建的复杂对象。
我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸##盒中。冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。
我们将创建一个表示食物条目(比如汉堡和冷饮)的 Item 接口和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing 接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中。
然后我们创建一个 Meal 类,带有 Item 的 ArrayList 和一个通过结合 Item 来创建不同类型的 Meal 对象的 MealBuilder。BuilderPatternDemo,我们的演示类使用 MealBuilder 来创建一个 Meal。
//Burger
package com.glut.demo7;
/**
* 创建实现 Item 接口的抽象类,该类提供了默认的功能。
*
* @author qichunlin
*
*/
public abstract class Burger implements Item{
@Override
public Packing packing() {
return new Wrapper();
}
@Override
public abstract float price();
}
//Bottle
package com.glut.demo7;
public class Bottle implements Packing{
@Override
public String pack() {
return "Bottle";
}
}
//ChickenBurger
package com.glut.demo7;
/**
* 继承的话如果父类中的方法是抽象的而子类不是抽象类择要全部重写父类中的方法
* @author qichunlin
*
*/
public class ChickenBurger extends Burger{
@Override
public String name() {
return "Chicken Burger";
}
@Override
public float price() {
return 50.5f;
}
}
//Coke
package com.glut.demo7;
/**
* 继承的父类中如果是抽象的方法就要全部继承哦
* @author qichunlin
*
*/
public class Coke extends ColdDrink{
@Override
public String name() {
// TODO Auto-generated method stub
return "Coke";
}
@Override
public float price() {
// TODO Auto-generated method stub
return 30.0f;
}
}
//ColdDrink
package com.glut.demo7;
/**
* 实现
* @author qichunlin
*
*/
public abstract class ColdDrink implements Item{
@Override
public Packing packing() {
return new Bottle();
}
@Override
public abstract float price();
}
//interface Item
package com.glut.demo7;
/**
* 创建表示食物条目和食物包装的接口
*
* @author qichunlin
*
*/
public interface Item {
public String name();//名字
public Packing packing();//包装
public float price();//价格
}
//Meal
package com.glut.demo7;
import java.util.ArrayList;
import java.util.List;
/**
* 创建一个 Meal 类,带有上面定义的 Item 对象。
* @author qichunlin
*
*/
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 showItmes() {
for(Item item :items) {
System.out.print("Item:"+item.name());
System.out.print(",Packing:"+item.packing().pack());
System.out.print(",Price:"+item.price());
}
}
}
//MealBuilder
package com.glut.demo7;
/**
* 创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象。
* @author qichunlin
*
*/
public class MealBuilder {
public Meal prepareVegMeal() {
Meal meal = new Meal();
meal.addItem(new VegBurrer());
meal.addItem(new Coke());
return meal;
}
public Meal prepareNonMeal() {
Meal meal = new Meal();
meal.addItem(new ChickenBurger());
meal.addItem(new Pepsi());
return meal;
}
}
//Wrapper
package com.glut.demo7;
/**
* 包装纸;
* @author qichunlin
*
*/
public class Wrapper implements Packing{
@Override
public String pack() {
return "Wrapper";
}
}
//Packing
package com.glut.demo7;
/**
* 创建食品包装的接口
*
* @author qichunlin
*
*/
public interface Packing {
public String pack();
}
//Pepsi
package com.glut.demo7;
public class Pepsi extends ColdDrink{
@Override
public String name() {
// TODO Auto-generated method stub
return "Pepsi";
}
@Override
public float price() {
// TODO Auto-generated method stub
return 35.0f;
}
}
//Test
package com.glut.demo7;
public class Test {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealBuilder();
Meal vegMeal = mealBuilder.prepareVegMeal();
System.out.println("Veg Meal");
vegMeal.showItmes();
System.out.println("Total Cost:"+vegMeal.getCost());
Meal nonVegMeal = mealBuilder.prepareNonMeal();
System.out.println("\n\nNon-Veg Meal");
nonVegMeal.showItmes();
System.out.println("Total Cost:"+nonVegMeal.getCost());
}
}
//VegBurrer
package com.glut.demo7;
/**
* 出现extends关键字如果是abstract 类 里面的方法必须全部实现
*
* @author qichunlin
*
*/
public class VegBurrer extends Burger{
@Override
public String name() {
return "Veg Burger";
}
@Override
public float price() {
return 25.0f;
}
}
使用场景:
1、需要生成的对象具有复杂的内部结构。
2、需要生成的对象内部属性本身相互依赖。
与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。