当前位置: 首页 > 面试题库 >

无需使用具有长参数列表的构造函数即可构建大型的不可变对象

秦宁
2023-03-14
问题内容

我有一些大对象(超过3个字段),它们可以并且应该是不变的。每次遇到这种情况时,我倾向于使用长参数列表创建构造函数可憎的对象。

感觉不对,很难使用,并且可读性受到影响。

如果字段是某种类型的集合类型(如列表),那就更糟了。一个简单的方法addSibling(S s)可以极大地简化对象的创建过程,但是使对象可变。

你们在这种情况下使用什么?

我使用的是Scala和Java,但我认为只要语言是面向对象的,问题就与语言无关。

我能想到的解决方案:

  1. “带有长参数列表的构造函数可憎”
  2. 建造者模式

问题答案:

好吧,您希望创建后既易于阅读又不可变的对象吗?

我认为 正确完成的 界面会为您提供帮助。

看起来像这样(完全由示例组成):

final Foo immutable = FooFactory.create()
    .whereRangeConstraintsAre(100,300)
    .withColor(Color.BLUE)
    .withArea(234)
    .withInterspacing(12)
    .build();

我用黑体字写了 “ CORRECTLY DONE”
,因为大多数Java程序员错误地使用了流畅的接口,并用构建对象的必要方法污染了对象,这当然是完全错误的。

诀窍是 只有build()方法实际上会创建Foo (因此Foo可能是不可变的)。

FooFactory.create() ,其中 XXX(..)withXXX(..) 都创建“其他”。

还有别的东西可能是FooFactory,这是做到这一点的一种方法。

您的FooFactory如下所示:

// Notice the private FooFactory constructor
private FooFactory() {
}

public static FooFactory create() {
    return new FooFactory();
}

public FooFactory withColor( final Color col ) {
    this.color = color;
    return this;
}

public Foo build() {
    return new FooImpl( color, and, all, the, other, parameters, go, here );
}


 类似资料:
  • 我有一个下面的类,它是子类的基本DTO。我需要修复受保护的构造函数,因为Intellij说:“参数化类生成器的原始使用”。有人可以看看,并指出如何重新编写这个构造函数,以支持通用风格在这里。 你觉得可能吗?有人看到此代码的潜在问题吗?感谢先进。

  • 鉴于 IntelliJ IDEA 2016.1.1报告“可以替换为方法引用”。 我知道无参数构造函数的< code>Foo::new语法,但是不知道如何将< code>foo作为参数传入。我肯定漏掉了什么。

  • 以这种方式传递参数有问题,我得到以下错误:“std::thread::thread”:没有重载函数接受4个参数。我怎么能这么做?

  • 我是新的Android和Java,并试图使基于位置的应用程序。 编辑 我做了一个非常非常简单的测试代码,得到了同样的错误。这是java: 我也犯了同样的错误。以下是我的应用程序级构建中的依赖项。格雷德尔: 原帖 我试图使用ViewModel和LiveData来更新用户位置,因为我知道这是生命周期感知的最佳方式。我有一个默认的地图活动... 一个扩展LiveData以存储用户位置的类。。。 以及一个

  • 请考虑以下定义和演绎指南: 如果我尝试使用显式模板参数实例化 ,代码将正确编译: 如果我试图通过演绎指南实例化< code>foo... > G7产生编译器错误: clang 5 爆炸: wandbox上的实例 虽然clang肯定被窃听了(报告为问题#32673),但g拒绝我的代码是正确的吗?我的代码格式错误吗?

  • 在经历冬眠3时。x文档我知道我们也可以为具有私有可见性的POJO声明一个无arg构造函数,但文档说它有限制: 无参数构造函数是所有持久类的要求;Hibernate必须使用Java反射为您创建对象。构造器可以是私有的,但是在没有字节码插装的情况下,运行时代理生成和有效的数据检索需要包或公共可见性。 我不熟悉Hibernate,我试图了解何时使用运行时代理,何时使用字节码,以及这在Hibernate中