构建器模式与配置对象

2023-12-23

构建器模式在创建不可变对象时很流行,但创建构建器会产生一些编程开销。所以我想知道为什么不简单地使用配置对象。

构建器的用法如下所示:

Product p = Product.Builder.name("Vodka").alcohol(0.38).size(0.7).price(17.99).build();

显然,这是非常可读且简洁的,但是您必须实现构建器:

public class Product {

    public final String name;
    public final float alcohol;
    public final float size;
    public final float price;

    private Product(Builder builder) {
        this.name = builder.name;
        this.alcohol = builder.alcohol;
        this.size = builder.size;
        this.price = builder.price;
    }

    public static class Builder {

        private String name;
        private float alcohol;
        private float size;
        private float price;

        // mandatory
        public static Builder name(String name) {
            Builder b = new Builder();
            b.name = name;
            return b;
        }

        public Builder alcohol(float alcohol) {
            this.alcohol = alcohol;
            return.this;
        }

        public Builder size(float size) {
            this.size = size;
            return.this;
        }

        public Builder price(float price) {
            this.price = price;
            return.this;
        }

        public Product build() {
            return new Product(this);
        }

    }

}

我的想法是,通过使用像这样的简单配置对象来减少代码:

class ProductConfig {

        public String name;
        public float alcohol;
        public float size;
        public float price;

        // name is still mandatory
        public ProductConfig(String name) {
            this.name = name;
        }

}

public class Product {

    public final String name;
    public final float alcohol;
    public final float size;
    public final float price;

    public Product(ProductConfig config) {
        this.name = config.name;
        this.alcohol = config.alcohol;
        this.size = config.size;
        this.price = config.price;
    }

}

Usage:

ProductConfig config = new ProductConfig("Vodka");
config.alcohol = 0.38;
config.size = 0.7;
config.price = 17.99;
Product p = new Product(config);

这种用法需要多几行,但也非常可读,但实现要简单得多,对于不熟悉构建器模式的人来说可能更容易理解。顺便问一下:这个模式有名字吗?

我忽略了配置方法中的缺点吗?


构建器模式改进了解耦 - 您的产品可以是一个接口,唯一了解实现(或在某些情况下实现)的类是构建器。如果构建器还实现了一个接口,那么您可以将其注入到您的代码中以进一步增强解耦。

这种解耦意味着您的代码更易于维护且更易于测试。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

构建器模式与配置对象 的相关文章

随机推荐

  • OSError:无法识别图像文件

    我正在尝试在 pytorch 中执行 impelement 代码 但出现以下错误 我的python版本是3 6 我的操作系统是linux ubuntu 16 04 lts 我在 mac os 旁边安装了 linux 我们将使用 torchv
  • 如何使用 React-Query 处理多个查询

    我已经开始使用 React Query 如果我只需要从数据库中的单个集合中获取数据 它会非常有效 但是 我正在努力寻找一种查询多个集合以在单个组件中使用的好方法 一个查询 没问题 const isLoading isError data e
  • CakePHP Twitter 克隆:无法让关注系统工作

    抱歉 标题不具有描述性 但我不知道如何表达它 目前 我正在尝试使用 cakePHP 开发 Twitter 克隆 因为我是网络编程新手 我带了3张桌子 用户 ID 姓名 id是自动生成的id 用户名 推文 id 内容 user id id是自
  • 在终端上显示输出并将最后 10 行添加到日志文件中

    我需要运行一个脚本并将完整内容输出到终端 然后我想从终端输出中获取最后 10 行并将它们放入日志文件中 我尝试过使用 script sh 2 gt 1 tail 10 gt log log但这会停止向终端的输出 利用流程替代bash wit
  • 按列分组的查询结果的行号

    我有一个包含以下列的表 编号 fk id 接收日期 可能有多个记录具有共同的fk id 它代表相关表中的外键id 我需要创建一个查询 为每条记录分配行号 按 fk id 分组 按 rcv date 排序 我最初从以下查询开始 它对于排序和分
  • json_decode() 无法正常工作

    这里我使用简单的html jquery ajax文件 ajax代码在这里 var email email protected cdn cgi l email protection var username ankur 07 var pass
  • Celery Beat:如何定义定义为类的周期性任务(基于类的任务)

    到目前为止 我只处理过定义为函数的 Celery 任务 我曾经定义它们的周期性CELERYBEAT SCHEDULE范围 像这样 from datetime import timedelta CELERYBEAT SCHEDULE add
  • 在 Swift 中实现协议的 NSManagedObject 的 EXC_BAD_ACCESS 错误

    我有以下两种方法 func isAuthenticated gt Bool var currentUser CurrentUser self getCurrentUser if currentUser nil return false se
  • 为什么serverstatus对mongodb写操作有不好的影响?

    我有 1 个 mongos 3 个 mongod 和 3 个配置服务器 当我写一些文档时 有时其中一个 mongods 的插入速度很慢 并且 mongod 日志文件中出现 serverstatus was very Slow 为什么 版本是
  • 如何使用 sqlite3.exe 从导出的 .sql 脚本创建数据库

    尝试将 SqlCe 数据库转换为 SQLite 我将其导出到 sql文件 现在我将如何使用sqlite exe以此创建数据库 sql file 放在哪里sql3 exe file 在 cmd 提示符或在sqlite exe shell 使用
  • Java 数组具有多种数据类型

    我可以使用什么来存储多种不同类型的数据 Int String 等 我有 PHP 背景 我可以将不同类型的数据存储到数组中 但我不知道如何在 Java 中做到这一点 举个例子 array array val1 gt 1 val2 gt cat
  • 是否可以从 PHP 检查 PHP 文件语法?

    我使用自动加载功能动态加载 PHP 类文件 这些文件可能由于某种原因丢失或损坏 自动加载将成功报告丢失的文件 以便应用程序逻辑可以处理该问题 但是 如果这些文件损坏 则整个处理会停止 用户会看到空白屏幕 并且错误日志中会显示 PHP 解析错
  • 尝试获取进程启动时间时“访问被拒绝”

    现在我正在尝试获取计算机上运行的所有进程的启动时间 到目前为止我的代码是这样的 foreach Process item in Process GetProcesses txtActivity AppendText item StartTi
  • 两个自动机之间的等价

    确定两个自动机之间的等价性的最佳或最简单的方法是什么 即 如果给定两个有限自动机 A 和 B 我如何确定两者是否识别相同的语言 它们都是确定性的或都是非确定性的 一种不同的 更简单的方法是对自动机进行补充和交叉 自动机A相当于B iff L
  • 允许同一 COM 库的多个版本

    我编写了一个 C 程序和库 允许用户更轻松地使用特定专有模拟器的 COM 接口 目前 我必须为我希望支持的每个版本的模拟器构建和分发不同版本的 C 库 开发模拟器的公司定期发布新版本 每个新版本都会有一个递增的主版本号 据我所知 版本之间的
  • PHP rtrim 函数修剪多余字符?为什么?

    如何rtrim工作 我有一个字符串 4dbb3dca 我不确定我的字符串是如何格式化的 我想打电话rtrim 4dbb3dca amp edit 可能 amp 特殊字符问题 但是在我的字符串之后4dbb3dc 我希望它是4dbb3dca 有
  • C++开发值得学Eclipse吗

    据我所知 从头开始学习使用 Eclipse 是很困难的 但我会得到诸如快速源代码浏览 调用图 静态代码分析等好处 使用 Eclipse for C CDT 还能带来哪些其他好处 我学习了 C Eclipse 它非常灵活并提供许多功能 我不再
  • 使用两个 1d 数组高效索引 2d numpy 数组

    我有一个大型 2d numpy 数组和两个 1d 数组 表示 2d 数组中的 x y 索引 我想使用这些一维数组对二维数组执行操作 我可以使用 for 循环来完成此操作 但在处理大型数组时速度非常慢 有更快的方法吗 我尝试简单地使用一维数组
  • Scala:隐式传递一个隐式参数,显式传递另一个参数。是否可以?

    让我们考虑一下这个函数 def foo implicit a Int b String println a b 现在 让我们假设有一个隐含的String and Int implicit val i1 1 在范围内 但我们想传递另一个 no
  • 构建器模式与配置对象

    构建器模式在创建不可变对象时很流行 但创建构建器会产生一些编程开销 所以我想知道为什么不简单地使用配置对象 构建器的用法如下所示 Product p Product Builder name Vodka alcohol 0 38 size