แบบแผนการตั้งชื่อเช่นตัวแปรโลคอลและตัวแปร [ปิด]


13

ฉันกำลังพูดคุยกับอนุสัญญาการเข้ารหัสผู้พัฒนาระดับสูงเพื่อนำไปใช้กับโครงการของเรา (ส่วนใหญ่เป็นโครงการ Java / JEE) ฉันไม่เห็นด้วยกับการประชุมที่เขาเสนอ:

ชื่อตัวแปรอินสแตนซ์ควรเริ่มต้นด้วย "_", ตัวแปรโลคอลด้วย "loc", และพารามิเตอร์เมธอดด้วย "par" ดังนั้นมันจะง่ายต่อการระบุที่มาและขอบเขตของตัวแปร

ในขณะที่เขาหยิบยกข้อโต้แย้งสำหรับหน่วยความจำระยะสั้นและความสามารถในการอ่านฉันไม่เห็นด้วยกับความจริงที่ว่ามันค่อนข้างลดความสามารถในการอ่าน IDEs เช่นตัวแปรรูปแบบ Eclipse แตกต่างกันไปตามประเภทของพวกเขาและปัญหานี้

คุณมีความเห็นข้อโต้แย้งหรือการศึกษาที่สนับสนุนประเด็นของฉัน (หรือคัดค้าน) หรือไม่?


คุณบอกว่าคุณไม่เห็นด้วยกับ "ความจริงที่ว่ามันค่อนข้างลดการอ่าน" ฉันไม่ได้บอกว่าคุณผิด แต่คุณมีหลักฐานอะไรบ้างที่สนับสนุนข้อเรียกร้องนั้น ฉันไม่ได้ตระหนักถึงการวิจัยใด ๆ ที่บอกว่ามันจะลดความสามารถในการอ่านได้ (ฉันศึกษาด้านจิตวิทยาที่บัณฑิตวิทยาลัยก่อนที่จะเป็นนักพัฒนาดังนั้นนี่จึงเป็นเรื่องที่น่าสนใจสำหรับฉัน)
AdamJonR

ฉันหมายถึงมันในขณะที่มันรกรุงรัง แต่ฉันไม่มีหลักฐานอื่นนอกเหนือจากความเห็นส่วนตัวของฉัน
HH

คำนำหน้าข้อมูลที่ซ้ำกันที่มีอยู่แล้วในรหัสและแสดงในสภาพแวดล้อมที่เหมาะสมครึ่งใด ๆ และอย่างที่เรารู้ข้อมูลที่ซ้ำกันอาจไม่สอดคล้องกัน DRY ควรนำคุณไปสู่การไม่ใช้ส่วนนำหน้า
Julia Hayward

คำตอบ:


15

ตามที่Wikipedia ได้กล่าวไว้ในหัวข้อ - กฎสำหรับการตั้งชื่อ java

ตัวแปรโลคัลตัวแปรอินสแตนซ์และตัวแปรคลาสจะถูกเขียนใน lowerCamelCase ชื่อตัวแปรไม่ควรเริ่มต้นด้วยเครื่องหมายขีดล่าง (_) หรือเครื่องหมายดอลลาร์ ($) ถึงแม้ว่าทั้งคู่จะได้รับอนุญาตก็ตาม ข้อตกลงการเข้ารหัสบางอย่างระบุว่าขีดล่างควรใช้เพื่อนำหน้าตัวแปรอินสแตนซ์ทั้งหมดเพื่อปรับปรุงการอ่านและการทำความเข้าใจโปรแกรม

จากประสบการณ์ของฉันกับมาตรฐานการเข้ารหัสชื่อตัวแปรอินสแตนซ์ที่ขึ้นต้นด้วย "_" นั้นไม่ค่อยดีเท่าที่มาตรฐานวิกิพีเดียพูด

ตัวแปรโลคัลที่มี "loc" และพารามิเตอร์เมธอดด้วย "par" อย่างที่คุณบอกว่ามันจะง่ายต่อการระบุที่มาและขอบเขตของตัวแปร แต่มันควรจะเป็นสำหรับคุณไม่ใช่โปรแกรมเมอร์คนอื่น ๆ ที่อาจผ่านโค้ดของคุณเพื่อการบำรุงรักษา .

ตามข้อกำหนดของClean Codeเกี่ยวกับวิธีการเหล่านี้ควรสั้นที่สุดเท่าที่จะทำได้เพื่อให้สามารถอ่านได้และชื่อตัวแปรไม่ควรถูกแมปไว้

คำนำหน้าสมาชิก / ขอบเขตคุณยังไม่จำเป็นต้องเติมตัวแปรสมาชิกด้วย 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 สำหรับสิ่งที่ผู้คนพูดถึงการตั้งชื่อการประชุม)

  • มีอะไร SCODE ของ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 สำหรับข้อมูลอินสแตนซ์ (ไม่ว่าจะเป็นตัวแปรหรือค่าคงที่) และ lower_case สำหรับพารามิเตอร์และตัวแปรในระบบเนื่องจากมีความแตกต่างน้อยมากถ้ามีจริง ๆ ฉันไม่เคยใช้ headlessCamelCase เพราะมันเป็นง่อยตัวระบุองค์ประกอบเดียวดูเหมือนตัวพิมพ์เล็กแม้ว่ามันจะตั้งใจที่จะเป็น headlessCamelCase

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.