C'est une vieille question, mais je vais quand même poster ici. J'ai plus de 20 ans de programmation et de gestion du code d'autres personnes.
Je pense que nommer votre variable avec une brève indication quant à leur portée est vraiment très utile pour la prochaine personne (ou vous-même) qui examinera votre code.
On ne regarde pas déjà le code dans un IDE avec de jolies couleurs (et je ne me souviens pas ce que les couleurs signifient et différents IDE montrent des couleurs différentes, etc.).
Certes, les méthodes doivent être suffisamment courtes pour ne pas être chargées de tonnes de variables et de tonnes de code, mais même sur une courte - lorsque vous regardez du code qui ne vous est pas familier, il est parfois difficile de dire si une variable est une variable de classe, locale variable ou paramètre de méthode.
Pour pouvoir distinguer en un coup d'œil, il est très facile de revoir le code que vous ne connaissez pas.
Prenez cet exemple:
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());
}
Maintenant, chronométrez-vous et regardez le code (extrait d'ElasticsearchTemplate du projet spring-data-elasticsearch - le code que je révisais qui m'a incité à rechercher sur Google ce que les gens disent à propos des conventions de dénomination).
- Quel est le scode de
resultsMapper
?
- Est
requestBuilding
un paramètre?
- etc...
Voici ma simple suggestion sur la façon de nommer les variables:
- Attributs statiques de classe (c'est-à-dire constantes): ALL_CAPS_WITH_UNDERSCORES (par exemple
HOST_NAME
).
- Attributs de classe (ie variables d'instance de classe): camelCase (par exemple
resultsMapper
).
- Paramètres de méthode: préfixé avec
a
(par exemple aQuery
, aClazz
).
- Variables locales: préfixées avec
my
(par exemple myIndexName
, myType
).
Le code ci-dessus devient:
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());
}
C'est parfait? Je ne pense pas. Mais ce qui précède, en ce qui concerne les variables, est maintenant plus facile à lire. Il y a d'autres choses telles que l'alignement et l'espacement, que je n'entrerai pas dans cette réponse car elles ne sont pas liées à la question, ce qui faciliterait également la lecture.
Vous n'aimez pas Camel Case? Bien, utilisez des traits de soulignement, etc., mais préfixez vos variables locales et vos paramètres pour les rendre différents des variables d'instance de classe.
Vous n'aimez pas a
et my
- bien, restez cohérent dans votre projet et utilisez autre chose ... mais utilisez quelque chose.
Règle n ° 1: cohérence au sein du projet.
Règle n ° 2: facilite la lecture et n'exige pas du lecteur qu'il sache tout avant de pouvoir apprendre.