Почему API даты Java (java.util.Date, .Calendar) такой беспорядок?

Как многие люди до сих пор до боли осведомлены, Java API для обработки календарных дат (особенно классов java.util.Date а также java.util.Calendar) ужасный беспорядок.

С верхней части моей головы:

  • Дата изменчива
  • Дата представляет собой метку времени, а не дату
  • нет простого способа преобразования между компонентами даты (день, месяц, год...) и датой
  • Календарь неудобен в использовании и пытается объединить разные календарные системы в один класс

Этот пост довольно хорошо подводит итог, и JSR-310 также раскрывает эти проблемы.

Теперь мой вопрос:

Как эти классы попали в Java SDK? Большинство из этих проблем кажутся довольно очевидными (особенно это касается того, что Date изменчивый), и их было легко избежать. Так как же это случилось? Время поджимает? Или проблемы очевидны только в ретроспективе?

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

4 ответа

Решение

Кто-то сказал это лучше, чем я мог бы сказать:

  • Учебный класс Date представляет определенный момент времени с точностью до миллисекунды. Дизайн этого класса - очень плохая шутка - отрезвляющий пример того, как облажаются даже хорошие программисты. Большинство методов в Date теперь устарели, их заменили методы в классах ниже.
  • Учебный класс Calendar абстрактный класс для преобразования между Date объект и набор целочисленных полей, таких как год, месяц, день и час.

  • Учебный класс GregorianCalendar это единственный подкласс Calendar в JDK. Это делает преобразования Даты в поля для календарной системы в общем использовании. Sun лицензировала этот сверхнормативный мусор от Taligent - отрезвляющий пример того, как облажаются среднестатистические программисты.

из FAQ для программистов Java, версия от 07.X.1998, автор Peter van der Linden - хотя эта часть была удалена из более поздних версий.

Что касается изменчивости, многие ранние классы JDK страдают от этого (Point, Rectangle, Dimension...) Неправильная оптимизация, я слышал, некоторые говорят.

Идея в том, что вы хотите иметь возможность повторно использовать объекты (o.getPosition().x += 5) вместо создания копий (o.setPosition(o.getPosition().add(5, 0))), как вы должны делать с неизменными. Это, возможно, даже было хорошей идеей для ранних виртуальных машин, но, скорее всего, не для современных виртуальных машин.

Ранние API Java - не более чем продукт своего времени. Неизменность стала популярной концепцией только спустя годы. Вы говорите, что неизменность "очевидна". Это может быть правдой сейчас, но не тогда. Также как внедрение зависимости теперь "очевидно", но это было не 10 лет назад.

Также было в свое время дорого создавать объекты Календаря.

Они остаются такими по причинам обратной совместимости. Возможно, более прискорбно то, что после того, как ошибка была осознана, старый класс не устарел, и были созданы новые классы даты / времени для всех API в будущем. В некоторой степени это произошло с принятием JDK 8 API, подобного JodaTime (java.time, JSR 310) но на самом деле это слишком мало, слишком поздно.

Время само по себе не легко измерить и справиться. Просто посмотрите на длину статьи в Википедии о времени. Кроме того, существуют разные представления о самом времени: абсолютная точка времени (как постоянная), точка времени в определенном месте, диапазон времени, разрешение времени...

Я помню, когда я впервые увидел java.util.Date (JDK 1.0?), Я был очень этому рад. Языки, которые я знал, не имели такой возможности. Я не думал о преобразовании времени и т. Д.

Я думаю, что это беспорядок, потому что все, что меняется, оставляет беспорядок, если вы эволюционируете от одного уровня понимания (XMLGregorianCaldender vs. Date) и требований (наносекунды, прошедшие 2030) к более высокому уровню, но сохраняя старое нетронутым. И java.util.Date не является исключением. Достаточно взглянуть на подсистему ввода-вывода или переход от AWT к Swing...

И из-за этого, "мы должны иногда нажимать кнопку сброса". (кто это сказал, кстати?)

Вы можете найти следующий пост интересным. Это в значительной степени объясняет, как класс Calendar в первую очередь попал в Java API, и проливает некоторый свет на происхождение класса date.

Семь Навыков Дисфункционального Дизайна

Другие вопросы по тегам