设计模式--创建型模式--建造者模式

建造者模式

什么是建造者模式?

文档资料中的解释

建造者模式:用多个简单的对象,一步一步构建成一个复杂的对象;构建的过程,由另一个更专业的Builder处理。

建造者模式的本质是什么?

将不变的基础组件 与 经常变化的组件组合 分离开,提高代码的可扩展性。
类似于:饭店里的各种各样的套餐,每一个套餐是不一样的,但里面的单品有可能是相同的。

实现案例代码

/**
 * 创建型模式:
 * 	建造者模式测试
 *
 * 	适用场景为:
 * 		基础部件不变,但部件之间的组合经常变化
 *
 * 	案例:
 * 		肯德基的套餐:
 * 			套餐1:汉堡+可乐
 * 			套餐2:汉堡+鸡腿
 * 			套餐3:汉堡+鸡米花
 * 			套餐4:汉堡+可乐+鸡腿
 * 		基础部件为:
 * 			汉堡、鸡腿、鸡米花、	可乐、牛奶
 */
public class BuilderTest {

	public static void main(String[] args) {
		// TODO
		MealBuilder mbl = new MealBuilder();
		mbl.taoCan1();
	}

}
















/* ===================== 接口 ========================== */

interface Food {
	/**
	 * 食物的名称
	 * @return
	 */
	String name();
	/**
	 * 食物的价格
	 * @return
	 */
	BigDecimal price();
}

/**
 * 主食
 */
interface ZhuShi extends Food {

}

/**
 * 冷饮
 */
interface Drink extends Food {

}


/**
 * 套餐
 */
class Meal {
	private List<Food> foods = new ArrayList<>(6);

	/**
	 * 套餐里面添加:食物
	 * @param food
	 */
	public void add(Food food) {
		this.foods.add(food);
	}

	/**
	 * 获取套餐的价格
	 * @return
	 */
	public BigDecimal getCost() {
		BigDecimal total = new BigDecimal("0.0");
		for(Food food : foods) {
			total = total.add(food.price());
		}
		return total;
	}

	/**
	 * 打印套餐的内容和总价格
	 */
	public void showTotalCost() {
		System.out.print("套餐内含有: ");
		for(int index=0; index<foods.size(); index++) {
			Food food = foods.get(index);
			System.out.print(food.name());
			if (index != foods.size()-1) {
				System.out.print(" ");
			}
		}
		System.out.print(", 总价格为: "+getCost()+"元");
		System.out.println("");
	}

	/**
	 * 打印每个食品的名称、价格
	 */
	public void showFoods() {
		for(Food food : foods) {
			System.out.println("\t食物: "+food.name()+", 价格: "+food.price());
		}
	}



}


class MealBuilder {
	/**
	 * 所有的套餐列表
	 */
	private List<Meal> meals = new ArrayList<>();

	/**
	 * 套餐一
	 * @return
	 */
	public List<Meal> taoCan1() {
		Meal meal = new Meal();
		meal.add(new Hanbao());
		meal.add(new JiMiHua());
		meal.add(new Milk());

		meal.showTotalCost();
		meal.showFoods();

		this.meals.add(meal);
		return this.meals;
	}

	/**
	 * 1~2个主食,1杯饮料
	 * @return
	 */
//	public List<Meal> generateMeals() {
//		for() {
//			Meal meal = randomMeal();
//			if (!this.meals.contains(meal)) {
//				this.meals.add(meal);
//			}
//		}
//	}

	private Meal randomMeal() {
		Meal meal = new Meal();
		final int zhuShiCount = 2;
		final int drinkCount = 1;

		for (int i=0; i<zhuShiCount; i++) {
			meal.add(randomZhuShi());
		}

		for (int i=0; i<drinkCount; i++) {
			meal.add(randomDrink());
		}
		
		return meal;
	}

	/**
	 * 随机饮料
	 * @return
	 */
	private Food randomDrink() {
		Class<Food>[] clazz = new Class[]{Milk.class, Coca.class};
		Random random = new Random(clazz.length);
		final int i = random.nextInt();
		final Class<Food> foodClass = clazz[i];
		try {
			return foodClass.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 随机主食
	 * @return
	 */
	private Food randomZhuShi() {
		Class<Food>[] clazz = new Class[]{Hanbao.class, JiTui.class, JiMiHua.class};
		Random random = new Random(clazz.length);
		final int i = random.nextInt();
		final Class<Food> foodClass = clazz[i];
		try {
			return foodClass.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return null;
	}

}







/* ===================== 实现类 ========================== */

/**
 * 汉堡-主食
 */
class Hanbao implements ZhuShi {

	@Override
	public String name() {
		return "汉堡";
	}

	@Override
	public BigDecimal price() {
		return new BigDecimal("12");
	}
}

/**
 * 鸡腿-主食
 */
class JiTui implements ZhuShi {

	@Override
	public String name() {
		return "鸡腿";
	}

	@Override
	public BigDecimal price() {
		return new BigDecimal("8.5");
	}
}

/**
 * 鸡米花-主食
 */
class JiMiHua implements ZhuShi {

	@Override
	public String name() {
		return "鸡米花";
	}

	@Override
	public BigDecimal price() {
		return new BigDecimal("8.0");
	}
}


/**
 * 牛奶-饮料
 */
class Milk implements Drink {

	@Override
	public String name() {
		return "牛奶";
	}

	@Override
	public BigDecimal price() {
		return new BigDecimal("4.0");
	}
}

/**
 * 可乐-饮料
 */
class Coca implements Drink {

	@Override
	public String name() {
		return "可乐";
	}

	@Override
	public BigDecimal price() {
		return new BigDecimal("3.0");
	}
}

稍微复杂点的场景

假设现在有在现有的菜式上,推出了新的套餐:套餐二、套餐三、套餐四,应该如何设计???

MealBuilder定义成一个接口,所有的套餐构建都实现这个接口 即可。代码如下:

package test2;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 创建型模式:
 * 	建造者模式测试
 *
 * 	适用场景为:
 * 		基础部件不变,但部件之间的组合经常变化
 *
 * 	案例:
 * 		肯德基的套餐:
 * 			套餐1:汉堡+可乐
 * 			套餐2:汉堡+鸡腿
 * 			套餐3:汉堡+鸡米花
 * 			套餐4:汉堡+可乐+鸡腿
 * 		基础部件为:
 * 			汉堡、鸡腿、鸡米花、	可乐、牛奶
 */
public class BuilderTest2 {

    public static void main(String[] args) {
        MealBuilder mbl = new TaoCan1MealBuilder();
        Meal meal = mbl.packMeal();
        meal.showTotalCost();
        meal.showFoods();

        System.out.println("================================================");

        MealBuilder mbl2 = new TaoCan2MealBuilder();
        Meal meal2 = mbl2.packMeal();
        meal2.showTotalCost();
        meal2.showFoods();

        System.out.println("================================================");

        MealBuilder mbl3 = new TaoCan3MealBuilder();
        Meal meal3 = mbl3.packMeal();
        meal3.showTotalCost();
        meal3.showFoods();
    }

}
















/* ===================== 接口 ========================== */

interface Food {
    /**
     * 食物的名称
     * @return
     */
    String name();
    /**
     * 食物的价格
     * @return
     */
    BigDecimal price();
}

/**
 * 主食
 */
interface ZhuShi extends Food {

}

/**
 * 冷饮
 */
interface Drink extends Food {

}


/**
 * 套餐
 */
class Meal {
    private List<Food> foods = new ArrayList<>(6);

    /**
     * 套餐里面添加:食物
     * @param food
     */
    public void add(Food food) {
        this.foods.add(food);
    }

    /**
     * 获取套餐的价格
     * @return
     */
    public BigDecimal getCost() {
        BigDecimal total = new BigDecimal("0.0");
        for(Food food : foods) {
            total = total.add(food.price());
        }
        return total;
    }

    /**
     * 打印套餐的内容和总价格
     */
    public void showTotalCost() {
        System.out.print("套餐内含有: ");
        for(int index=0; index<foods.size(); index++) {
            Food food = foods.get(index);
            System.out.print(food.name());
            if (index != foods.size()-1) {
                System.out.print(" ");
            }
        }
        System.out.print(", 总价格为: "+getCost()+"元");
        System.out.println("");
    }

    /**
     * 打印每个食品的名称、价格
     */
    public void showFoods() {
        for(Food food : foods) {
            System.out.println("\t食物: "+food.name()+", 价格: "+food.price());
        }
    }



}








/* ========================= 构建者 ========================== */


interface MealBuilder {
    Meal packMeal();
}


/**
 * 套餐一
 */
class TaoCan1MealBuilder implements MealBuilder {
    @Override
    public Meal packMeal() {
        Meal meal = new Meal();
        meal.add(new Hanbao());
        meal.add(new JiMiHua());
        meal.add(new Milk());
        return meal;
    }
}

class TaoCan2MealBuilder implements MealBuilder {
    @Override
    public Meal packMeal() {
        Meal meal = new Meal();
        meal.add(new Hanbao());
        meal.add(new JiTui());
        meal.add(new Milk());
        return meal;
    }
}

class TaoCan3MealBuilder implements MealBuilder {
    @Override
    public Meal packMeal() {
        Meal meal = new Meal();
        meal.add(new JiMiHua());
        meal.add(new JiTui());
        meal.add(new Coca());
        return meal;
    }
}


//class MealBuilder {
//    /**
//     * 所有的套餐列表
//     */
//    private List<Meal> meals = new ArrayList<>();
//
//    /**
//     * 套餐一
//     * @return
//     */
//    public List<Meal> taoCan1() {
//        Meal meal = new Meal();
//        meal.add(new Hanbao());
//        meal.add(new JiMiHua());
//        meal.add(new Milk());
//
//        meal.showTotalCost();
//        meal.showFoods();
//
//        this.meals.add(meal);
//        return this.meals;
//    }
//
//    /**
//     * 1~2个主食,1杯饮料
//     * @return
//     */
////	public List<Meal> generateMeals() {
////		for() {
////			Meal meal = randomMeal();
////			if (!this.meals.contains(meal)) {
////				this.meals.add(meal);
////			}
////		}
////	}
//
//    private Meal randomMeal() {
//        Meal meal = new Meal();
//        final int zhuShiCount = 2;
//        final int drinkCount = 1;
//
//        for (int i=0; i<zhuShiCount; i++) {
//            meal.add(randomZhuShi());
//        }
//
//        for (int i=0; i<drinkCount; i++) {
//            meal.add(randomDrink());
//        }
//
//        return meal;
//    }
//
//    /**
//     * 随机饮料
//     * @return
//     */
//    private Food randomDrink() {
//        Class<Food>[] clazz = new Class[]{Milk.class, Coca.class};
//        Random random = new Random(clazz.length);
//        final int i = random.nextInt();
//        final Class<Food> foodClass = clazz[i];
//        try {
//            return foodClass.newInstance();
//        } catch (InstantiationException e) {
//            e.printStackTrace();
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        }
//        return null;
//    }
//
//    /**
//     * 随机主食
//     * @return
//     */
//    private Food randomZhuShi() {
//        Class<Food>[] clazz = new Class[]{Hanbao.class, JiTui.class, JiMiHua.class};
//        Random random = new Random(clazz.length);
//        final int i = random.nextInt();
//        final Class<Food> foodClass = clazz[i];
//        try {
//            return foodClass.newInstance();
//        } catch (InstantiationException e) {
//            e.printStackTrace();
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        }
//        return null;
//    }
//
//}







/* ===================== 实现类 ========================== */

/**
 * 汉堡-主食
 */
class Hanbao implements ZhuShi {

    @Override
    public String name() {
        return "汉堡";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal("12");
    }
}

/**
 * 鸡腿-主食
 */
class JiTui implements ZhuShi {

    @Override
    public String name() {
        return "鸡腿";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal("8.5");
    }
}

/**
 * 鸡米花-主食
 */
class JiMiHua implements ZhuShi {

    @Override
    public String name() {
        return "鸡米花";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal("8.0");
    }
}


/**
 * 牛奶-饮料
 */
class Milk implements Drink {

    @Override
    public String name() {
        return "牛奶";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal("4.0");
    }
}

/**
 * 可乐-饮料
 */
class Coca implements Drink {

    @Override
    public String name() {
        return "可乐";
    }

    @Override
    public BigDecimal price() {
        return new BigDecimal("3.0");
    }
}

JDK、Spring中建造者的应用

JDK

String类的构建:StringBuilder

Spring

BeanDefinition的构建BeanDefinitionBuilder

posted @ 2021-11-10 16:26  小小落  阅读(65)  评论(0)    收藏  举报