Использование {} для сегментации больших блоков кода для улучшения чтения кода - Хорошая практика?
Я рассматриваю возможность использования анонимных кодовых блоков {}, чтобы логически различать "кодовые блоки" внутри одного и того же вызова метода, что (теоретически) должно улучшить читаемость кода.
Мне интересно, какой из следующих 2 сегментов кода лучше для ваших глаз?
Кроме того, 2 сегмента кода компилируются в один и тот же байт-код? Другими словами, можно использовать {}, чтобы каким-либо образом повлиять на производительность кода?
Вариант 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 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 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;
}
Спасибо за обзор, Максим.
Ответы
Ответ 1
Если вы изучаете добавление дополнительного { }
в рамках одного и того же метода только для удобства чтения, мой совет будет состоять в том, чтобы рассмотреть возможность рефакторинга вашего метода на несколько более мелких методов.
Эти более мелкие методы имеют то преимущество, легче понять сами по себе и быть более многоразовыми (если они" слабо связаны "). См. Принцип принцип единой ответственности.
Ответ 2
Если вы дойдете до состояния, что было бы удобно помещать скобки вокруг некоторой части кода (как в Варианте 2), вы должны перенести его на свой собственный метод. Это улучшает читаемость.
Кстати, я также думаю, что вам не нужно прокомментировать каждую строку вашего кода. Например, обновление timestamp самоочевидно даже без комментариев.
Ответ 3
Обычно я не добавляю блок с разделителями без какой-либо синтаксической причины, но если переменная нужна только в ограниченной области, я бы предпочел создать вложенную область, кроме определения переменной в середине большего один (поскольку в последнем случае нет четкого указания, когда переменная выходит из "полезной" области).
Что касается вытаскивания такого кодового блока в другой метод, я думаю, что неплохо, если полученный метод (1) имеет разумную партию параметров, а (2) может быть дано имя, которое описывает его поведение как как и действительный код. Если использование метода потребует передачи чрезмерного количества параметров, или если вам нужно будет посмотреть на код в методе, чтобы понять, что делает его вызывающий, то я думаю, что лучше использовать анонимный блок видимости.
Ответ 4
Я думаю, что это немного субъективно, нет правильного или неправильного ответа... мое мнение не делает этого. Отдельные блоки кода с блоками комментариев, которые предшествуют и объясняют, почему они отличаются, но не используют фигурные скобки. Когда я вижу фигурные скобки, я сразу думаю, что должен быть ведущий if
, while
или что-то... и не найти это немного странно.
Ответ 5
Вместо этого вам следует использовать отдельные методы. Вы можете вызвать первый блок processRequest. Любой, кто читает этот код, сможет увидеть, какие параметры используются, какие данные возвращены, что он делает (даже без комментариев). Блоки не предоставляют такую информацию.
Bytecode, вероятно, будет таким же.
Ответ 6
Если вы разрабатываете С#, я бы посоветовал вам использовать #region... #endregion вместо этого для удобства чтения.
Ответ 7
I иногда предпочитают использовать второй вариант. Это происходит, когда извлечение отдельных методов приведет к беспорядку с несколькими параметрами возврата (т.е. Обертыванием их в искусственный объект).
Ответ 8
Lighttpd имеет блоки комментариев в файле конфигурации, выполненные в этом стиле;
#{{{ module name
module.option = value;
module.option = value;
#}}}
Таким образом, вы можете просто комментировать, а не {} использовать свой код.
В Perl будут оцениваться все внутри {}, sub {} или eval {}; однако, хранение большого количества {} блоков внутри некоторой подпрограммы считается достаточно плохим, чтобы вывести код из более мелких частей;
$html. = eval {$ val = & Амп; getNextPiece(); return $val; };
Итак, практика известна.
Ответ 9
Скобки обычно используются для группировки операторов для структур управления и т.п. Я нахожу их раздражающими, когда они используются для чего-то еще.
Если у меня есть функция перекрытия, которая (по какой-либо причине), я не хочу делиться, я разбиваю ее на блоки с комментариями.
Ответ 10
Скобки { }
имеют свою цель (еще больше в 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 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 ------------- */
IMHO, комментарии, вероятно, лучше всего подходят для считывания кодов.