通过 setter 或构造函数分配多个字段



我研究了这个主题,发现通过构造函数分配字段比 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,你可以直接将值分配给对象(假设你不想在构造函数中赋值)

最新更新