Prestructors

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

让构造函数在封装参数之前对其进行预处理似乎是一种不好的做法。然而,很多时候确实需要这样做:对作为参数提供的对象进行一些操作,然后再将它们赋值给构造对象的属性。为此,我建议使用“prestructors”(预处理器),它可以是方法或独立的对象。

假设这是你的代码:

import java.util.List;
import java.util.Collections;
class Books {
  private final List<String> titles;
  Books(List<String> list) {
    this.titles = Collections.unmodifiableList(list);
  }
}

唯一的构造函数期望一个标题列表,这个列表被封装为this.titles以备将来使用。它还通过JDK装饰器unmodifiableList来防止任何意外修改。到目前为止,一切都很好。现在,我们想让我们的类更智能一些,不仅接受List,还接受一个字符串数组:

class Books {
  private List<String> titles;
  Books(List<String> list) {
    this.titles = Collections.unmodifiableList(list);
  }
  Books(String... array) {
    final List<String> list = new ArrayList<>(array.length);
    for (final String title : array) {
      list.add(title);
    }
    this.titles = list;
  }
}

这段代码有什么问题?那些阅读过我之前有关面向对象编程的博客文章的人肯定知道答案。首先,有两个主要构造函数,这是另一个不好的实践。其次,在第二个构造函数中有代码,这也是一个不好的想法。

以下是我通常如何重构这段代码,以解决上述两个问题:

class Books {
  private List<String> titles;
  Books(List<String> list) {
    this.titles = Collections.unmodifiableList(list);
  }
  Books(String... array) {
    this(Books.toList(array));
  }
  private static List<String> toList(String... array) {
    final List<String> list = new ArrayList<>(array.length);
    for (final String title : array) {
      list.add(title);
    }
    return list;
  }
}

我把这个新的静态方法toList()称为prestructor:它仅在对象构造的瞬间使用,而且仅从次要构造函数中使用。

更好的设计方法是创建一个名为ToList的新类,它可以以更声明性和延迟的方式完成完全相同的操作:

class Books {
  private List<String> titles;
  Books(List<String> list) {
    this.titles = Collections.unmodifiableList(list);
  }
  Books(String... array) {
    this(new ToList(array));
  }
}
class ToList<T> implements List<T> {
  private final T[] array;
  ToList(T... items) {
    this.array = items;
  }
  // All required methods of the List interface
}

ListOf来自Cactoos是这样一个预构造器的完美示例。

Translated by ChatGPT gpt-3.5-turbo/36 on 2023-10-12 at 16:02

sixnines availability badge   GitHub stars