web-dev-qa-db-ja.com

インスタンス、ローカル、パラメーター変数の命名規則

私は私たちのプロジェクト(主にJava/JEEプロジェクト)に適用するために上級開発者コーディング規約と話し合っていました。私は彼が提案した1つの条約に同意しませんでした:

インスタンス変数名は「_」で始まり、ローカル変数は「loc」で、メソッドパラメーターは「par」で始まる必要があるため、変数のOriginとスコープを簡単に識別できます。

彼は短期記憶と読みやすさについての議論を提唱しましたが、読みやすさがかなり低下するという事実には同意しませんでした。EclipseのようなIDEは、型によって変数の形式が異なり、この問題は適切なクラスとメソッドの設計で回避されます。

私の主張を支持する(またはそれに反対する)意見、議論、研究はありますか?

13
H-H

Wikipedia がこの件について述べているように-Javaの命名規則

ローカル変数、インスタンス変数、クラス変数もlowerCamelCaseで記述されます。変数名は、アンダースコア(_)またはドル記号($)文字で始めることはできませんが、両方を使用できます。特定のコーディング規約では、読み取りとプログラムの理解を向上させるために、すべてのインスタンス変数の前にアンダースコアを使用する必要があると規定されています。

コーディング標準に関する私の経験によれば、インスタンス変数名は "_"で始まりますが、ウィキペディア標準ではそうは言えません。

変数Originとスコープを特定するのは簡単だと言ったように、 "loc"を含むローカル変数と "par"を含むメソッドパラメーターですが、いつかメンテナンスのためにコードを調べる他のプログラマーではなく、 。

メソッドについての クリーンコード 仕様に従って、これらは読みやすくするためにできる限り短くする必要があり、変数名はマップされるべきではなく、メソッドが実行する操作に関連している必要があります。

メンバー/スコープのプレフィックス。メンバー変数の前にm_を付ける必要もなくなりました。クラスと関数は、必要のない程度に小さくする必要があります。また、メンバーをハイライトまたは色分けして区別できるようにする編集環境を使用する必要があります。

public class Part {
private String m_dsc; // The textual description
void setName(String name) {
m_dsc = name;
}
}

public class Part {
String description;
void setDescription(String description) {
this.description = description;
}
}

その上、人々はすぐに名前の意味のある部分を見るためにプレフィックス(またはサフィックス)を無視することを学びます。コードを読むほど、プレフィックスが見えなくなります。結局、接頭辞は見えない混乱と古いコードのマーカーになります。

15
Niranjan Singh

これは古い質問ですが、とにかくここに投稿します。私は20年以上のプログラミングと他の人のコードの処理に携わっています。

変数のスコープを短くして名前を付けると、コードを見る次の人(または自分自身)にとって本当に便利だと思います。

IDEきれいな色でコードを見ていない(そして、色が何を意味しているのか思い出せず、IDE異なる色を表示している、など) )。

確かに、メソッドは十分に短いはずなので、大量の変数や大量のコードがロードされていませんが、短いものでもロードされます-まったくなじみのないコードを見ると、変数がローカルなクラス変数であるかどうかを判断するのが難しい場合があります変数またはメソッドのパラメーター。

一目で区別できるようにすると、慣れていないコードを簡単に確認できます。

この例を見てみましょう:

public <T> Page<T> moreLikeThis(MoreLikeThisQuery query, Class<T> clazz) {
    int startRecord = 0;
    ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(clazz);
    String indexName = isNotBlank(query.getIndexName()) ? query.getIndexName() : persistentEntity.getIndexName();
    String type = isNotBlank(query.getType()) ? query.getType() : persistentEntity.getIndexType();

    Assert.notNull(indexName, "No 'indexName' defined for MoreLikeThisQuery");
    Assert.notNull(type, "No 'type' defined for MoreLikeThisQuery");
    Assert.notNull(query.getId(), "No document id defined for MoreLikeThisQuery");

    MoreLikeThisRequestBuilder requestBuilder = client.prepareMoreLikeThis(indexName, type, query.getId());

    if (query.getPageable() != null) {
        startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize();
        requestBuilder.setSearchSize(query.getPageable().getPageSize());
    }
    requestBuilder.setSearchFrom(startRecord);

    if (isNotEmpty(query.getSearchIndices())) {
        requestBuilder.setSearchIndices(toArray(query.getSearchIndices()));
    }
    if (isNotEmpty(query.getSearchTypes())) {
        requestBuilder.setSearchTypes(toArray(query.getSearchTypes()));
    }
    if (isNotEmpty(query.getFields())) {
        requestBuilder.setField(toArray(query.getFields()));
    }
    if (isNotBlank(query.getRouting())) {
        requestBuilder.setRouting(query.getRouting());
    }
    if (query.getPercentTermsToMatch() != null) {
        requestBuilder.setPercentTermsToMatch(query.getPercentTermsToMatch());
    }
    if (query.getMinTermFreq() != null) {
        requestBuilder.setMinTermFreq(query.getMinTermFreq());
    }
    if (query.getMaxQueryTerms() != null) {
        requestBuilder.maxQueryTerms(query.getMaxQueryTerms());
    }
    if (isNotEmpty(query.getStopWords())) {
        requestBuilder.setStopWords(toArray(query.getStopWords()));
    }
    if (query.getMinDocFreq() != null) {
        requestBuilder.setMinDocFreq(query.getMinDocFreq());
    }
    if (query.getMaxDocFreq() != null) {
        requestBuilder.setMaxDocFreq(query.getMaxDocFreq());
    }
    if (query.getMinWordLen() != null) {
        requestBuilder.setMinWordLen(query.getMinWordLen());
    }
    if (query.getMaxWordLen() != null) {
        requestBuilder.setMaxWordLen(query.getMaxWordLen());
    }
    if (query.getBoostTerms() != null) {
        requestBuilder.setBoostTerms(query.getBoostTerms());
    }

    SearchResponse response = requestBuilder.execute().actionGet();
    return resultsMapper.mapResults(response, clazz, query.getPageable());
}

さあ、時間をかけてコードを見てください(spring-data-elasticsearchプロジェクトのElasticsearchTemplateから抽出-私がレビューしていたコードにより、Googleで名前付け規則についての人々の発言を検索するように促されました)。

  • resultsMapperのコードは何ですか?
  • requestBuildingはパラメーターですか?
  • 等...

変数の命名方法に関する簡単な提案を次に示します。

  • クラス静的属性(つまり、定数):ALL_CAPS_WITH_UNDERSCORES(たとえば、Host_NAME)。
  • クラス属性(つまり、クラスインスタンス変数):camelCase(たとえば、resultsMapper)。
  • メソッドパラメータ:接頭辞a(例:aQueryaClazz)。
  • ローカル変数:プレフィックスmy(例:myIndexNamemyType)。

上記のコードは次のようになります。

public <T> Page<T> moreLikeThis(MoreLikeThisQuery aQuery, Class<T> aClazz) {
  int myStartRecord = 0;
  ElasticsearchPersistentEntity myPersistentEntity = getPersistentEntityFor(aClazz);
  String myIndexName = isNotBlank(aQuery.getIndexName()) ? aQuery.getIndexName() : myPersistentEntity.getIndexName();
  String myType = isNotBlank(aQuery.getType()) ? aQuery.getType() : myPersistentEntity.getIndexType();

  Assert.notNull(myIndexName, "No 'indexName' defined for MoreLikeThisQuery");
  Assert.notNull(myType, "No 'type' defined for MoreLikeThisQuery");
  Assert.notNull(aQuery.getId(), "No document id defined for MoreLikeThisQuery");

  MoreLikeThisRequestBuilder myRequestBuilder = client.prepareMoreLikeThis(myIndexName, myType, aQuery.getId());

  if (aQuery.getPageable() != null) {
     myStartRecord = aQuery.getPageable().getPageNumber() * aQuery.getPageable().getPageSize();
     myRequestBuilder.setSearchSize(aQuery.getPageable().getPageSize());
  }
  myRequestBuilder.setSearchFrom(myStartRecord);

  if (isNotEmpty(aQuery.getSearchIndices())) {
     myRequestBuilder.setSearchIndices(toArray(aQuery.getSearchIndices()));
  }
  if (isNotEmpty(aQuery.getSearchTypes())) {
     myRequestBuilder.setSearchTypes(toArray(aQuery.getSearchTypes()));
  }
  if (isNotEmpty(aQuery.getFields())) {
     myRequestBuilder.setField(toArray(aQuery.getFields()));
  }
  if (isNotBlank(aQuery.getRouting())) {
     myRequestBuilder.setRouting(aQuery.getRouting());
  }
  if (aQuery.getPercentTermsToMatch() != null) {
     myRequestBuilder.setPercentTermsToMatch(aQuery.getPercentTermsToMatch());
  }
  if (aQuery.getMinTermFreq() != null) {
     myRequestBuilder.setMinTermFreq(aQuery.getMinTermFreq());
  }
  if (aQuery.getMaxQueryTerms() != null) {
     myRequestBuilder.maxQueryTerms(aQuery.getMaxQueryTerms());
  }
  if (isNotEmpty(aQuery.getStopWords())) {
     myRequestBuilder.setStopWords(toArray(aQuery.getStopWords()));
  }
  if (aQuery.getMinDocFreq() != null) {
     myRequestBuilder.setMinDocFreq(aQuery.getMinDocFreq());
  }
  if (aQuery.getMaxDocFreq() != null) {
     myRequestBuilder.setMaxDocFreq(aQuery.getMaxDocFreq());
  }
  if (aQuery.getMinWordLen() != null) {
     myRequestBuilder.setMinWordLen(aQuery.getMinWordLen());
  }
  if (aQuery.getMaxWordLen() != null) {
     myRequestBuilder.setMaxWordLen(aQuery.getMaxWordLen());
  }
  if (aQuery.getBoostTerms() != null) {
     myRequestBuilder.setBoostTerms(aQuery.getBoostTerms());
  }

  SearchResponse myResponse = myRequestBuilder.execute().actionGet();
  return resultsMapper.mapResults(myResponse, aClazz, aQuery.getPageable());

}

それは完璧ですか?私はそうは思いません。しかし、変数に関する限り、上記は読みやすくなりました。配置や間隔などの他にもありますが、質問とは関係がないので、この答えには触れません。読みやすくするためです。

あなたはキャメルケースが好きではありませんか?下線などを使用しますが、ローカル変数とパラメーターの前にプレフィックスを付けて、クラスインスタンス変数と異なるようにします。

amyは好きではありません。プロジェクト内で一貫性を保ち、他のものを使用するだけです。しかし、何かを使用してください。

ルール#1:プロジェクト内の一貫性。

ルール#2:読みやすくし、読者が学習する前にすべてを知っている必要はありません。

4
ETL

これは主に好みの問題であり、「正しい」答えはありません。したがって、この質問は実際には終了している可能性があります。しかし、その前に、私はあなたに完全に同意することをお話ししましょう。プレフィックスは、私に関する限り、可視性を低下させます。接頭辞が必要な場合は ハンガリー語表記の元々の意図 のようなより有用なものに使用すべきであり、IDEはとにかく強調表示を提供できます。

インスタンスデータ(変数か定数か)にはSentenceCaseを使用し、パラメーターとローカル変数にはlower_caseを使用します。これは、2つの値の差があったとしてもごくわずかであるためです。 それが不完全であるので、headlessCamelCaseを使用することは決してありません:headlessCamelCaseであることが意図されていたとしても、単一コンポーネントの識別子は小文字のように見えます。

3
Mike Nakis