Convenzioni di denominazione per esempio, variabili locali e parametri [chiusa]

12

Stavo discutendo con le convenzioni di codifica degli sviluppatori senior da applicare ai nostri progetti (principalmente progetti Java / JEE). Sono stato in disaccordo con una convenzione che ha proposto:

Instance variable names should start with "_", local variables with "loc", and method parameters with "par", so it would be easy to identify a variable origin and scope.

Mentre proponeva argomenti per la memoria e la leggibilità a breve termine, non ero d'accordo sul fatto che diminuisse la leggibilità, IDE come le variabili di formato Eclipse in modo diverso a seconda del loro tipo e questo problema sarebbe evitato con una buona classe e metodo design.

Hai qualche opinione, argomento o studio che supporta il mio punto (o lo oppone)?

    
posta H-H 02.01.2012 - 08:41
fonte

3 risposte

15

Come dice Wikipedia sull'argomento - Regole per la denominazione di java,

Local variables, instance variables, and class variables are also written in lowerCamelCase. Variable names should not start with underscore (_) or dollar sign ($) characters, even though both are allowed. Certain coding conventions state that underscores should be used to prefix all instance variables, for improved reading and program understanding.

Secondo la mia esperienza con gli standard di codifica, i nomi delle variabili di istanza iniziano con "_" non è molto buono come dicono gli standard di Wikipedia.

variabili locali con "loc" e parametri del metodo con "par", come hai detto sarebbe facile identificare un'origine e un ambito variabili, ma dovrebbe essere per te, non per gli altri programmatori che potrebbero passare attraverso il tuo codice per manutenzione un giorno.

In base alla descrizione del codice di pulizia sui metodi che dovrebbero essere brevi quanto possono fare per la leggibilità e i nomi delle variabili non dovrebbero essere mappati mentalmente, dovrebbero essere pertinenti alle tue operazioni eseguite dal tuo metodo.

Prefissi membro / ambito, Inoltre non è necessario prefisso le variabili membro con m_ più. Le tue classi e funzioni dovrebbe essere abbastanza piccolo da non averne bisogno. E dovresti usare un montaggio ambiente che evidenzia o colorizza i membri per renderli distinti.

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

Inoltre, le persone imparano rapidamente a ignorare il prefisso (o suffisso) per vedere il significato parte del nome. Più leggiamo il codice, meno vediamo i prefissi. Alla fine il i prefissi diventano una confusione invisibile e un indicatore di codice precedente.

    
risposta data 02.01.2012 - 09:38
fonte
3

Questo è in gran parte una questione di preferenza, e come tale non esiste una risposta 'corretta'. Quindi, questa domanda potrebbe davvero essere chiusa. Ma prima che lo faccia, lascia che ti dica che sono completamente d'accordo con te. I prefissi riducono la visibilità per quanto mi riguarda. Per non parlare del fatto che se ci devono essere dei prefissi, dovrebbero essere usati per cose più utili, come l'intenzione originale del Notazione ungherese , e non per le cose che il tuo IDE può comunque fornire per evidenziare.

Uso SentenceCase per dati di esempio (variabili o costanti) e lower_case per parametri e variabili locali, poiché c'è davvero poca o nessuna differenza tra i due. Non uso mai, mai e poi mai, headcapCamelCase perché è lame : un identificatore di un singolo componente ha l'aspetto di un carattere minuscolo, anche se era destinato a essere senza testaCamelCase.

    
risposta data 02.01.2012 - 10:22
fonte
3

Questa è una vecchia domanda, ma inserirò comunque qui. Ho circa 20 anni di programmazione e gestione del codice di altre persone.

Penso che nominare la tua variabile con una breve indicazione del loro ambito sia davvero molto utile per la prossima persona (o te stesso) che guarderà il tuo codice.

Uno non guarda già il codice in un IDE con dei bei colori (e non riesco a ricordare cosa significano i colori e IDE diversi mostrano colori diversi, ecc.)

È vero, i metodi dovrebbero essere abbastanza brevi da non essere caricati con tonnellate di variabili e tonnellate di codice, ma anche su uno corto - quando si guarda un codice che non è affatto familiare, a volte è difficile dire se una variabile è una classe variabile, variabile locale o parametro del metodo.

Essere in grado di distinguere a colpo d'occhio rende molto facile rivedere il codice che non conosci.

Prendi questo esempio:

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

Ora, pensa a te stesso e guarda il codice (estratto da ElasticsearchTemplate dal progetto spring-data-elasticsearch - il codice che stavo esaminando e che mi ha spinto a cercare su Google ciò che la gente dice sulle convenzioni di denominazione).

  • Qual è lo scode di resultsMapper ?
  • È requestBuilding un parametro?
  • ecc ...

Ecco il mio semplice suggerimento su come le variabili dovrebbero essere denominate:

  • Attributi statici di classe (cioè costanti): ALL_CAPS_WITH_UNDERSCORES (ad esempio HOST_NAME ).
  • Attributi di classe (vale a dire variabili di istanza di classe): camelCase (ad esempio resultsMapper ).
  • Parametri del metodo: prefissati con a (ad esempio aQuery , aClazz ).
  • Variabili locali: prefissate con my (ad esempio myIndexName , myType ).

Il codice sopra diventa:

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

}

È perfetto? Io non la penso così Ma quanto sopra, per quanto riguarda le variabili, è ora più facile da leggere. Ci sono altre cose come l'allineamento e la spaziatura, che non entrerò in questa risposta in quanto non è correlata alla domanda, che renderebbe anche più facile la lettura.

Non ti piace il caso Camel? Bene, usa caratteri di sottolineatura, ecc., Ma anteponi le variabili locali e i tuoi parametri per renderli diversi rispetto alle variabili di istanza di classe.

Non ti piace a e my - bene, resta coerente nel tuo progetto e usa qualcos'altro ... ma usa qualcosa.

Regola 1: consistenza all'interno del progetto.

La regola n. 2: rende facile la lettura e non richiede che il lettore sappia tutto prima che possa imparare.

    
risposta data 30.11.2014 - 02:27
fonte

Leggi altre domande sui tag