it-swarm-eu.dev

Namenskonventionen, zum Beispiel lokale und Parametervariablen

Ich habe mit einem leitenden Entwickler über Codierungskonventionen gesprochen, die für unsere Projekte gelten sollen (hauptsächlich Java/JEE-Projekte). Ich war mit einer von ihm vorgeschlagenen Konvention nicht einverstanden:

Instanzvariablennamen sollten mit "_", lokale Variablen mit "loc" und Methodenparameter mit "par" beginnen, damit eine Variable leicht identifiziert werden kann. Ursprung und Umfang.

Während er Argumente für das Kurzzeitgedächtnis und die Lesbarkeit vorbrachte, war ich nicht der Meinung, dass dies die Lesbarkeit eher verringert, IDEs wie Eclipse-Formatvariablen je nach Typ unterschiedlich sind und dieses Problem mit einem guten Klassen- und Methodendesign vermieden werden würde.

Haben Sie eine Meinung, Argumente oder Studien, die meinen Standpunkt unterstützen (oder ablehnen)?

13
H-H

Wie Wikipedia zum Thema sagt - Regeln für die Benennung von Java,

Lokale Variablen, Instanzvariablen und Klassenvariablen werden ebenfalls in lowerCamelCase geschrieben. Variablennamen sollten nicht mit Unterstrichen (_) oder Dollarzeichen ($) beginnen, obwohl beide zulässig sind. Bestimmte Codierungskonventionen legen fest, dass Unterstriche verwendet werden sollten, um allen Instanzvariablen ein Präfix zu geben, um das Lesen und das Programmverständnis zu verbessern.

Nach meiner Erfahrung mit Codierungsstandards sind Instanzvariablennamen, die mit "_" beginnen, nicht sehr gut, wie Wikipedia-Standards sagen.

lokale Variablen mit "loc" und Methodenparameter mit "par", wie Sie sagten, wäre es einfach, eine Variable zu identifizieren. Ursprung und Umfang, aber es sollte für Sie sein, nicht für die anderen Programmierer, die Ihren Code eines Tages zur Wartung durchgehen könnten .

Gemäß der Clean Code -Spezifikation für die Methoden sollten diese so kurz wie möglich sein, um die Lesbarkeit zu gewährleisten, und Variablennamen sollten nicht berücksichtigt werden. Sie sollten für Ihre Operation relevant sein, die Ihre Methode ausführt.

Mitglieds-/Bereichspräfixe, Sie müssen Mitgliedsvariablen auch nicht mehr m_ voranstellen. Ihre Klassen und Funktionen sollten so klein sein, dass Sie sie nicht benötigen. Außerdem sollten Sie eine Bearbeitungsumgebung verwenden, in der Elemente hervorgehoben oder eingefärbt werden, um sie voneinander zu unterscheiden.

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;
}
}

Außerdem lernen die Leute schnell, das Präfix (oder Suffix) zu ignorieren, um den aussagekräftigen Teil des Namens zu sehen. Je mehr wir den Code lesen, desto weniger sehen wir die Präfixe. Schließlich werden die Präfixe unsichtbar und ein Marker für älteren Code.

15
Niranjan Singh

Dies ist eine alte Frage, aber ich werde sie trotzdem hier posten. Ich habe mehr als 20 Jahre Erfahrung im Programmieren und im Umgang mit dem Code anderer Leute.

Ich denke, dass die Benennung Ihrer Variablen mit einem kurzen Hinweis auf ihren Umfang für die nächste Person (oder Sie selbst), die sich Ihren Code ansieht, wirklich sehr nützlich ist.

Man sieht sich Code in einem IDE mit hübschen Farben noch nicht an (und ich kann mich nicht erinnern, was die Farben bedeuten und verschiedene IDE verschiedene Farben usw. zeigen).

Richtig, Methoden sollten kurz genug sein, damit sie nicht mit Tonnen von Variablen und Tonnen von Code geladen werden, sondern auch mit kurzen - wenn Sie sich Code ansehen, der völlig unbekannt ist, ist es manchmal schwierig zu sagen, ob eine Variable eine Klassenvariable ist, lokal Variablen- oder Methodenparameter.

Um auf einen Blick unterscheiden zu können, ist es sehr einfach, den Code zu überprüfen, mit dem Sie nicht vertraut sind.

Nehmen Sie dieses Beispiel:

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());
}

Nehmen Sie sich jetzt Zeit und sehen Sie sich den Code an (extrahiert aus ElasticsearchTemplate aus dem Projekt spring-data-elasticsearch - der Code, den ich überprüft habe und der mich dazu veranlasste, bei Google nach den Aussagen der Leute zu Namenskonventionen zu suchen).

  • Was ist der Scode von resultsMapper?
  • Ist requestBuilding ein Parameter?
  • usw...

Hier ist mein einfacher Vorschlag, wie Variablen benannt werden sollen:

  • Statische Klassenattribute (d. H. Konstanten): ALL_CAPS_WITH_UNDERSCORES (z. B. Host_NAME).
  • Klassenattribute (d. H. Klasseninstanzvariablen): camelCase (z. B. resultsMapper).
  • Methodenparameter: mit dem Präfix a (z. B. aQuery, aClazz).
  • Lokale Variablen: mit dem Präfix my (z. B. myIndexName, myType).

Der obige Code lautet:

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());

}}

Ist das perfekt Das glaube ich nicht. Was die Variablen betrifft, ist das jetzt einfacher zu lesen. Es gibt andere Dinge wie Ausrichtung und Abstand, auf die ich in dieser Antwort nicht eingehen werde, da sie nicht mit der Frage zusammenhängen, was das Lesen ebenfalls erleichtern würde.

Sie mögen Camel Case nicht? Gut, verwenden Sie Unterstriche usw., aber stellen Sie Ihre lokalen Variablen und Ihre Parameter voran, um sie von Klasseninstanzvariablen zu unterscheiden.

Sie mögen a und my nicht - gut, bleiben Sie einfach in Ihrem Projekt konsistent und verwenden Sie etwas anderes ... aber verwenden Sie etwas.

Regel 1 : Konsistenz innerhalb des Projekts.

Regel 2 : Erleichtern Sie das Lesen und verlangen Sie nicht, dass der Leser alles weiß, bevor er lernen kann.

4
ETL

Dies ist größtenteils eine Frage der Präferenz, und als solche gibt es keine "richtige" Antwort. Diese Frage könnte also tatsächlich geschlossen sein. Aber bevor es soweit ist, möchte ich Ihnen sagen, dass ich Ihnen vollkommen zustimme. Präfixe verringern für mich die Sichtbarkeit. Ganz zu schweigen von der Tatsache, dass Präfixe, wenn sie vorhanden sein sollen, für nützlichere Dinge wie die ursprüngliche Absicht der ungarischen Notation und nicht für Dinge verwendet werden sollten, die Ihre IDE kann ohnehin Hervorhebungen liefern.

Ich verwende SentenceCase zum Beispiel für Daten (ob Variablen oder Konstanten) und Kleinbuchstaben für Parameter und lokale Variablen, da zwischen beiden wirklich nur ein sehr geringer Unterschied besteht. Ich verwende headlessCamelCase niemals, weil es lahm ist : Ein Einzelkomponenten-Bezeichner sieht aus wie Kleinbuchstaben, selbst wenn er headlessCamelCase sein sollte.

3
Mike Nakis