Các quy ước đặt tên, ví dụ, các biến cục bộ và tham số [đã đóng]


13

Tôi đã thảo luận với một công ước mã hóa phát triển cao cấp để áp dụng cho các dự án của chúng tôi (chủ yếu là các dự án Java / JEE). Tôi không đồng ý với một quy ước mà ông đề xuất:

Tên biến sơ thẩm phải bắt đầu bằng "_", biến cục bộ có "loc" và tham số phương thức có "par", do đó sẽ dễ dàng xác định nguồn gốc và phạm vi của biến.

Trong khi anh ấy đưa ra các đối số cho bộ nhớ ngắn hạn và khả năng đọc, tôi không đồng ý với thực tế là nó giảm khả năng đọc, các IDE thích các biến định dạng Eclipse khác nhau tùy theo loại của chúng và vấn đề này sẽ tránh được với một thiết kế phương thức và lớp tốt.

Bạn có bất kỳ ý kiến, lập luận hoặc nghiên cứu nào ủng hộ quan điểm của tôi (hoặc phản đối nó) không?


Bạn nói rằng bạn không đồng ý với "thực tế là nó làm giảm khả năng đọc". Tôi không nói bạn sai, nhưng bạn đã cung cấp bằng chứng gì để hỗ trợ cho tuyên bố đó? Tôi không biết về bất kỳ nghiên cứu nào nói rằng nó sẽ làm giảm khả năng đọc (Tôi đã nghiên cứu về nhận thức tại tâm lý học sau đại học trước khi trở thành nhà phát triển, vì vậy đây là một lĩnh vực tôi quan tâm.)
AdamJonR

Tôi có nghĩa là nó như là lộn xộn. Nhưng tôi không có bất kỳ bằng chứng nào khác ngoài ý kiến ​​cá nhân của mình
HH

Các tiền tố trùng lặp thông tin đã được chứa trong mã và được hiển thị trong bất kỳ môi trường nửa nào. Và như chúng ta đều biết, thông tin trùng lặp có thể trở nên không nhất quán. DRY sẽ hướng bạn đến việc không sử dụng các tiền tố.
Julia Hayward

Câu trả lời:


15

Như Wikipedia nói về chủ đề - Quy tắc đặt tên java,

Các biến cục bộ, biến thể hiện và biến lớp cũng được viết bằng lowCamelCase. Tên biến không được bắt đầu bằng ký tự gạch dưới (_) hoặc ký hiệu đô la ($), mặc dù cả hai đều được cho phép. Một số quy ước mã hóa nhất định tuyên bố rằng dấu gạch dưới nên được sử dụng để tiền tố tất cả các biến thể hiện, để cải thiện việc đọc và hiểu chương trình.

Theo kinh nghiệm của tôi với các tiêu chuẩn mã hóa, các tên biến Instance bắt đầu bằng "_" không tốt như các tiêu chuẩn wikipedia nói.

Các biến cục bộ với "loc" và các tham số phương thức với "par", như bạn đã nói, sẽ dễ dàng xác định nguồn gốc và phạm vi biến, nhưng nó phải dành cho bạn, không phải các lập trình viên khác có thể đi qua mã của bạn để bảo trì một ngày nào đó .

Theo thông số kỹ thuật của Clean Code về các phương thức, các phương thức này phải ngắn nhất có thể để bạn có thể đọc được và các tên biến không nên được ánh xạ, chúng phải phù hợp với hoạt động của bạn mà phương thức của bạn thực hiện.

Tiền tố thành viên / phạm vi, Bạn cũng không cần phải thêm tiền tố biến thành viên với m_ nữa. Các lớp học và chức năng của bạn phải đủ nhỏ để bạn không cần đến chúng. Và bạn nên sử dụng một môi trường chỉnh sửa làm nổi bật hoặc tô màu các thành viên để làm cho họ khác biệt.

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

Bên cạnh đó, mọi người nhanh chóng học cách bỏ qua tiền tố (hoặc hậu tố) để xem phần ý nghĩa của tên. Chúng ta càng đọc mã, chúng ta càng thấy ít tiền tố. Cuối cùng, các tiền tố trở nên lộn xộn vô hình và một dấu hiệu của mã cũ hơn.


4

Đây là một câu hỏi cũ, nhưng dù sao tôi cũng sẽ đăng ở đây. Tôi có hơn 20 năm lập trình và giao dịch với mã của người khác.

Tôi nghĩ rằng việc đặt tên biến của bạn với một dấu hiệu ngắn về phạm vi của chúng thực sự hữu ích cho người tiếp theo (hoặc chính bạn), người sẽ xem mã của bạn.

Người ta chưa xem mã trong một IDE có màu sắc đẹp (và tôi không thể nhớ màu sắc có nghĩa là gì và IDE khác nhau hiển thị các màu khác nhau, v.v.).

Đúng, các phương thức phải đủ ngắn để nó không được tải với hàng tấn biến và tấn mã mà ngay cả khi ngắn - khi bạn nhìn vào mã hoàn toàn xa lạ, đôi khi rất khó để biết liệu một biến có phải là biến lớp hay không, cục bộ tham số biến hoặc phương thức.

Để có thể phân biệt trong nháy mắt làm cho nó rất dễ dàng để xem lại mã mà bạn không quen thuộc.

Lấy ví dụ này:

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

Bây giờ, hãy dành thời gian cho chính mình và xem mã (được trích xuất từ ​​ElSTERearchTemplate từ dự án nghiên cứu dữ liệu mùa xuân - mã mà tôi đang xem xét khiến tôi tìm kiếm trên Google về những gì mọi người nói về quy ước đặt tên).

  • Cái gì của cái resultsMappergì?
  • requestBuildingmột tham số?
  • Vân vân...

Đây là gợi ý đơn giản của tôi về cách đặt tên biến:

  • Các thuộc tính tĩnh của lớp (tức là hằng số): ALL_CAPS_WITH_UNDERSCORES (ví dụ: HOST_NAME ).
  • Các thuộc tính lớp (tức là các biến thể hiện của lớp): camelCase (vd resultsMapper).
  • Thông số phương pháp: bắt đầu bằng a(ví dụ aQuery, aClazz).
  • Biến cục bộ: bắt đầu bằng my(ví dụ myIndexName, myType).

Đoạn mã trên trở thành:

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

}

Điều đó có hoàn hảo không? Tôi không nghĩ vậy. Nhưng ở trên, khi có liên quan đến các biến, bây giờ dễ đọc hơn. Có những thứ khác như căn chỉnh và khoảng cách, mà tôi sẽ không nhận được trong câu trả lời này vì nó không liên quan đến câu hỏi, điều này cũng sẽ giúp bạn dễ đọc hơn.

Bạn không thích Camel Case? Tốt thôi, hãy sử dụng dấu gạch dưới, v.v., nhưng tiền tố các biến cục bộ và các tham số của bạn để làm cho chúng khác với các biến thể hiện của lớp.

Bạn không thích amy - tốt thôi, hãy kiên định trong dự án của bạn và sử dụng thứ khác ... nhưng hãy sử dụng thứ gì đó.

Quy tắc số 1: tính nhất quán trong dự án.

Quy tắc số 2: làm cho nó dễ đọc và không yêu cầu người đọc biết mọi thứ trước khi anh ta có thể học.


3

Đây phần lớn là vấn đề ưu tiên và vì thế không có câu trả lời 'chính xác'. Vì vậy, câu hỏi này thực sự có thể được đóng lại. Nhưng trước khi nó xảy ra, hãy để tôi nói với bạn rằng tôi hoàn toàn đồng ý với bạn. Tiền tố giảm tầm nhìn xa như tôi quan tâm. Nói một cách thực tế rằng nếu có bất kỳ tiền tố nào, chúng nên được sử dụng cho những thứ hữu ích hơn, như ý định ban đầu của Ký hiệu Hungary , và không phải cho những thứ mà IDE của bạn có thể làm nổi bật cho dù sao đi nữa.

Tôi sử dụng SentenceCase cho dữ liệu ví dụ (cho dù biến hoặc hằng) và low_case cho tham số và biến cục bộ, vì thực sự có rất ít, nếu có, sự khác biệt giữa hai. Tôi không bao giờ, không bao giờ sử dụng headlessCamelCase vì nó là khập khiễng : một định danh một thành phần trông giống như chữ thường, ngay cả khi nó được dự định là headlessCamelCase.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.