创建型模式之-建造者模式
简介
说到建造者模式,有些人可能比较陌生,那么StringBuilder.append().append()....=> StringBuilder
应该不陌生吧,其实在Spark中也用到了类似的设计模式,SparkSession.builder.conf().appName().....getOrCreate() => SparkSession
,类似于这样的模式,就是建造者模式
。
建造者模式
(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
NOTE: Java中,抽象类implement interface的时候,不需重写interface中的抽象方法,当然也可以重写
Bottle --打包的具体实现类
Buger --抽象类
Coca --具体实现类
ColdDrinking --抽象类,用来实现Item单品接口
Item --接口,代表一个单品
Meal --类,代表一个套餐,用来装载不同的Item
MealBuilder --建造者类,用来创建Meal套餐
NonVegBuger --素食汉堡,Buger的子类
Packing --打包方式接口
Pepsi --ColdDrink的具体实现类
TestCreatePatternDemo --程序入口
VegBuger --素食Buger,Buger的实现类
Wrapper --纸质的包装方式实现类
优点: 1、建造者独立,易扩展。 2、便于控制细节风险。
缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。
建造者模式将变与不变分离:
不变:创建者只能创建相应的对象
变:创建的对象的内部属性是复杂可变的
1 建造者模式图解
2 建造者模式的简单实现
2.1 目标对象的创建流程
//可以一次添加Item,不同的Item有不同的打包方式,不同的item有不同的价格,不同的item有不同的name
Meal meal = MealBuilder.build().addItem(new Item()).addItem(new Item)......
meal.getCost()
meal.showItems()
meal.addItem() => this
2.2 建造者模式的具体代码
TestCreatePatternDemo
package com.shufang.create_type.builder_pattern;
// 测试的程序入口
public class TestCreatePatternDemo {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealBuilder();
//创建一个素食汉堡+可口可乐套餐
Meal meal = mealBuilder.createVegMeal().addItem(new VegBuger()).addItem(new Coca());
//创建一个肉食汉堡+百事可乐套餐
Meal meal1 = mealBuilder.createNonVegMeal().addItem(new NonVegBuger()).addItem(new Pepsi());
/** 输出结果如下:
* 23.88
* 单品名称:素食汉堡,单品价格:18.88,单品打包方式:wrapper packing(用包装纸打包)
* 单品名称:可口可乐,单品价格:5.0,单品打包方式:bottle packing(用杯子打包)
* ----------------
* 25.8
* 单品名称:非素食汉堡,单品价格:20.68,单品打包方式:wrapper packing(用包装纸打包)
* 单品名称:百事可乐,单品价格:5.12,单品打包方式:bottle packing(用杯子打包)
*/
System.out.println(meal.getCost());
meal.getItemList();
System.out.println("----------------");
System.out.println(meal1.getCost());
meal1.getItemList();
}
}
MealBuilder
//建造者,用来创建简单的Meal对象
package com.shufang.create_type.builder_pattern;
/**
* 建造者模式很常见:
* Java中的StringBuilder.append.append.append => StringBuilder
* Spark中的SparkSession.builder().conf().conf()
* .....
* 这些都是建造者模式,在创建复杂对象的同时可以控制创建细节
*/
//用来创建不同的套餐组合
public class MealBuilder {
// 创建一个素食套餐
public Meal createVegMeal(){
Meal meal = new Meal();
return meal;
};
// 创建一个非素食套餐
public Meal createNonVegMeal(){
Meal meal = new Meal();
return meal;
};
}
Meal
//具体套餐类
package com.shufang.create_type.builder_pattern;
import java.util.ArrayList;
//这是一个事物套餐
public class Meal {
//用来存储不同的套餐组成成员如:汉堡、可乐
private ArrayList<Item> items = new ArrayList<Item>();
//添加单品到套餐
public Meal addItem(Item item) {
items.add(item);
System.out.println("item:" + item + " 添加成功");
return this; //添加单品后,返回当前对象
}
//获取当前套餐的总消费
public Double getCost() {
Double cost = 0D;
for (Item item : items) {
cost += item.price();
}
return cost;
}
//获取明细单品
public void getItemList(){
for (Item item : items) {
System.out.println("单品名称:"+item.name()+",单品价格:"+ item.price()+",单品打包方式:"+item.pack().pack());
}
}
}
Item
//单品的抽象接口
package com.shufang.create_type.builder_pattern;
//抽象单品,如Item「汉堡、打包方式、汉堡价格」
public interface Item {
String name();
Packing pack();
Double price();
}
Buger
//汉堡,Item单品的具体实现
package com.shufang.create_type.builder_pattern;
//单品的具体实现之一、汉堡,这是一个抽象类,已经继承了接口的抽象方法,不需要实现
public abstract class Buger implements Item{
//重写打包方法,只要是汉堡,都用包装纸打包,这是所有汉堡公共的,如果到子类实现的话,需要每个具体实例都要实现一遍该方法
@Override
public Packing pack() {
return new Wrapper();
}
}
ColdDrink
//冷饮,抽象类,具体实现自Item单品接口
package com.shufang.create_type.builder_pattern;
public abstract class ColdDrinking implements Item {
//是要是冷饮,都用杯子bottle来进行打包
@Override
public Packing pack() {
return new Bottle();
}
}
Packing
//打包方式的接口抽象
package com.shufang.create_type.builder_pattern;
/**
* 打包方式接口
*/
public interface Packing {
String pack();
}
VegBuger
//具体是Buger汉堡的实现类,价格18.68
package com.shufang.create_type.builder_pattern;
public class VegBuger extends Buger {
@Override
public String name() {
return "素食汉堡";
}
@Override
public Double price() {
return 18.88d;
}
}
NonVegBuger
package com.shufang.create_type.builder_pattern;
//具体是汉堡Buger的实体类,名字叫非素食汉堡,价格20.68
public class NonVegBuger extends Buger {
@Override
public String name() {
return "非素食汉堡";
}
@Override
public Double price() {
return 20.68d;
}
}
Coca
//冷饮的具体实现类,可口可乐,价格5元
package com.shufang.create_type.builder_pattern;
public class Coca extends ColdDrinking {
@Override
public String name() {
return "可口可乐";
}
@Override
public Double price() {
return 5.00d;
}
}
Pepsi
//冷饮的具体实现类,百事可乐,价格5.12
package com.shufang.create_type.builder_pattern;
public class Pepsi extends ColdDrinking {
@Override
public String name() {
return "百事可乐";
}
@Override
public Double price() {
return 5.12d;
}
}
Wrapper
//打包方式的具体实现类,用纸盒打包
package com.shufang.create_type.builder_pattern;
// 具体的打包方式
public class Wrapper implements Packing {
@Override
public String pack() {
return "wrapper packing(用包装纸打包)";
}
}
Bottle
// 打包方式的具体实现类,用杯子打包
package com.shufang.create_type.builder_pattern;
public class Bottle implements Packing {
@Override
public String pack() {
return "bottle packing(用杯子打包)";
}
}