我研究了这个主题,发现通过构造函数分配字段比 setter 更好。但是,如果我有一个包含 10 个字段的对象怎么办?这将导致大型建筑商,这仍然被认为是良好做法吗?
例如:
public DefaultAccount(Long id, String name, String surname, String username, String password, Role role) {
this.id = id;
this.name = name;
this.surname = surname;
this.username = username;
this.password = password;
this.role = role;
}
这个构造函数对我来说看起来很大。
采用多个参数的构造函数(或具有多个采用不同参数集的构造函数)的一个问题是,当多个参数具有相同的类型时可能发生的错误。从您的示例中考虑以错误的方式获取姓名和姓氏顺序是多么容易。
对此的解决方案可能是使用生成器模式。
以下是对其工作原理的全面介绍: 实践中的构建器模式下面的堆栈溢出问题也很好地涵盖了它:你什么时候会使用构建器模式
这取决于情况。您列出的示例是一个非常简单的类,只有简单的类型。我认为这没关系。但是,我不太确定你考虑二传手的说法。但是您可能需要考虑一些事情:
如果你正在使用一些更大的框架(Spring,Hibernate...),它们中的很多将使用默认构造函数(如new Person())实例化对象,然后为字段调用setters。如果某些内容不可用,它们将引发异常。
拥有像您列出的构造函数一样的构造函数很好。但无论如何都需要二传手。如果它们变得复杂,请考虑重构类。也许需要太多的依赖项。也许不是有 10 个参数,而是将它们封装在另一个对象中(例如配置)。
尽量不要公开字段。当在某些时候你必须检查 setter 中的某个条件并且你的字段是公开的时,你会花一些时间来重构它。如果需要,请检查 setter 中的前提条件并引发异常。
我还在stackoverflow上发现了这个问题,它进一步提出了关于setter的问题:Java在构造函数中设置私有字段
在任何方法(包括构造函数)中都有大量参数是一种不好的做法。
首先,我看到 DefaultAccount 构造函数,其字段与帐户没有直接关系。
例如,您应该将示例名称和姓氏提取到另一个(用户?)类等。
如果不是所有的参数都是强制性的,那么考虑使用Joshua Bloch在Effective Java的项目#2中建议的Builder模式,其中说...
客户端不是直接创建所需的对象,而是调用 具有所有必需参数的构造函数(或静态工厂) 并获取生成器对象。然后客户端调用类似 setter 的方法 以设置感兴趣的每个可选参数。 最后,客户端调用无参数
build
方法来生成 对象,这是不可变的。
在我看来,最有效的方法是将问题分解为尽可能多的类,如下所示:
public DefaultAccount(Long id, String name, String surname, User user)
{
this.id = id;
this.name = name;
this.surname = surname;
this.user = user;
}
// From second class User
public User(String username, String password, Role role)
{
this.username = username;
this.password = password;
this.role = role;
}
通过这种方式,您可以避免大量的构造函数,并提高代码的可维护性和可读性。
您还可以使用配置类,如此处所述。
当你有多个类时,也会使用getter和setter,当你的字段是私有的(或受保护的并且需要从另一个包访问)时也是如此。如果你只有一个类,你不需要创建getter和setter,你可以直接将值分配给对象(假设你不想在构造函数中赋值)