【问题标题】:What is the best way to build a subclassed object of an abstract superclass with required and optional parameters in Java 9?在 Java 9 中构建具有必需和可选参数的抽象超类的子类对象的最佳方法是什么?
【发布时间】:2017-10-06 09:39:08
【问题描述】:

在 Java 中构建对象有多种方法。对于我的用例,假设我有一个带有私有属性字段的抽象 Person 类和一个名为 Tom 的子类。

1.获取器/设置器

Person 类中的无参数构造函数、setter 和 getter。可以通过使用 Project Lombok 的 @Data 注释来简化。

Tom tom = new Tom(); // Subclass of Person
tom.setName("Tom");
tom.setAge(42);

我读到除非使用框架,否则应该避免使用这种方法。

2。参数化构造函数

使用构造函数参数构建对象。具有各种可选和必需属性的大对象的过度构造函数重载。也可以使用 Project Lombok 的各种constructor annotations 进行简化。

Tom tom = new Tom("Tom", 42);

然后,Tom 的构造函数将调用super("Tom", 42)。在Person中,如果可选参数较多,可以使用构造函数重载。

3.建造者模式

因为构造函数重载会很快变得非常混乱,Josh Bloch 提出了构建器模式。同样,这可以通过 Project Lombok 的 @Builder 注释来简化。这是使用非抽象 Person 类时的样子:

Person person = new Person.Builder().name("Tom").age(42).build();

正如others 在我之前所说的那样,尝试将构建器模式与继承一起使用是困难的(但并非不可能)。


我确信构建对象的方法还有很多,但我只列出了我熟悉的那些。

我的问题是:使用 Java 8 甚至 Java 9 功能,构建作为具有必需和可选属性的抽象超类的子类的对象的绝对最佳方法是什么? p>

很多关于 SO 的教程和问题已经过时,并且可能没有强制执行现在被认为是最佳实践的内容。

【问题讨论】:

    标签: java oop inheritance abstract-class lombok


    【解决方案1】:

    不幸的是,Java 和 OO 中的最佳实践是非常主观的,但我尝试列出一些主要是客观的标准:

    1. 该类是否为子类根本不应该影响该类的 API,包括其构造函数的外观。

    2. 对象应该在构造后准备好使用。这意味着它的所有公共方法都应该在构造函数之后工作。这会取消您的选项#1 的资格。 (除非被不友好的框架强制)。

    3. 有一个“主”构造函数来完成工作,并让所有其他构造函数调用这个。除非您的超类也有许多构造函数,否则事情会变得更加复杂,否则您很可能必须反映超类想要的东西。

    4. 它应该易于使用。这意味着,除非使用它们变得困难,否则最好使用构造函数而不是生成器。如果有很多参数(对我来说超过 3-4 个),或者它们的组合可能太多(再次,对我来说超过 3-4 个),或者有一个构造深度(必须构造其他对象首先),然后我会使用构建器。

    5. 在任何情况下都不要使用Optional 作为参数。

    6. 不要使用龙目岛。它可能会让你的(作者)的生活更轻松,但会惹恼所有必须阅读代码的人。请记住,我们阅读代码的次数远多于编写代码! (这可能是一个值得商榷的点)

    7. 继承很棘手,应尽可能避免。不要用它来共享代码,这是一种反模式。对于建筑商来说也是如此。您可以编写一个可以返回不同实现类的构建器,但它不必(不应该)子类化其他构建器来执行此操作。

    我可能忘记了一些规则,但除此之外,Java 8 和 9 中没有新的突破性语法来简化构造。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-21
      • 1970-01-01
      • 1970-01-01
      • 2014-03-21
      • 2020-10-30
      • 1970-01-01
      相关资源
      最近更新 更多