具有所有类属性的构造函数还是具有 setter 的默认构造函数?

2022-09-01 20:07:18

以下是两种方法:

  • 具有所有类属性的构造函数

优点:我必须输入确切数量的参数类型,因此如果我犯了错误,编译器会警告我(顺便说一句,有没有办法防止在参数列表中错误地切换两个整数的问题?

缺点:如果我有很多属性,实例化行可能会变得非常长,并且可以跨越两条或多行

  • setter 和默认的空构造函数

优点:我可以清楚地看到我正在设置的内容,所以如果我做错了什么,我可以在键入它时立即查明它(我不能犯切换两个相同类型的变量的previuos错误)

缺点:具有大量属性的对象的实例化可能需要几行(不知道这是否真的是一个缺点),如果我忘记设置属性,编译器不会说什么。

你会做什么,为什么?您是否知道任何光模式(考虑每次实例化具有7个以上属性的对象时都应使用它)来建议?我之所以问这个问题,是因为我倾向于不喜欢大型构造函数,我无法快速找出我正在寻找的变量在哪里,另一方面,我发现“设置所有属性”很容易丢失一些属性。

随意论证我的假设的利弊,因为它们只是我的想法:)

更新 - 我发现的一个与此相关的问题:构建大型,不可变的对象,而无需使用具有长参数列表的构造函数


答案 1

您错过了拥有大量参数的构造函数的最大优点:它允许您创建不可变类型。

创建不可变类型的正常方法是使用帮助器类型 - 一个构建器,它维护最终对象中所需的值,然后在准备就绪时构建不可变对象。


答案 2

您可以看看Joshua Bloch倡导的Builder模式,并在 Effective Java 中进行了描述。有一个演示文稿,其中包含 http://developers.sun.com/learning/javaoneonline/2007/pdf/TS-2689.pdf 要点;毫无疑问,你可以挖掘出一个更好的参考。

基本上,您有另一个类,可能是一个内部类,它提供以正在设置的属性命名的方法,并返回原始生成器,以便您可以链接调用。它构成了一个相当可读的代码块。

例如,假设我有一个具有一些属性的简单。构造此内容的客户端代码可以使用生成器来准备如下:MessageMessage

Message message = new Message.Builder()
    .sender( new User( ... ) )
    .recipient( new User( ... ) )
    .subject( "Hello, world!" )
    .text( messageText )
    .build();

的片段可能类似于以下内容:Message.Builder

public class Builder {

    private User sender = null;
    // Other properties

    public Builder sender( User sender ) {
        this.sender = sender;
        return this;
    }
    // Methods for other properties

    public Message build() {
        Message message = new Message();
        message.setSender( sender );
        // Set the other properties
        return message;
    }

}