建造者模式

本文介绍建造者模式的基本概念,包括其定义、使用场景及实现要点,并通过实例详细讲解如何运用建造者模式来创建不同类型的套餐。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一句话定义:

将复杂对象的构建与表示分离,同样的构建过程可以创建不同的具体表示。

使用场景:

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();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值