Назви конвенцій, наприклад, локальні та параметри змінних [закрито]


13

Я обговорював з вищими умовами кодування розробника, щоб застосувати до наших проектів (головним чином, проекти Java / JEE). Я не погодився з однією конвенцією, яку він запропонував:

Імена змінних екземплярів повинні починатися з "_", локальних змінних з "loc", а параметрів методу з "par", так що було б легко визначити походження та область змінної.

Хоча він висував аргументи щодо короткочасної пам’яті та читабельності, я не погодився з тим, що це швидше зменшує читабельність, IDE, як змінні формату Eclipse, по-різному залежно від їх типу, і цю проблему вдасться уникнути при гарному дизайні класу та методу.

Чи є у вас думка, аргументи чи дослідження, які підтримують мою точку зору (чи проти цього)?


Ви кажете, що ви не погоджувалися з "тим фактом, що це швидше зменшує читабельність". Я не кажу, що ви помиляєтесь, але які докази ви надали, щоб підтвердити це твердження? Мені невідомі жодні дослідження, які б сказали, що це зменшить читабельність (я вивчав когнітивні знання в психології аспірантури, перш ніж стати розробником, тому для мене це сфера інтересів.)
AdamJonR

Я мав на увазі це, як це захаращено. Але я не маю жодних доказів, окрім моєї особистої думки
HH

Префікси дублюють інформацію, яка вже міститься в коді і відображається в будь-якому напівпристойному середовищі. І як ми всі знаємо, дублююча інформація може стати непослідовною. DRY має вказувати на те, що ви не використовуєте префікси.
Джулія Хейвард

Відповіді:


15

Як говорить Вікіпедія з цього приводу - Правила називання Java,

Локальні змінні, змінні екземпляри та змінні класу також записуються в нижчуCamelCase. Імена змінних не повинні починатися з символів підкреслення (_) або знака долара ($), навіть якщо дозволено обидва. Деякі умови кодування визначають, що підкреслення слід використовувати для префіксації всіх змінних примірників для поліпшення читання та розуміння програми.

Згідно з моїм досвідом роботи зі стандартами кодування, назви змінних інстанцій, що починаються з "_", не так добре, як кажуть стандарти wikipedia.

локальні змінні з "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;
}
}

Крім того, люди швидко вчаться ігнорувати префікс (або суфікс), щоб побачити змістовну частину імені. Чим більше ми читаємо код, тим менше бачимо префікси. Врешті-решт префікси стають небаченими безладом і маркером старішого коду.


4

Це давнє запитання, але я все одно буду публікувати тут. У мене є 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());
}

Тепер приділіть собі час і подивіться на код (витягнутий з ElasticsearchTemplate з проекту spring-data-elasticsearch - код, який я переглядав, який змусив мене шукати в Google те, що кажуть люди про конвенції про іменування).

  • Що таке коса resultsMapper?
  • Є чи requestBuildingпараметр?
  • тощо ...

Ось моя проста пропозиція щодо того, як слід називати змінні:

  • Статичні атрибути класу (тобто константи): ALL_CAPS_WITH_UNDERSCORES (наприклад HOST_NAME).
  • Атрибути класу (тобто змінні екземпляри класу): camelCase (наприклад resultsMapper).
  • Параметри методу: з префіксом a(наприклад aQuery, aClazz).
  • Локальні змінні: з префіксом my(наприклад myIndexName, myType).

Код вище стає:

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

}

Це ідеально? Я не думаю, що так. Але вищесказане, що стосується змінних, зараз легше читати. Є й інші речі, такі як вирівнювання та пробіли, до яких я не вникатиму у цій відповіді, оскільки це не пов'язане з питанням, що полегшило б також читання.

Вам не подобається Camel Case? Добре, використовуйте підкреслення тощо, але приставте свої локальні змінні та параметри, щоб вони відрізнялися від змінних екземплярів класу.

Вам не подобається aі my- прекрасно, просто залишайтеся послідовними у своєму проекті та використовуйте щось інше ... але використовуйте щось.

Правило №1: послідовність у проекті.

Правило №2: полегшити читання і не вимагати від читача все знати, перш ніж він зможе навчитися.


3

Це багато в чому питання переваги, і як такої немає «правильної» відповіді. Отже, це питання насправді може бути закритим. Але перш ніж це зробити, дозвольте сказати вам, що я повністю з вами згоден. Наскільки я переживаю, префікси зменшують видимість. Не кажучи вже про те, що якщо є якісь префікси, їх слід використовувати для більш корисних речей, як- от оригінальний намір угорської нотації , а не для речей, які ваш IDE так чи інакше може виділити.

Я використовую SentenceCase, наприклад, дані (будь то змінні чи константи) та нижній регістр для параметрів і локальних змінних, оскільки дійсно дуже мало, якщо така є, різниці між ними. Я ніколи ніколи не використовую headlessCamelCase, бо це кульгавий : однокомпонентний ідентифікатор виглядає як малий регістр, навіть якщо він мав бути безголовимCamelCase.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.