一句话定义:
将复杂对象的构建与表示分离,同样的构建过程可以创建不同的具体表示。
使用场景:
1. 相同的方法,不同的执行顺序,产生不同的结果;
2. 基本部件不发生改变,有很多默认参数,组合顺序常常发生改变;
3. 在创建时进行初始化配置,不提供set方法与构造方法,只能通过build方法创建。
实现要点:
1. 将变与不变分离;
2. 创建者:创建提供实例;
3. 管理者:管理创建出实例的依赖关系。
4. 相比工厂模式,更加关注装配的顺序细节。
情景假设:
模拟一份快餐(meal)的产出过程,包含一份菜(food),一份汤(soup)。
菜使用盘子(dish)装, 汤使用杯子(cup)装。
实现步骤:
1. 创建食品与包装接口
public interface Food {
String getName();
String getPackage();
}
public interface Package {
String pack();
}
2. 创建包装实体类
public class Cup implements Package {
@Override
public String pack() {
return "杯子";
}
}
public class Dish implements Package {
@Override
public String pack() {
return "盘子";
}
}
3. 根据默认的包装,创建食品抽象类
public abstract class EatFood implements Food {
/**
* 使用盘子盛装
* 组建盘子
*/
@Override
public String getPackage() {
return new Dish().pack();
}
}
public abstract class DrinkFood implements Food {
@Override
public String getPackage() {
return new Cup().pack();
}
}
4. 继承食品抽象类,实现具体种类,创建食品类
public class MealFood extends EatFood {
/**
* 组建食物
*/
@Override
public String getName() {
return "肉食";
}
}
public class VegetableFood extends EatFood{
@Override
public String getName() {
return "素食";
}
}
public class HotSoup extends DrinkFood {
@Override
public String getName() {
return "热饮";
}
}
public class ColdDrink extends DrinkFood {
@Override
public String getName() {
return "冷饮";
}
}
5. 创建套餐类(Meal),管理一份套餐
public class Meal {
private List<Food> aMeal = new ArrayList<>();
/**
* 加菜
*/
public void addFood(Food food){
aMeal.add(food);
}
/**
* 展示Meal
*/
public void showFoods(){
for (int i = 0; i < aMeal.size(); i++) {
System.out.print(aMeal.get(i).getName() + " 包装:" + aMeal.get(i).getPackage() + "\\n");
}
}
}
6. 创建套餐建造者Build类
public class MealBuild {
/**
* 创建套餐一
*/
public Meal BuildMealOne(){
Meal meal = new Meal();
meal.addFood(new MealFood());
meal.addFood(new VegetableFood());
meal.addFood(new HotSoup());
return meal;
}
/**
* 创建套餐二
*/
public Meal BuildMealTwo(){
Meal meal = new Meal();
meal.addFood(new MealFood());
meal.addFood(new MealFood());
meal.addFood(new ColdDrink());
return meal;
}
}
7. build初始化配置封装
这样使用户直接创建一份菜单,而不是一份一份去添加。
如果需要隐藏创建方式,且创建之后不能更改初始化设置。
最好是将Meal的构造方法、addFood等方法权限设置为私有,MealBuild 设置为内部类,MealBuild中的creat方法也设为私有。这样只有在初始化创建时能够进行配置,隐藏内部初始化细节,创建之后不能进行修改。代码如下:
public class Meal {
private List<Food> aMeal = new ArrayList<>();
/**
* 私有化构造方法,隐藏内部实现
*/
private Meal(){}
/**
* 隐藏配制方法
* 加菜
*/
private void addFood(Food food){
aMeal.add(food);
}
/**
* 展示Meal
*/
public void showFoods(){
for (int i = 0; i < aMeal.size(); i++) {
System.out.print(aMeal.get(i).getName() + " 包装:" + aMeal.get(i).getPackage() + "");
Log.i("info", "showFoods: ==++" + aMeal.get(i).getName() + " 包装:" + aMeal.get(i).getPackage() + "");
}
}
/**
* 内部类 进行创建 同时封装内部实现
*/
public static class MealBuild{
List<Food> aMeal = new ArrayList<>();
/**
* 暴露设置方法
*/
public MealBuild add(Food food){
aMeal.add(food);
return this;
}
/**
* 暴露方法进行创建
*/
public Meal creat(){
Meal meal = new Meal();
for (Food food :
aMeal) {
meal.addFood(food);
}
return meal;
}
}
}
使用方式如下:
Meal bigMeal = new Meal.MealBuild().add(new MealFood())
.add(new VegetableFood())
.add(new HotSoup())
.creat();
bigMeal.showFoods();