Что вызывать фабричные (java) методы, используемые с неизменяемыми объектами - PullRequest
5 голосов
/ 04 января 2011

При создании классов для «неизменяемых объектов» подразумевается неизменное состояние экземпляров; все поля, назначенные в конструкторе) в Java (и аналогичных языках), иногда полезно разрешить создание измененных экземпляров. То есть, используя экземпляр в качестве базы и создавая новый экземпляр, который отличается только одним значением свойства; другие значения, поступающие из базового экземпляра. Чтобы привести простой пример, можно было бы иметь такой класс:

public class Circle {
  final double x, y; // location
  final double radius;

  public Circle(double x, double y, double r) {
    this.x = x;
    this.y = y;
    this.r = r;
  }

  // method for creating a new instance, moved in x-axis by specified amount
  public Circle withOffset(double deltaX) {
    return new Circle(x+deltaX, y, radius);
  }
}

Итак: как должен вызываться метод withOffset? (примечание: НЕ то, что должно быть его именем - но как называется этот класс методов). Технически это своего рода фабричный метод, но почему-то это не совсем подходит мне, поскольку часто фабрикам просто присваиваются базовые свойства (и они являются либо статическими методами, либо не являются членами типа результата, но типа фабрики).

Так что я предполагаю, что для таких методов должен быть лучший термин. Поскольку эти методы могут использоваться для реализации « Свободный интерфейс », может быть, они могут быть «Свободные фабричные методы»? Лучшие предложения?

РЕДАКТИРОВАТЬ: как предлагает один из ответов, java.math.BigDecimal является хорошим примером с его методами «сложение», «вычитание» (и т. Д.).

Также: я заметил, что есть этот вопрос (не менее Джоном Скитом), который как бы связан (хотя он спрашивает о конкретном имени для метода)

РЕДАКТИРОВАТЬ, МАЙ-2014: Мой текущий любимый mutant factory, FWIW.

Ответы [ 3 ]

3 голосов
/ 04 января 2011

Хм ... он создает мутированные версии объекта ... может быть, мы должны назвать его фабрикой мутантов? : -)

3 голосов
/ 04 января 2011

Я называю эти типы методов "методы копирования" .

Хотя метод clone() создает точную копию, метод copy создает копию экземпляра, как правило, с подразумеваемым или явным изменением.Например, String#toUpperCase() будет методом копирования неизменяемого класса String - он копирует экземпляр с вариацией: он преобразует все буквы в буквы.

Я бы назвал метод withOffset() в вашем примере каканалогичный метод копирования.

Я не знаю ни одной ссылки, которая документирует термин «метод копирования».Я заимствовал термин «копия» из его использования в C ++: конструкторы копирования и руководство по именованию «копировать» из стандартов кодирования Taligent ( больше информации ).


Asдля термина "плавные фабричные методы" я не знаю, почему "свободный" будет иметь значение, поскольку "свободный интерфейс" - это просто стиль API (отдельный от шаблона компоновщика).Если термин «фабричный метод» здесь не применим, я не вижу, как его называть «беглый фабричный метод» делает его лучше.

1 голос
/ 04 января 2011

Это не похоже на заводской метод. Одна только подпись только говорит мне, что я могу связать ее в разных вызовах, но не то, что она должна создавать новый экземпляр: Я вижу этот вариант использования более похожим на StringBuilder, который позволяет append ("a"). Append ("b"). Конечно, он может каждый раз возвращать новый StringBuilder (как это делает ваш Круг).

Так что это не дизайн фабрики. (Подумайте о том, чтобы извлечь интерфейс и написать JavaDoc для этого метода: «нужно вернуть новый экземпляр, так как я неизменный» - почему так ??) Тот факт, что ваш класс неизменен, - это просто деталь реализации).

EDIT: Перас лучшим примером был бы BigInteger, так как он также неизменен. Наряду с умножением (BigInteger), он предоставляет метод, закрытый для пакета:

BigInteger multiply(long v)

, который возвращает новый экземпляр и очень похож на ваш случай. Это просто операция, которая возвращает результат того же типа, что и исходный объект; не фабрика, и я не думаю, что такая операция действительно заслуживает своего имени.

...