среда, 5 мая 2010 г.

[prog.flame] Попрограммировал на Java, делюсь впечатлениями. Часть VI. Форматирование кода и Javadoc.

Очередная, вероятно, заключительная заметка о впечатлениях после программирования на Java. Предыдущие части:

Часть I
Часть II
Часть III
Часть IV
Часть V

Никогда больше я не слышал таких жарких споров вокруг соглашений о форматировании кода, чем у Java-программистов. Люди с пеной у рта спорят не только о том, стоит ли использовать какие-нибудь префиксы/суффиксы для полей класса, и даже не о том, стоит ли открывающую фигурную скобку переносить на новую строку. Спорят о том, сколько пробелов должно быть в табуляции и на сколько пробелов нужно делать отступ при: a) переносе длинного выражения, b) переносе параметров при вызове метода, c) при декларировании методов с большим количеством параметров и т.д.

Самое смешное, что все эти горячие споры действительно имеют смысл. Поскольку IDE настолько умные, что могут переформатировать код по своему разумению. И если ты в свою IDE загружаешь чужой код и случайно его переформатируешь, то чужой исходник оказывается полностью перекроенным. Что затем скажется на мержинге изменений из разных веток от разных программистов.

Все это, наверное, преследует благую цель – сделать код одного разработчика “родным” по оформлению для всех остальных разработчиков. Но это с одной стороны. А с другой стороны – это пример постепенного превращения программистов в одинаковых и взаимозаменяемых винтиков. Ваша индивидуальность никому не нужна. Если вам удобно писать код как-то так:

class Demo
   {
   public void
   doSomeAction(
         ActionContext ctx,
         ActionParams actionParams,
         Logger logger)
      throws IllegalArgumentException
      {
         WorkingContext workingCtx = makeWorkingContext
               ( ctx.getCurrentUser().getFullContextParams()
               , logger );
         doActionInsideWorkingContext
               ( wokingCtx
               , actionParams );
      }
   }

то это никого не волнует. Не соответствуют ваши предпочтения рекомендованным Sun-ом соглашениям – идете в сад и засуньте свои фантазии сами найдете куда.

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

Так же и в Java – нет у меня права расставлять пробелы и переносы так, как я привык. И это сильно напрягает.

До маразма можно дойти в любом языке и я слышал о C++ных проектах, в которых были просто-напросто драконовские Gode Style Guide – чуть ли не на 250-300 страниц. Но как раз дело в том, что в C/C++ – это эпизодические явления. Тогда как в Java, благодаря как IDE, так и самой ориентации на взаимозаменяемость программистов, ситуация доведена до крайности.

Ну и напоследок о штуке, которая меня всегда в Java раздражала. Это правила документирования параметров метода в Javadoc. В Java все параметры должны быть описаны в комментарии, предшествующем методу:

class Demo
   {
   /**
    * Демонстрационный метод, который типа делает что-то.
    *
    * Данный комментарий должен продемонстрировать правила офомления
    * документации для параметров методов в Javadoc.
    *
    * @param ctx Контекст, на котором воображаемая операция
    *            должна выполняться.
    * @param actionParams Параметры воображаемой операции.
    * @param logger Интерфейс для журнализации выполняемых действий.
    */
   public void
   doSomeAction(
         ActionContext ctx,
         ActionParams actionParams,
         Logger logger)
      throws IllegalArgumentException
      {

Мне не нравится то, что список параметров дублируется – он есть и в Javadoc комментарии, и в декларации метода. Нафига? Мне не понятно.

В свое время, когда я выбирал средство для документирования C++ кода, я специально остановился на Doxygen, поскольку он позволял писать комментарий к параметру метода прямо перед декларацией этого параметра:

class Demo
   {
   /**
    * Демонстрационный метод, который типа делает что-то.
    *
    * Данный комментарий должен продемонстрировать правила офомления
    * документации для параметров методов в Doxygen.
    */
   public void
   doSomeAction(
      /// Контекст, на котором воображаемая операция должна выполняться.
      ActionContext & ctx,
      /// Параметры воображаемой операции. 
      ActionParams & actionParams,
      /// Интерфейс для журнализации выполняемых действий.
      Logger & logger)
      {

Doxygen-овский подход мне нравится тем, что он позволяет набирать текст программы последовательно – комментарий перед методом с общими словами, начало декларации метода, описание первого параметра, первый параметр, описание второго параметра, второй параметр, …, тело метода. В Java эта последовательность нарушается. Нужно либо дублировать список параметров, либо сначала писать декларацию метода (а то и весь метод), а уже потом, с помощью IDE строить описание параметров метода.

Итого. Двойственные впечатления оставляет Java. С одной стороны, очень примитивный и многословный язык, в котором развернуться особо-то и не где. С другой стороны он безопасный, программировать на нем просто, изучать его просто, за время его существования его чуть подрихтовали, сделали помощнее, поприятнее местами. Плюс к нему разработали очень мощные инструменты. Что, в результате, сделало программирование на Java более приятным занятием, чем можно было ожидать.

Так что понятно, почему Java стал мейнстримом. Но лично мне по-прежнему хочется держаться от Java подальше.

11 комментариев:

Alexander P. комментирует...

Ну, ещё не всё так плохо. Вот у некоторых в комментариях сплошной сгенерированный XML http://sharpsnmplib.codeplex.com/SourceControl/changeset/view/44024#753453 :).

Евгений Охотников комментирует...

Да уж, XML в комментариях -- это уже за гранью разумного в моем понимании.

Stan комментирует...

Евгений, слышали же, наверное, такую аббревиатуру ЕСКД? Так в ней не допускается ни какой индивидуальности, а в советское время ещё и уголовная ответственность за подобную индивидуальность была предусмотрена. Но кто из инженеров-конструкторов сокрушался по этому поводу?

Quaker комментирует...

Почему в заголовке 5-ая часть? Это уже 6-ая часть заметок о java...

Евгений Охотников комментирует...

2Stan:

Я сталкивался не с ЕСКД, а с ЕСПД.

Ситуацию я вижу так: в ЕСПД были жесткие требования на оформление готового текста документа. Не было никаких требований к исходнику документа. Например, набирая текст ТЗ в LaTeX, я могу в LaTeX-овском исходнике оформлять текст так, как это мне удобно. И это никого не волнует, поскольку в DVI и PDF, сгенерированных из LaTeX-ового исходника, все правила соблюдены. Аналогичные вещи происходят и в научном мире -- никого не волнует, как оформляется текст диссертации в LaTeX, зато предъявляются строгие требования к результирующим файлам.

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

PS. Кстати, в книге "Оружие победы" часто говорилось, что чертежи из КБ очень сильно преображались еще в отделе технолога, а потом еще и многократно правились на производстве. Так что рабочие пользовались такой документацией, которая никаким ЕСКД не удовлетворяла :)))

Евгений Охотников комментирует...

2Quaker: спасибо, это последствия copy-paste. Исправил.

Stan комментирует...

>>> Сравнивать исходники программы с конструкторской документацией некорректно.

А вот это почему? Производство - это компилятор, хорошо, но что такое исходник. Чем он отличается от чертежей и пояснительной записки, кроме большей формальности?

Евгений Охотников комментирует...

>А вот это почему? Производство - это компилятор, хорошо, но что такое исходник. Чем он отличается от чертежей и пояснительной записки, кроме большей формальности?

Не, здесь нужно крутить в другую сторону. Какую цель преследует ЕСКД? Однозначность чтения описанного на чертеже исполнителем.

Что в программе служит для обеспечения однозначности чтения "исполнителем"-компилятором? Синтаксическая корректность. Всего лишь. Т.е. аналогом требований ЕСКД будет синтаксическая корректность.

AFAIK, в конструкторских бюро нет никаких ограничений на то, как каждый конструктор ведет черновые расчеты и черновые варианты чертежей. А это прямые аналоги исходников программы.

Stan комментирует...

> Не, здесь нужно крутить в другую сторону. Какую цель преследует ЕСКД? Однозначность чтения описанного на чертеже исполнителем.

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

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

Евгений Охотников комментирует...

>Но возращаясь к начальному вопросу, чем же стандартизация представления ущемляет индивидуальность?

Если вы не возражаете, я попробую ответить на ваш вопрос в отдельном посте. Поскольку в комментарий мой ответ может не уместиться.

Stan комментирует...

Мне было бы интересно прочесть ваше развёрнутое мнение.