Pull to refresh

Comments 50

интересно
скажите, а в java нет типа decimal? в .net (к примеру в C#) есть и он как раз рекомендуется для использования в финансовых операциях.
java.math.BigDecimal
как раз long лучше заменить в данном случае на него.
Зачем на него заменять long, если удалось избавиться от дробной части.
Кроме того, поробуйте выполнить тот же тест что и для double для BigDecimal.
Результат будет таким же.
ну при его использовании не придется избавляться от дробной части, она там обрабатывается и округляется так, как вам будет нужно
В данном случае использование целочисленного типа упрощает написанный код. Избавиться от дробной части не сложно и делать это нужно в одном месте. Следить же за округлением пришлось бы во всех местах.
Кроме того, long — стандартный тип, поэтому можно использовать стандартные операторы, что повышает читаемость кода.
да я понимаю. В большинстве случаев ваша реализация подойдет на 100%. Но если писать более общий класс Money, то лучше, пожалуй, выбрать BigDecimal.
Использование BigDecimal тоже вполне возможно, но только в каком случае не подойдет этот класс Money?
Я вижу единственный случай — использование слишком больших значений денег, но тогда можно заменить long и на BigInteger.
ну вот, какой-то тролль прошелся и по вашей карме и по моей…
Да, действительно.
Странно.
кстати, попробовал выполнить ваш тест с BigDecimal.
результат превосходный и совсем не такой как с double =)
Я запускаю следующий код:
BigDecimal val = new BigDecimal( 0.00 );
for (int i = 0; i < 10; i++) {
  val = val.add( new BigDecimal(0.10) );
}
System.out.println( val.equals( new BigDecimal( 1.00 ) ) );
* This source code was highlighted with Source Code Highlighter.

Результат такой же как с double.
1. сравнивать надо их через compareTo()
2. создавать лучше через BigDecimal(String val)
вот так попробуйте

BigDecimal result = new BigDecimal(«0»);
for (int i = 0; i < 10; i++){
result = result.add(new BigDecimal(«0.10»));
}
System.out.println(result.compareTo(new BigDecimal(«1»)));
Так работает, но только, если выполнить два эти условия.
С конструктором из double не работает.
Вообще, на мой взгляд, для работы с этим классом нужно соблюсти слишком много условностей, про которые можно и забыть.
ну в общем 2 пути. Либо прочесть документацию к готовому велосипеду и соблюсти инструкцию, либо изобрести свой велосипед. В принципе ради тренировки можно и второй вариант выбрать.
Жаль, что в Java нет перегрузки операторов. Как-то уныло вызывать всякие subtract…
там и правда нет много «синтаксического сахара», который придумали в других языках. Но в этом есть и своя прелесть — объекты, методы, чистый ооп. Никаких свойств, делегатов, событий и перегрузки операторов.
Знаете — это как пользоваться утилитами через UI или консоль. Есть любители и того и другого.
Не соглашусь со сравнением. GUI (именно так, консоль — тоже UI) и консоль — разные интерфейсы, разные способы доступа к одинаковым функциям. А наличие делегатов и перегрузок и их отсутствие — это именно наличие и отсутствие функций, которым, кстати, никто не заставляет пользоваться. Грубо говоря, не нравится — не ешь.
в C# можно реализовать такую же событийную модель как в Java. Пользуясь только объектами и их методами. А можно использовать делегаты и события. Результат будет одинаковым, как и в случае использования консоли и GUI (пасиб за поправку)
И это прекрасно. Все довольны остаются.
Это в Java-то чистый ООП? Cкажите-ка, переменная типа int — это объект или нет?
И у него, наверное, есть методы, состояние и прочие обязательные признаки объекта? И какого же он класса?

PS. На всякий случай: что такое autoboxing я знаю, и это совсем-совсем другое.
Не стану утверждать наверняка (не было времени проверить), но ИМХО, было бы глупо реализовывать примитивные типы не как объекты в языке, в котором все остальное реализовано как объекты, даже сами классы являются объектами класса Class. Другое дело, что для программиста примитивные типы не выглядят как объекты. Синтаксический сахар это называется, вроде?
Ну, во-первых, примитивные типы были введены, как оптимизация.

Во-вторых, про «объекты в языке» (наверное, имелось в виду «объекты с точки зрения VM»?) vs «объекты для программиста» — это даже интересно. Как по вашему, для кого придумывается язык программирования, для программиста или для компьютера? Чтобы кому было удобнее? Или поставлю вопрос даже более широко — для кого придумывался ООП, для программиста или для компьютера? И даже если примитивные типы трактовались бы VM, как объекты (на всякий случай уточню, что это не так), то меня, как программиста, это совершенно не волновало бы (в первом приближении) — потому что я не могу с ними работать, как с объектами. И чтобы хотя бы частично компенсировать это, и была придумана подпорка под названием autoboxing (которая, кстати, в отличии от «объектности с точки зрения программиста», является в чистом виде синтаксическим сахаром).

Ну и в-третьих, относительно синтаксического сахара — возможно, мне показалось, но у меня создалось впечатление, что вы использовали это словосочетание в пренебрежительном смысле — так ли это? :-)
Неременная типа int — это НЕ объект. Но умеет прикидываться объектом когда надо посредством autoboxing.
Всё будет хорошо?..
да, конечно! Прорвемся
Может быть, это и не так плохо. Есть много противников перегрузки операторов.
Об этом подробно написано в википедии.
Может, и не плохо. Специально для «противников» в своих шарповых классах делаю и add/subtract, и ±. Чтоб не били.
Кроме спорности, наличие перегрузки ослажняет реализацию самого языка.
Ну, разве это наши с Вами проблемы? :)
Не наши, если это не скажется на производительности.
у меня сложилось впечатление, что Фаулер написал целую главу по мотивам вашего поста. а Кент Бек так и вообще полкнижки.
опередили :)
Всем читать «Архитектура корпоративных программных приложений» Фаулера. Там достаточно подробно тема раскрывается.
currency != null?!
Спокойнее, спокойнее :)
Этот код сгенерирован IDEA. Я сам бы до такого не додумался.
Идея часто подсказывает оптимизации, которые лучше не использовать.
Я бы наверное как-то так написал:
if ((currency == null) != (money.currency == null) || !currency.equals(money.currency)) return false;
:)
Основное требование к коду — чтобы он легко читался и понимался, а отнюдь не чтобы он выглядел круто. Сравнение результатов сравнений отнюдь не улучшает читаемость (потому что читающему приходится, по сути, привести в уме ваш код к более нормальному виду и оперировать уже с ним).
Да, разумеется. Просто у меня в час ночи мысли были не о том, как написать читаемо а просто избавиться от тренарного оператора.
UFO just landed and posted this here
Я не проверял очень простые методы.
Метод CompareTo тоже простой. В нем вред ли возникнет ошибка, но я все же проверил один вариант.

Некоторые предпочитают проверять все функции. Бек, по-моему, как раз за это.
Другие же, например Фаулер, считают, что проверять элементарные функции не нужно.
Я считаю, что написание полных тестов занимает слишком много времени, что не окупится.
Тест можно поправить, если обнаружится глюк. Многие ошибки выявятся функциональном тестированием.
UFO just landed and posted this here
Много кода из ничего. Одна из черт, за которые не люблю Джаву.
отличная идея постить на хабре результаты своего творчества. Хотите похвастаться своим кодом — идите на sf.net хотя бы…
Я написал этот код специально для статьи.
На мой взгляд, та проблема, которую я здесь описал заслуживает внимания.
я не против чтобы вы писали код…
Удивительно, как много строчек кода нужно написать для реализации фигни.
Sign up to leave a comment.

Articles