设计模式(五):建造者模式
1. 建造者模式的介绍
建造者模式(Builder Pattern)属于创建型模式,使用多个简单的对象一步一步构建成一个复杂的对象。
优点:
- 分离构建过程和表示,使得构建过程更加灵活,可以构建不同的表示。
- 可以更好地控制构建过程,隐藏具体构建细节。
- 代码复用性高,可以在不同的构建过程中重复使用相同的建造者。
缺点:
- 如果产品的属性较少,建造者模式可能会导致代码冗余。
- 建造者模式增加了系统的类和对象数量。
2. 建造者模式的类图
一个中式快餐店,推出两种早餐套餐:
- 套餐一:一次性碗装甜豆浆 + 热干面
- 套餐二:一次性碗装咸豆浆 + 炸酱面
针对上述场景,将创建一个食物的接口Food
和实现Food
接口的具体食物类,以及食物包装接口Pack
和实现Pack
接口的具体包装类。然后创建Meal
套餐类,包含一个装Food
的List
,最后创建一个 MealBuilder
类,用来生成不同的Meal
套餐。
3. 建造者模式的实现
3.1 创建食物接口
package blog;
/**
* 食物
*/
public interface Food {
String getName();
String getDescription();
String getPrice();
Pack getPack();
}
package blog;
/**
* 豆浆
*/
public abstract class Soymilk implements Food {
@Override
public Pack getPack() {
return new DisposablePack();
}
abstract String getTaste();
}
package blog;
/**
* 面条
*/
public abstract class Noodles implements Food {
abstract String getType();
@Override
public Pack getPack() {
return new NormalPack();
}
}
3.2 创建包装接口
package blog;
/**
* 包装
*/
public interface Pack {
String getName();
String getType();
}
3.3 创建具体包装
package blog;
/**
* 一次性包装
*/
public class DisposablePack implements Pack{
@Override
public String getName() {
return "一次性包装";
}
@Override
public String getType() {
return "一次性";
}
}
package blog;
/**
* 普通包装
*/
public class NormalPack implements Pack{
@Override
public String getName() {
return "普通包装";
}
@Override
public String getType() {
return "普通";
}
}
3.4 创建具体食物
package blog;
/**
* 甜豆浆
*/
public class SweetSoymilk extends Soymilk {
@Override
public String getName() {
return "甜豆浆";
}
@Override
public String getDescription() {
return "甜味的豆浆";
}
@Override
public String getPrice() {
return "2元";
}
@Override
public String getTaste() {
return "甜";
}
}
package blog;
/**
* 咸豆浆
*/
public class SalineSoymilk extends Soymilk {
@Override
public String getName() {
return "咸豆浆";
}
@Override
public String getDescription() {
return "咸味的豆浆";
}
@Override
public String getPrice() {
return "1.5元";
}
@Override
public String getTaste() {
return "咸";
}
}
package blog;
/**
* 热干面
*/
public class HotDryNoodles extends Noodles {
@Override
public String getName() {
return "武汉热干面";
}
@Override
public String getDescription() {
return "武汉的热干面";
}
@Override
public String getPrice() {
return "5元";
}
@Override
public String getType() {
return "武汉版";
}
}
package blog;
/**
* 炸酱面
*/
public class SauceNoodles extends Noodles {
@Override
public String getName() {
return "炸酱面";
}
@Override
public String getDescription() {
return "北京炸酱面";
}
@Override
public String getPrice() {
return "10元";
}
@Override
public String getType() {
return "北京版";
}
}
3.5 创建Meal类
package blog;
import java.util.ArrayList;
import java.util.List;
/**
* 套餐
*/
public class Meal {
private List<Food> meal = new ArrayList<>();
public void addFood(Food food) {
meal.add(food);
}
public void showMeal() {
meal.forEach(food -> {
System.out.print(food.getPack().getName() + food.getName() + food.getPrice() + " ");
});
System.out.println();
}
}
3.6 创建MealBuilder类
package blog;
/**
* 构建套餐
*/
public class MealBuilder {
public Meal buildMeal1() {
Meal meal = new Meal();
meal.addFood(new SweetSoymilk());
meal.addFood(new HotDryNoodles());
return meal;
}
public Meal buildMeal2() {
Meal meal = new Meal();
meal.addFood(new SalineSoymilk());
meal.addFood(new SauceNoodles());
return meal;
}
}
3.7 演示建造者模式
package blog;
public class BuilderDemo {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealBuilder();
Meal meal1 = mealBuilder.buildMeal1();
meal1.showMeal();
Meal meal2 = mealBuilder.buildMeal2();
meal2.showMeal();
}
}