建造者模式
发布日期:2021-05-20 00:21:59 浏览次数:17 分类:精选文章

本文共 2943 字,大约阅读时间需要 9 分钟。

建造者模式(Builder Pattern)是一种软件设计模式,旨在将一个对象的构建与其表示分离开来,使得构建过程能够创建不同的表示。这种模式在软件开发中尤其适用于处理复杂对象的构建问题。

建造者模式的概念

建造者模式通过将构建过程与表示过程分离,允许用户在指定对象类型时获得相应的表示。这意味着用户只需要确定要创建的产品类型,而具体的构建细节则由建造者类处理。

建造者模式的成员

建造者模式通常包括以下成员:

  • 抽象建造者(Abstract Builder):定义构建步骤的抽象接口,确保每个构建步骤可用不同方式实现。

  • 具体建造者(Concrete Builder):实现抽象建造者的接口,明确产品的具体表示。例如,在炒酸奶的例子中,AppleFriedYogurtBananaFriedYogurt是两个具体建造者,每个都实现了不同的配料添加方式。

  • 构造器(Director):指挥者类,负责根据用户需求调用适当的建造者进行构造。比如,在炒酸奶例子中,Director类决定了构造流程:调用BuildpartABuildpartBBuildpartC

  • 产品(Product):定义对象的组成部分和装配接口,代表最终要构建的复杂对象。在炒酸奶例子中,FriedYogurt是产品类,内部包含所有配料,通过Add方法添加配料,并通过Show方法展示结果。

  • 实际构造一个炒酸奶的建造者模式

    以炒酸奶为例,定义不同的口味:苹果炒酸奶和香蕉炒酸奶。每种口味的配料不同:

    • 苹果炒酸奶:苹果丁、伊利酸奶、红豆。
    • 香蕉炒酸奶:香蕉丁、蒙牛酸奶、芝麻。

    构造一个类图如下:

    • 抽象建造者(FriedYogurtBuilder):提供三个步骤接口:BuildpartA()BuildpartB()BuildpartC(),以及递归方法GetFriedYogurt()

    • 具体建造者(AppleFriedYogurt和BananaFriedYogurt):分别实现抽象建造者的接口,添加不同配料到FriedYogurt对象中。

    • 构造器(Director):调用具体建造者的方法按照顺序构造炒酸奶。

    • 产品(FriedYogurt):维护配料列表,提供展示方法。

    代码示例

    // 抽象建造者类
    abstract class FriedYogurtBuilder {
    public abstract void buildPartA();
    public abstract void buildPartB();
    public abstract void buildPartC();
    public abstract FriedYogurt getFriedYogurt();
    }
    // 具体建造者类(苹果炒酸奶)
    class AppleFriedYogurt extends FriedYogurtBuilder {
    private FriedYogurt yogurt = new FriedYogurt();
    @Override
    public void buildPartA() {
    yogurt.add("苹果丁");
    }
    @Override
    public void buildPartB() {
    yogurt.add("伊利酸奶");
    }
    @Override
    public void buildPartC() {
    yogurt.add("红豆");
    }
    @Override
    public FriedYogurt getFriedYogurt() {
    return yogurt;
    }
    }
    // 具体建造者类(香蕉炒酸奶)
    class BananaFriedYogurt extends FriedYogurtBuilder {
    private FriedYogurt yogurt = new FriedYogurt();
    @Override
    public void buildPartA() {
    yogurt.add("香蕉丁");
    }
    @Override
    public void buildPartB() {
    yogurt.add("蒙牛酸奶");
    }
    @Override
    public void buildPartC() {
    yogurt.add("芝麻豆");
    }
    @Override
    public FriedYogurt getFriedYogurt() {
    return yogurt;
    }
    }
    // 构造器类
    class Director {
    public void construct(FriedYogurtBuilder builder) {
    builder.buildPartA();
    builder.buildPartB();
    builder.buildPartC();
    }
    }
    // 产品类
    class FriedYogurt {
    private List
    parts = new ArrayList<>();
    public void add(String part) {
    parts.add(part);
    }
    public void show() {
    System.out.println("炒酸奶的配料正在准备");
    for (String part : parts) {
    System.out.println("配料" + part + "已经添加好");
    }
    System.out.println("炒酸奶做好了");
    }
    }
    // 客户端使用代码
    Director director = new Director();
    FriedYogurtBuilder bananaBuilder = new BananaFriedYogurt();
    director.construct(bananaBuilder);
    FriedYogurt friedYogurt = bananaBuilder.getFriedYogurt();
    friedYogurt.show();

    建造者模式的优缺点

    优点

    • 可扩展性:新类型的产品只需新增具体建造者,无需修改现有代码。
    • 控制风险:通过抽象接口,细节由具体建造者处理,降低了构建过程中的风险。

    缺点

    • 局限性:如果产品类型过多,需针对每个类型创建建造者,增加维护复杂度。
    • 复杂性:内部变化复杂时,可能需要大量的建造者类,增加开发难度。
    上一篇:原型模式
    下一篇:单例模式

    发表评论

    最新留言

    留言是一种美德,欢迎回访!
    [***.207.175.100]2025年04月29日 15时13分16秒

    关于作者

        喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
    -- 愿君每日到此一游!

    推荐文章

    Nmap渗透测试指南之探索网络 2023-01-23
    Nmap渗透测试指南之防火墙/IDS逃逸、信息搜集 2023-01-23
    Nmap端口服务 之 CentOS7 关于启动Apache(httpd)服务、telnet服务、smtp服务、ftp服务、sftp服务、snmp服务 2023-01-23
    PHP系列:PHP 基础编程 2(时间函数、数组---实现登录&注册&修改) 2023-01-23
    PHP系列:使用PHP实现登录注册功能的完整指南 2023-01-23
    Python&aconda系列:cmd/powershell/anaconda prompt提示“系统找不到指定的路径”(亲测有效) 2023-01-23
    Python&aconda系列:conda踩坑记录2.UnsatisfiableError: The following specifications were found to be incompa 2023-01-23
    Python&aconda系列:Jupyter Notebook快速上手、深度学习库PyTorch安装 2023-01-23
    Python&aconda系列:(W&L)Conda使用faiss-gpu报错及解决办法、安装numpy的坑、cmd执行Python脚本找不到第三方库、安装tensorflow-gpu时遇到的from 2023-01-23
    python&anconda 系列:Pycharm在debug问题的N种解决方案(一般程序、web方向、人工智能方向) 2023-01-23
    python&anconda系列(亲测有效):tensorflow AttributeError: ‘str’ object has no attribute ‘decode’ 2023-01-23
    python&anconda系列:tf.keras.backend.get_session()和keras.backend.get_会话()返回不同的会话对象(待解答) 2023-01-23
    "WARNING: Increasing RAM size to 1GB" and "Cannot set up guest memory 'xxx.ram': Invalid argument". 2023-01-23
    #if 0 #elif 1 #else #endif 用法 2023-01-23
    #include <gdiplus.h>出错 2023-01-23
    $ajax({}).done 和 $ajax({}) success 区别 2023-01-23
    'ascii' codec can't encode characters in position 0-4: ordinal not in range(128) 2023-01-23
    (反射+内省机制的运用)处理jdbc的结果集 2023-01-23
    (反射+内省机制的运用)简单模拟spring IoC容器的操作 2023-01-23
    #C8# UVM中的factory机制 #S8.2.3# 重载 component 哪些情形 2023-01-23