Должны ли методы быть разрушительными в пользовательских объектах?

StackOverflow https://stackoverflow.com/questions/628049

  •  06-07-2019
  •  | 
  •  

Вопрос

Мне нужно реализовать Java.Polynomial в качестве школьного задания.Часть методов добавить (полином), умножить (полиномиальный) и т. д.

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

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

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

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

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

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

Это было полезно?

Решение

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

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top