Что мы можем узнать из печальной истории о java.util.Date

Поскольку java.util.Date медленно, но верно устаревает в Заход Солнца, java.time принимает его мантию, стоит сделать паузу, чтобы извлечь некоторые уроки из его беспокойной жизни, прежде чем позволить ему успокоиться.

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

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

Учитывая его название, было бы неплохо, если бы Date представлял календарную дату, то есть определенный день ... но это не так. Он представляет собой момент времени, который можно рассматривать как имеющий компонент даты. Обычно это называется дата – время или, если вы хотите поместить его в код, DateTime. Time также работает, поскольку это всеобъемлющая концепция. Иногда бывает сложно найти правильное имя; в данном случае это не так.

Теперь мы понимаем, что мы подразумеваем под датой, датой – временем и Date, что делает getDate? Возвращает ли он все значение даты и времени? Или, может быть, просто компонент даты? Ни то, ни другое: возвращает день месяца. В кругах программистов это значение чаще и конкретно обозначается как день месяца, а не дата, термин, обычно зарезервированный для представления календарной даты.

И пока мы здесь, да, getDay лучше было бы назвать getDayOfWeek. Мало того, что важно выбрать правильное имя, важно распознавать и разрешать неоднозначные термины, такие как день (неделя, месяц, год…?). Обратите внимание, что проблемы с именованием лучше решать, выбирая более подходящее имя, чем с помощью javadoc.

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

Например, Аполлон-11 приземлился на Луну в 20:17 20 июля (седьмой месяц) 1969 года (CE, UTC и т. Д.). Но если вы вызываете getTime, getDate, getMonth и getYear, ожидая этих чисел, ожидайте разочарования: getTime возвращает отрицательное число миллисекунд с начала 1970 года; getDate возвращает 20 (как и ожидалось, считается от 1); getMonth возвращает 6 (месяцы отсчитываются от 0); а getYear возвращает 69 (годы отсчитываются с 1900, а не с 0 и не с 1970).

Хороший нейминг - это часть дизайна. Он устанавливает ожидания и представляет модель, показывающую, как что-то следует понимать и использовать. Если вы хотите рассказать читателю getMillisSince1970, не говори getTime. Конкретные имена побуждают вас рассматривать альтернативы, задаваться вопросом, правильно ли вы улавливаете правильную абстракцию. Это не просто маркировка и не просто java.util.Date: речь идет о коде, который вы пишете, и коде, который вы используете.