Должны ли методы быть разрушительными в пользовательских объектах? - PullRequest
2 голосов
/ 10 марта 2009

Я должен реализовать Java.Polynomial как школьное задание. Часть методов: сложение (полином) , умножение (полином) и т. Д.

В случае чего-то вроде

p.add(q); // computes p + q

лучше ли вернуть void и оставить сумму полиномов в p? или лучше вернуть многочлен и оставить прежнее значение p без изменений?

Мой инстинкт подсказывает мне, что я должен сделать следующее

  • реализовать p.add (q) как «деструктивный» метод ... он добавляет q к значению p и сохраняет сумму в p
  • также реализует статический метод Polynomial.add (p, q), который возвращает сумму полиномов.

Что вы думаете?

Ответы [ 8 ]

7 голосов
/ 10 марта 2009

Лично мне очень нравятся неизменные типы. Я бы написал p.plus(q) вместо p.add(q) и вернул бы новый многочлен. Неизменность имеет большое значение не только с точки зрения безопасности потоков (что в данном случае кажется, что это не проблема), но и с точки зрения рассуждений о вашем коде. Намного проще предсказать, что произойдет, если вы знаете, что ничто не может изменить содержимое объекта под вашими ногами, когда вы спрятали ссылку на него.

6 голосов
/ 10 марта 2009

Это вопрос стиля. Обычно лучше (и «аккуратнее»), когда объекты неизменяемы, поэтому методы не являются «деструктивными» (они не являются мутаторами, у них нет побочных эффектов), но возвращают новый экземпляр с новым значением.

Самым известным неизменным классом является String.

3 голосов
/ 10 марта 2009

Таким образом, все говорят, что вы должны сделать его неизменным, и если нет особых причин, чтобы сделать его изменчивым (вы добавите миллиард многочленов к одному магическому и не хотите выделять память), неизменность это путь.

Если у вас есть подлинные причины производительности, вы можете захотеть иметь деструктивную и неразрушающую версию, но помните - это приводит к путанице. Я думаю, что ваша идея перегрузки добавить, чтобы быть разрушительной или не основанной на хитрости, сделает вещи очень, очень запутанными. Лучше сделайте все неразрушающим и сделайте метод addDestructive (poly p), если вы выберете.

3 голосов
/ 10 марта 2009

«Лучше вернуть полином и сохранить прежнее значение p в неизменном виде»

Жизнь станет лучше, если вы заставите ваши числовые типы вести себя как другие числа.

«Деструктивные» операции являются неизбежным злом, когда вам приходится оптимизировать производительность за счет сокращения выделения памяти.

Компромисс в том, что ваша обработка становится непрозрачной из-за более сложных изменений состояния переменных в состоянии. Вы не хотите скрытого изменения состояния; вы хотите, чтобы ваши присвоения значений переменным были большими, очевидными первоклассными, с чем-то вроде.

2 голосов
/ 10 марта 2009

Даже если вы используете «деструктивный» метод, вы все равно захотите вернуть новое значение, чтобы включить цепочку функций. И, несмотря ни на что, столкнувшись с одной и той же проблемой для BigInteger и BigDecimal, Sun решила пойти неразрушающе.

1 голос
/ 10 марта 2009

Полином имеет фиксированное значение в терминах своих переменных, и, таким образом, имеет смысл только быть неизменным. Верните новый полином для ваших операций.

1 голос
/ 10 марта 2009

лучше ли вернуть void и оставить сумму полиномов в p?

Неплохо, не обязательно лучше.

или лучше вернуть полином и сохранить прежнее значение p в неизменном виде?

Это лучше, меньше сюрпризов, а код легче понять и поддерживать. (хотя вам придется создать больше переменных)

1 голос
/ 10 марта 2009

Сделайте его неизменным и сделайте интерфейс таким же, как для BigInteger (насколько это применимо).

...