16

匿名{ }コード ブロックを使用して、同じメソッド呼び出し内の「コード ブロック」を論理的に区別するオプションを検討しています。これにより、(理論的には) コードの読みやすさが向上するはずです。

次の 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'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;
 }

レビューをありがとう、マキシム。

4

10 に答える 10

55

{ }読みやすさのために同じメソッド内にextra を追加することを検討している場合は、メソッドをいくつかの小さなメソッドにリファクタリングすることを検討することをお勧めします。
これらの小さなメソッドには、それ自体が理解しやすく、再利用しやすいという利点があります (「疎結合」の場合)。単一責任の原則を参照してください。

于 2010-10-25T17:31:58.653 に答える
13

(オプション 2 のように) コードの一部を括弧で囲むと便利な状態になった場合は、独自のメソッドに移動する必要があります。それが可読性を向上させるものです。

ちなみに、コードのすべての行にコメントを付ける必要はないと思います。たとえば、タイムスタンプの更新は、コメントがなくても一目瞭然です。

于 2010-10-25T17:32:49.327 に答える
3

通常、構文上の理由がない限り中括弧で区切られたブロックを追加することはありませんが、変数が限られたスコープ内でのみ必要になる場合は、より大きなスコープの途中で変数を定義するよりも、ネストされたスコープを作成したいと思います (後者の場合、変数がいつ「有用な」スコープから外れるかを明確に示すものはありません)。

このようなコード ブロックを別のメソッドに引き出すことに関しては、結果として得られるメソッドに (1) 適切なパラメーターのバッチがあり、(2) その動作を説明する名前と、実際のコードはそうです。メソッドを使用するために過剰な数のパラメーターを渡す必要がある場合、または呼び出し元が何をしているかを理解するためにメソッド内のコードを調べる必要がある場合は、匿名のスコープ ブロックを使用する方がよいと思います。

于 2010-10-25T18:17:19.027 に答える
1

これは少し主観的で、正しい答えも間違った答えもないと思います...私の意見は、やらないことです。コードのブロックは、前にコメント ブロックを付けて区切り、それらが異なる理由を説明しますが、中かっこは使用しないでください。if中括弧を見ると、先頭に 、 、または何かがあるはずだとすぐに思いますwhile... が見つからないのは少し奇妙です。

于 2010-10-25T17:32:51.697 に答える
1

おそらく、代わりに別の方法を使用する必要があります。最初のブロック processRequest を呼び出すことができます。このコードを読めば、どのパラメータが使用され、どのデータが返され、何をするのか (コメントがなくても) を確認できます。ブロックはそのような情報を提供しません。

バイトコードはおそらく同じです。

于 2010-10-25T17:34:41.217 に答える
0

私は時々 2 番目のオプションを使用することを好みます。これは、個別のメソッドを抽出すると、複数の戻りパラメーターが混乱する (つまり、それらを人工的なオブジェクトにラップする) 場合に発生します。

于 2010-10-25T17:37:03.833 に答える
0

中括弧は通常、制御構造などのステートメントをグループ化するために使用されます。他のものに使用すると耳障りだと思います。

(何らかの理由で) 分割したくない長すぎる関数がある場合は、コメントを付けてブロックに分割します。

于 2010-10-25T21:12:12.100 に答える
0

中括弧{ }には目的があり ( Java 7ではさらに)、読みやすさのためだけに使用されることはめったにないと思います。個人的には選択肢2のように使うとまず「これは静的ブロックなの?」と思います。したがって、オプション 1 は「より正常」で読みやすいと思います。

ここで多くの人が示唆しているように、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 ------------- */

IMHO、コメントはおそらくコードを読みやすくするのに最適です。

于 2010-10-26T10:48:24.820 に答える
0

Lighttpd の構成ファイルには、このスタイルで作成されたコメント ブロックがあります。

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

したがって、コードを {} する代わりにコメントするだけで済みます。

Perl では、{ }、sub { }、または eval { } 内のすべてが評価されます。ただし、一部のサブルーチン内に大量の { } ブロックを保持することは、コードを小さな部分にプッシュするのに十分悪いと見なされます。

$html .= eval { $val = &getNextPiece(); $val を返します。};

したがって、慣習は知られています。

于 2010-10-25T20:59:57.063 に答える
0

C# で開発している場合は、読みやすくするために、代わりに #region ... #endregion を使用することをお勧めします。

于 2010-10-25T17:35:43.737 に答える