Konvensi penamaan misalnya, variabel lokal dan parameter [ditutup]

13

Saya sedang berdiskusi dengan konvensi pengembang kode senior untuk diterapkan pada proyek kami (terutama proyek Java / JEE). Saya tidak setuju dengan satu konvensi yang ia usulkan:

Nama variabel instan harus dimulai dengan "_", variabel lokal dengan "loc", dan parameter metode dengan "par", sehingga akan mudah untuk mengidentifikasi asal variabel dan ruang lingkup.

Sementara ia mengajukan argumen untuk memori jangka pendek dan keterbacaan, saya tidak setuju pada kenyataan bahwa itu agak mengurangi keterbacaan, IDE seperti Eclipse memformat variabel secara berbeda tergantung pada jenisnya, dan masalah ini akan dihindari dengan kelas yang bagus dan desain metode.

Apakah Anda memiliki pendapat, argumen, atau studi yang mendukung pendapat saya (atau menentangnya)?

HH
sumber
Anda mengatakan bahwa Anda tidak setuju pada "fakta bahwa itu agak mengurangi keterbacaan." Saya tidak mengatakan Anda salah, tetapi bukti apa yang Anda berikan untuk mendukung klaim itu? Saya tidak mengetahui adanya penelitian yang mengatakan itu akan mengurangi keterbacaan (saya belajar kognitif di psikologi sekolah pascasarjana sebelum menjadi pengembang, jadi ini adalah bidang yang menarik bagi saya.)
AdamJonR
Saya maksudkan karena berantakan. Tapi saya tidak punya bukti selain pendapat pribadi saya
HH
Awalan duplikat informasi yang sudah terkandung dalam kode dan ditampilkan dalam lingkungan setengah layak. Dan seperti yang kita semua tahu, informasi rangkap dapat menjadi tidak konsisten. KERING seharusnya mengarahkan Anda ke arah tidak menggunakan awalan.
Julia Hayward

Jawaban:

15

Seperti Wikipedia mengatakan tentang masalah ini - Aturan untuk penamaan java,

Variabel lokal, variabel instan, dan variabel kelas juga ditulis dalam lowerCamelCase. Nama variabel tidak boleh dimulai dengan karakter garis bawah (_) atau tanda dolar ($), meskipun keduanya diizinkan. Konvensi pengkodean tertentu menyatakan bahwa garis bawah harus digunakan untuk awalan semua variabel instan, untuk meningkatkan kemampuan membaca dan pemahaman program.

Menurut pengalaman saya dengan standar pengkodean, nama variabel Instance mulai dengan "_" tidak sebagus yang dikatakan standar wikipedia.

variabel lokal dengan "loc", dan parameter metode dengan "par", seperti yang Anda katakan akan mudah untuk mengidentifikasi asal variabel dan ruang lingkup, tetapi harus untuk Anda, bukan programmer lain yang mungkin pergi melalui kode Anda untuk pemeliharaan suatu hari nanti .

Sesuai spesifikasi Kode Bersih tentang metode ini harus pendek sebanyak yang dapat Anda lakukan untuk keterbacaan dan nama variabel tidak boleh dipetakan dengan pikiran, mereka harus relevan dengan operasi Anda yang dilakukan metode Anda.

Awalan Anggota / Lingkup, Anda juga tidak perlu awalan variabel anggota dengan m_ lagi. Kelas dan fungsi Anda harus cukup kecil sehingga Anda tidak membutuhkannya. Dan Anda harus menggunakan lingkungan pengeditan yang menyoroti atau mewarnai anggota untuk membuatnya berbeda.

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

Selain itu, orang dengan cepat belajar untuk mengabaikan awalan (atau akhiran) untuk melihat bagian bermakna dari nama tersebut. Semakin banyak kita membaca kode, semakin sedikit kita melihat awalan. Akhirnya awalan menjadi berantakan dan menjadi penanda kode lama.

Niranjan Singh
sumber
4

Ini adalah pertanyaan lama, tetapi saya akan tetap memposting di sini. Saya memiliki lebih dari 20 tahun pemrograman dan berurusan dengan kode orang lain.

Saya pikir penamaan variabel Anda dengan indikasi singkat untuk ruang lingkup mereka benar-benar berguna untuk orang berikutnya (atau diri Anda sendiri) yang akan melihat kode Anda.

Seseorang belum melihat kode dalam IDE dengan warna cantik (dan saya tidak ingat apa arti warna dan IDE berbeda menunjukkan warna berbeda, dll).

Benar, metode harus cukup pendek sehingga tidak dimuat dengan banyak variabel dan banyak kode, tetapi bahkan pada pendek - ketika Anda melihat kode yang sama sekali tidak dikenal, kadang-kadang sulit untuk mengetahui apakah suatu variabel adalah variabel kelas, lokal variabel atau parameter metode.

Untuk dapat membedakan secara sekilas membuatnya sangat mudah untuk meninjau kode yang tidak Anda kenal.

Ambil contoh ini:

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

Sekarang, tentukan waktu Anda sendiri dan lihat kodenya (diekstrak dari ElasticsearchTemplate dari proyek spring-data-elasticsearch - kode yang saya ulas yang mendorong saya untuk mencari di Google apa yang orang katakan tentang konvensi penamaan)

  • Apa skode dari resultsMapper?
  • Apakah requestBuildingparameter?
  • dll ...

Berikut adalah saran sederhana saya tentang bagaimana variabel harus dinamai:

  • Atribut statis kelas (yaitu konstanta): ALL_CAPS_WITH_UNDERSCORES (misalnya HOST_NAME).
  • Atribut kelas (yaitu variabel instance kelas): camelCase (misalnya resultsMapper).
  • Parameter metode: diawali dengan a(misalnya aQuery, aClazz).
  • Variabel lokal: diawali dengan my(misalnya myIndexName, myType).

Kode di atas menjadi:

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

}

Apakah itu sempurna? Saya kira tidak. Tetapi hal di atas, sejauh menyangkut variabel, sekarang lebih mudah dibaca. Ada hal-hal lain seperti penjajaran dan spasi, yang tidak akan saya bahas dalam jawaban ini karena tidak terkait dengan pertanyaan, yang akan membuatnya lebih mudah dibaca juga.

Anda tidak suka Unta? Baik, gunakan garis bawah, dll, tetapi awali variabel lokal Anda dan parameter Anda untuk membuatnya berbeda dari variabel instance kelas.

Anda tidak suka adan my- baiklah, tetap konsisten dalam proyek Anda dan gunakan sesuatu yang lain ... tetapi gunakan sesuatu.

Aturan # 1: konsistensi dalam proyek.

Aturan # 2: membuatnya mudah dibaca dan tidak mengharuskan pembaca untuk mengetahui segalanya sebelum dia bisa belajar.

ETL
sumber
3

Ini sebagian besar adalah masalah preferensi, dan karena itu tidak ada jawaban yang 'benar'. Jadi, pertanyaan ini mungkin benar-benar ditutup. Tetapi sebelum itu terjadi, izinkan saya memberi tahu Anda bahwa saya sepenuhnya setuju dengan Anda. Awalan mengurangi visibilitas sejauh yang saya ketahui. Apalagi fakta bahwa jika ada awalan, mereka harus digunakan untuk hal-hal yang lebih berguna, seperti maksud asli Notasi Hongaria , dan bukan untuk hal-hal yang IDE Anda dapat memberikan menyoroti untuk pula.

Saya menggunakan SentenceCase untuk data contoh (apakah variabel atau konstanta) dan lower_case untuk parameter dan variabel lokal, karena sebenarnya sangat sedikit, jika ada, perbedaan antara keduanya. Saya tidak pernah menggunakan headlessCamelCase karena lumpuh : pengenal komponen tunggal terlihat seperti huruf kecil, bahkan jika itu dimaksudkan untuk menjadi headlessCamelCase.

Mike Nakis
sumber