Использование {} для сегментирования больших блоков кода для улучшения читабельности кода - Хорошая практика? - PullRequest
15 голосов
/ 25 октября 2010

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

Мне интересно, какой из следующих двух сегментов кода лучше для вас?

Кроме того, компилируются ли два сегмента кода в один и тот же байт-код? Другими словами, может ли использование {} каким-либо образом повлиять на производительность кода?

Вариант 1: кодовый блок без {} идентификатора

 public static String serviceMatch(HttpServletRequest servletRequest, RequestTypeEnum requestTypeEnum, ...censorsed..., RequestStatistics requestStatistics) {
  Request request;

  // We get the parser that fits the ...censorsed..., effectively transforming the HTTPReqeuest to application local "Request*" object
  RequestParser parser = RequestParserFactory.getParser(...censorsed...);

  // Populate basic parameters, the "heavy" data will be lazy loaded
  request = parser.parse(servletRequest);

  // Instead of polluting the parsers let's put it here... (unless we identify meaningful justifications for the other alternative of changing RequestParser.parse() interface.
  request.requestType = requestTypeEnum;

  // Store the request statistics object on the request, so that we have access to it from all over the code
  request.requestStatistics = requestStatistics;



  // Update timestamp when request was parsed
  request.requestStatistics._1_end_parseRequest = System.currentTimeMillis();


  /*
   * ...censorsed...
   */
  MatchResult matchResult = Matcher.findMatch(...censorsed...);

  /*
   * ...censorsed...
   */
  String reply = ReplyFormatFactory.getFormatter(...censorsed...

  // Update timestamp when reply finished construction
  request.requestStatistics._6_end_formatReply = System.currentTimeMillis();

  return reply;
 }

Вариант 2: блок кода с {} идентификатором

 public static String serviceMatch(HttpServletRequest servletRequest, RequestTypeEnum requestTypeEnum, ...censorsed..., RequestStatistics requestStatistics) {
  Request request;

  /*
   * Request parsing block
   */
  {
   // We get the parser that fits the ...censorsed..., effectively transforming the HTTPReqeuest to application local "Request*" object
   RequestParser parser = RequestParserFactory.getParser(...censorsed...);

   // Populate basic parameters, the "heavy" data will be lazy loaded
   request = parser.parse(servletRequest);

   // Instead of polluting the parsers let's put it here... (unless we identify meaningful justifications for the other alternative of changing RequestParser.parse() interface.
   request.requestType = requestTypeEnum;

       // Store the request statistics object on the request, so that we have access to it from all over the code
   request.requestStatistics = requestStatistics;
  }



  // Update timestamp when request was parsed
  request.requestStatistics._1_end_parseRequest = System.currentTimeMillis();


  /*
   * ...censorsed...
   */
  MatchResult matchResult = Matcher.findMatch(...censorsed...);

  /*
   * ...censorsed...
   */
  String reply = ReplyFormatFactory.getFormatter(...censorsed...

  // Update timestamp when reply finished construction
  request.requestStatistics._6_end_formatReply = System.currentTimeMillis();

  return reply;
 }

Спасибо за обзор, Максим.

Ответы [ 10 ]

55 голосов
/ 25 октября 2010

Если вы хотите добавить дополнительные { } в один и тот же метод только для удобства чтения, я бы посоветовал подумать о реорганизации вашего метода в несколько более мелких методов.Эти меньшие методы имеют то преимущество, что их легче понять самим, и они более пригодны для повторного использования (если они «слабо связаны»).См. принцип единоличной ответственности .

13 голосов
/ 25 октября 2010

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

Кстати, я также думаю, что вам не нужно комментировать каждую строку вашего кода. Например, обновление метки времени не требует пояснений даже без комментария.

3 голосов
/ 25 октября 2010

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

Что касается извлечения такого блока кода в другой метод, я думаю, что будет хорошей идеей, если результирующий метод и (1) имеет разумную партию параметров, и (2) можно дать имя, которое описывает его поведение как хорошо, как фактический код делает. Если использование метода потребует передачи чрезмерного количества параметров, или если нужно будет посмотреть на код в методе, чтобы понять, что делает его вызывающая сторона, то я думаю, что лучше использовать анонимный блок области видимости.

1 голос
/ 25 октября 2010

Возможно, вам следует использовать вместо этого отдельные методы.Вы можете вызвать первый блок processRequest.Любой, кто читает этот код, сможет увидеть, какие параметры используются, какие данные возвращаются, что они делают (даже без комментариев).Блоки не предоставляют такую ​​информацию.

Байт-код, скорее всего, будет таким же.

1 голос
/ 25 октября 2010

Я думаю, что это немного субъективно, нет правильного или неправильного ответа ... мое мнение не делай этого. Разделите блоки кода с блоками комментариев, которые предшествуют, и объясните , почему они разные, но не используйте фигурные скобки. Когда я вижу фигурные скобки, я сразу думаю, что должен быть ведущий if, while или что-то ... и не находить это немного странно.

0 голосов
/ 26 октября 2010

Брекеты { } имеют свое назначение (даже больше в Java 7 ), и я думаю, что они редко используются только для удобства чтения. Лично, если они используются, как в варианте 2, первое, что приходит мне в голову, это: «Это статический блок?». Следовательно, я нахожу Вариант 1 «более нормальным» и читаемым.

Если вы действительно хотите придерживаться одного метода, а не рефакторинга этого куска кода, как предлагают многие здесь, вместо этого используйте комментарии в качестве разделителей строк. Что-то вроде:

    /* -------------------------------------------- */
    /* describe in detail here why you don't want to put this in another method */
    /* so other readers will know why! */

   // We get the parser that fits the ...censorsed..., effectively transforming the HTTPReqeuest to application local "Request*" object
   RequestParser parser = RequestParserFactory.getParser(...censorsed...);

   // Populate basic parameters, the "heavy" data will be lazy loaded
   request = parser.parse(servletRequest);

   // Instead of polluting the parsers let's put it here... (unless we identify meaningful justifications for the other alternative of changing RequestParser.parse() interface.
   request.requestType = requestTypeEnum;

       // Store the request statistics object on the request, so that we have access to it from all over the code
   request.requestStatistics = requestStatistics;
  }
   /* -------- END of confusing block ------------- */

ИМХО, комментарии, вероятно, являются лучшими в создании читабельных кодов.

0 голосов
/ 26 октября 2010

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

Если у меня есть сверхдлинная функция, которую (по любой причине) я не хочу разбивать, я разбиваю ее на блоки с комментариями.

0 голосов
/ 26 октября 2010

Lighttpd имеет блоки комментариев в файле конфигурации, выполненные в этом стиле;

#{{{ module name
module.option = value;
module.option = value;
#}}} 

Так что вы можете просто комментировать вместо {} 'ваш код.

В Perl, все что угодновнутри {} будет вычисляться sub {} или eval {};однако хранение большого количества блоков {} внутри некоторой подпрограммы считается достаточно плохим, чтобы вытолкнуть код небольшими частями;

$ html. = eval {$ val = & getNextPiece ();вернуть $ val;};

Итак, практика известна.

0 голосов
/ 25 октября 2010

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

0 голосов
/ 25 октября 2010

Если вы разрабатываете на C #, я бы посоветовал вам использовать #region ... #endregion вместо этого для удобства чтения.

...