当前位置: 首页 > article >正文

设计模式讲解01-建造者模式(Builder)

1. 概述

建造者模式也称为:生成器模式

定义:建造者模式是一种创建型设计模式,它允许你将创建复杂对象的步骤与表示方式相分离。

解释:建造者模式就是将复杂对象的创建过程拆分成多个简单对象的创建过程,并将这些简单对象组合成复杂对象!

2. 优缺点

优点

缺点

  1. 灵活:可以分步骤地构建复杂对象,使得构建过程更加灵活。
  1. 增加工作量:需要额外的代码来创建和管理具体建造者类,增加工作量。
  1. 解耦:可以隔离复杂对象的创建和使用,客户端不必关心对象的创建细节。
  1. 效率低:相比于其他创建型模式,在运行时效率较低,特别是对象过于复杂时。
  1. 易扩展:增加新的具体建造者很方便,可以扩展构建器功能,符合开闭原则。

3. 结构

建造者模式包含以下几个主要角色:

  • 产品(Product)要构建的复杂对象;产品类通常包含多个部分或者属性,并由具体的建造者逐步构建而成。
  • 抽象建造者(Builder)定义了构建产品的抽象接口,包括构建产品的各个部分的方法;通常包括多个构建方法和一个返回产品的方法。
  • 具体建造者(Concrete Builder)实现了抽象建造者接口,具体确定如何构建产品的各个部分,并负责返回最终构建的产品。
  • 指导者(Director)负责调用建造者的方法来构建产品;指导者并不了解具体的构建过程,只关心产品的构建顺序和方式。

4. 代码实现

4.1. 需求介绍

我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒中。冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。

我们将创建一个表示食物条目(比如汉堡和冷饮)的 Item 接口和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing 接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中。

然后我们创建一个 Meal 类,带有 ItemArrayList 和一个通过结合 Item 来创建不同类型的 Meal 对象的 MealBuilderBuilderPatternDemo 类使用 MealBuilder 来创建一个 Meal

4.2. 代码演示

  1. 创建一个代表食物条目和食物包装的接口。
/**
 * @Description 食品条目接口
 * @Author gongming.Zhang
 * @Date 2024/11/1 15:54
 * @Version 1.0
 */
public interface Item {
    // 商品名称
    String name();
    // 包装类型 (纸盒、瓶子)
    Packing packing();
    // 价格
    float price();
}
package top.zhang.builderdesignpatterns.entity.packing;

/**
 * @Description 食物包装条目接口
 * @Author gongming.Zhang
 * @Date 2024/11/1 15:56
 * @Version 1.0
 */
public interface Packing {
    // 包装类型(纸盒、瓶子)
    String pack();
}

  1. 创建并实现 Packing 接口的实体类。
/**
 * @Description 纸盒实现类
 * @Author gongming.Zhang
 * @Date 2024/11/1 15:57
 * @Version 1.0
 */
public class Wrapper implements Packing {
    @Override
    public String pack() {
        return "Wrapper";
    }
}
/**
 * @Description 瓶子实现类
 * @Author gongming.Zhang
 * @Date 2024/11/1 15:58
 * @Version 1.0
 */
public class Bottle implements Packing {
    @Override
    public String pack() {
        return "Bottle";
    }
}

  1. 创建并实现 Item接口的抽象类,该类提供默认的功能。
/**
 * @Description 汉堡抽象类
 * @Author gongming.Zhang
 * @Date 2024/11/1 16:00
 * @Version 1.0
 */
public abstract class Burger implements Item {

    @Override
    public Packing packing() {
        return new Wrapper();
    }

    @Override
    public abstract float price();
}
/**
 * @Description 冷饮抽象类
 * @Author gongming.Zhang
 * @Date 2024/11/1 16:24
 * @Version 1.0
 */
public abstract class ColdDrink implements Item {
    @Override
    public Packing packing() {
        return new Bottle();
    }

    @Override
    public abstract float price();
}

  1. 创建并继承 BurgerColdDrink
/**
 * @Description 鸡肉汉堡实体类
 * @Author gongming.Zhang
 * @Date 2024/11/1 16:28
 * @Version 1.0
 */
public class ChickenBurger extends Burger {
    @Override
    public String name() {
        return "Chicken Burger";
    }

    @Override
    public float price() {
        return 50.5f;
    }
}
/**
 * @Description 素食汉堡实体类
 * @Author gongming.Zhang
 * @Date 2024/11/1 16:26
 * @Version 1.0
 */
public class VegBurger extends Burger {
    @Override
    public String name() {
        return "Veg Burger";
    }

    @Override
    public float price() {
        return 25.0f;
    }
}
/**
 * @Description 可口可乐实体类
 * @Author gongming.Zhang
 * @Date 2024/11/1 16:28
 * @Version 1.0
 */
public class Coke extends ColdDrink {
    @Override
    public String name() {
        return "Coke";
    }

    @Override
    public float price() {
        return 30.0f;
    }
}
/**
 * @Description 百事可乐实体类
 * @Author gongming.Zhang
 * @Date 2024/11/1 16:30
 * @Version 1.0
 */
public class Pepsi extends ColdDrink {
    @Override
    public String name() {
        return "Pepsi";
    }

    @Override
    public float price() {
        return 35.0f;
    }
}

  1. 创建一个 Meal 类,表示菜品实体。(产品)
package top.zhang.builderdesignpatterns.entity;

import top.zhang.builderdesignpatterns.entity.food.Item;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description 菜品实体类  ——  产品
 * @Author gongming.Zhang
 * @Date 2024/11/1 16:31
 * @Version 1.0
 */
public class Meal {
    private List<Item> items = new ArrayList<Item>();

    public void addItem(Item item) {
        items.add(item);
    }

    /**
     * 获取购买的商品总价
     *
     * @return 商品总价格
     */
    public float getCost() {
        float cost = 0.0f;
        for (Item item : items) {
            cost += item.price();
        }
        return cost;
    }

    /**
     * 展示购买的商品信息
     *
     */
    public void showItems() {
        for (Item item : items) {
            System.out.print("Item : "+item.name());
            System.out.print(", Packing : "+item.packing().pack());
            System.out.println(", Price : "+item.price());
        }
    }
}

  1. 创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象。(具体建造者)
package top.zhang.builderdesignpatterns.entity;

import top.zhang.builderdesignpatterns.entity.food.entity.ChickenBurger;
import top.zhang.builderdesignpatterns.entity.food.entity.Coke;
import top.zhang.builderdesignpatterns.entity.food.entity.Pepsi;
import top.zhang.builderdesignpatterns.entity.food.entity.VegBurger;

/**
 * @Description 负责构建 Meal 对象  ——  具体建造者
 * @Author gongming.Zhang
 * @Date 2024/11/1 16:34
 * @Version 1.0
 */
public class MealBuilder {

    /**
     * 构建蔬菜餐数据
     *
     * @return 菜品实体类
     */
    public Meal prepareVegMeal() {
        Meal meal = new Meal();
        meal.addItem(new VegBurger());
        meal.addItem(new Coke());
        return meal;
    }

    /**
     * 构建非蔬菜餐数据
     *
     * @return 菜品实体类
     */
    public Meal prepareNonVegMeal() {
        Meal meal = new Meal();
        meal.addItem(new ChickenBurger());
        meal.addItem(new Pepsi());
        return meal;
    }
}

  1. 测试建造者模式
@SpringBootTest
@RunWith(SpringRunner.class)
class BuilderDesignPatternsApplicationTests {

    @Test
    public void BuilderPatternDemo() {
        MealBuilder mealBuilder = new MealBuilder();

        Meal vegMeal = mealBuilder.prepareVegMeal();
        System.out.println("Veg Meal");
        vegMeal.showItems();
        System.out.println("total Cost: " + vegMeal.getCost());

        System.out.println("\n\n");

        Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
        System.out.println("Non-Veg Meal");
        nonVegMeal.showItems();
        System.out.println("Total Cost: " +nonVegMeal.getCost());
    }
}

5. 总结

使用场景

  • 当需要创建一些特定的对象,但是它们拥有共同的组成部分时,比如:一个房子可以由个个部件:框架、墙、窗户等,这些部件可以组合起来构造完整的房子。
  • 当对象的构建过程比较复杂且需要多个步骤时,例如,创建一份电子商务订单需要多个步骤,如选择商品、填写地址和支付等,这些步骤可以被分别封装成为订单构建器中的不同方法。
  • 当需要创建一些特定类型的对象,例如复杂的数据结构或配置对象时,这在编写配置文件解析器以及通用数据结构如二叉树等时很有用。
  • 建造者模式也可以被用于通过更高级的方式来构建复杂对象,例如:序列化和反序列化。

与抽象工厂模式的区别

抽象工厂模式强调的是产品族的创建,即相关的产品一起被创建出来,而建造者模式强调的是一个复杂对象的创建,即它的各个部分逐步被创建出来。


http://www.kler.cn/a/378670.html

相关文章:

  • 已解决,部署GPTSoVITS报错‘AsyncRequest‘ object has no attribute ‘_json_response_data‘
  • Chrome 130 版本开发者工具(DevTools)更新内容
  • 【AI】【提高认知】深度学习与反向传播:理解AI的基础
  • Centos7.6离线安装软件
  • 校招回顾 | “青春不散场,梦想正起航”,极限科技(INFINI Labs)亮相湖北工业大学 2025 秋季校园招聘会
  • git入门教程6:git基本版本控制
  • ZDS 数字股票 布局全球视野,开启智能金融新篇章
  • 秒杀优化(异步秒杀,基于redis-stream实现消息队列)
  • node.js rc4加密/解密 不好用怎么办?
  • 中文分词模拟器
  • 双十一晚会停办,一个消费时代结束了
  • 鸿蒙网络编程系列43-仓颉版HttpRequest下载文件示例
  • 第02章 MySQL环境搭建
  • 无人机反步滑膜控制算法!
  • 谷歌浏览器报“喔唷,崩溃啦!”怎么办?
  • 五层塔灯——智能仓储的守护者
  • 数组相关操作的java实现
  • TH-OCR 文字识别:开启高效数字化时代
  • 【JavaEE】【网络原理】初识网络
  • 理解SQL中通配符的使用
  • WPF+MVVM案例实战(十三)- 封装一个自定义消息弹窗控件(上)
  • leetcode 3259.超级饮料的最大强化能量
  • Spark学习
  • centos 选什么Distribution?flash安装
  • 机器学习初学者指南:Scikit-Learn基础到实战
  • python的安装环境Miniconda(Conda 命令管理依赖配置)