Đặt tên trong clean code (Phần 2)

01/11/2020 - lượt xem
Chia sẻ
 
Rate this post

Tiếp tục với đặt tên có ý nghĩa. Ở bài trước Đặt tên trong clean code (Phần 1)  chúng ta thấy được tầm quan trong của đặt tên. Và cách đặt tên sao cho hiệu quả theo mục đich sử dụng tránh gây nhầm lẫn. Tiếp đến bài hôm nay chúng ta sẽ đi sâu vào đặt tên trong class, method, function … Hãy cùng tìm hiểu ngay.

Tên class ( Class names )

Tên class, đối tượng nên là 1 danh từ hoặc cụm danh từ giống như là: Customer, WikiPage, Account, AddressParser.

Tên class không nên sử dụng là 1 động từ.

Tên phương thức: Method names

Phương thức nên là động từ giống như là postPayment, deletePage hay save. Các phương thức truy suất nên bắt đầu là get, set, is…

string name = employee.getName();

customer.setName("mike");

if (paycheck.isPosted())...

//Khi Constructors overload, sử dụng static factory method cùng với tên và đối số.

Complex fulcrumPoint = Complex.FromRealNumber(23.0);

Tốt hơn là:

Complex fulcrumPoint = new Complex(23.0);

Đừng nên cố gắng tỏ ra dễ thương ( Don’t be Cute )

Tên gọi một cách rõ ràng luôn tốt hơn là những tên theo phong cách hài hước.

Ví dụ như dùng eatMyShorts thì nên dùng abort thay thế sẽ tốt hơn rất nhiều

Say what you mean. Mean what you say. (Hãy nói những gì bạn thấy có ý nghĩa)

Chọn 1 từ cho mỗi khái niệm ( Pick One Word per Concept )

Bạn nên chọn 1 từ cho 1 khái niệm trừu tượng cụ thể. Ví như cùng để lấy dữ liệu bạn có thể đặt tên hàm là dạng : fetch, retrieve hay là get trong các class khác nhau. Tuy nhiên sau đó là bài toán sử dụng, làm thế nào để ghi nhớ được trong từng class đã sử dụng tên hàm nào?

Do vậy nên cùng với 1 khái niệm được đặt ra chúng ta nên có 1 thuật ngữ nhất quán xuyên suốt. Dù rằng IDE hiện đại đều hỗ trợ rất nhiều trong việc gợi ý hàm, tham số truyền vào… nhưng đặt tên có tiêu chuẩn vẫn là cách làm được khuyến nghị dùng hơn cả.

Không chơi chữ ( Don’t pun )

Không sử dụng cùng 1 từ với 2 mục đích khác nhau. Sử dụng cùng 1 thuật ngữ cho 2 ý tưởng khác nhau thực chất là một cách chơi chữ.

Nếu bạn tuân thủ nguyên tắc “1 từ mỗi khái niệm”, bạn có thể sử dụng cho nhiều class. Ví dụ như dùng 1 phương thức add trong nhiều class đó. Miễn là vẫn đảm bảo hàm add này vẫn đảm bảo về mặt ngữ nghĩa – tham số truyền vào và dữ liệu trả về tương đương nhau.

Ví dụ chúng ta đang có nhiều class đều có phương thức add với mục đích tạo ra giá trị mới hoặc nối với giá trị với nhau. Và sau đó chúng ta muốn có 1 class mới, trong đó 1 phương thức với ý nghĩa thêm 1 phần tử vào 1 mảng (Collection). Lúc này chúng ta nên sử dụng tên khác cho phương thức đó, có thể là insert hoặc append thay vì là add.

 

Use Solution Domain Names

Hãy nhớ rằng, những người đọc code của bạn chính là các lập trình viên. Do vậy hãy sử dụng thuật ngữ Khoa học máy tính, tên giải thuật, tên pattern (mẫu), toán học… Chúng ta nên sử dụng cách đặt tên hướng tới giải pháp xử lý thay vì nói lên các nghiệp vụ. ĐIều này sẽ giúp cho những đồng nghiệp của chúng ta dễ dàng hiểu được đoạn mã mà không phải chạy tới chạy lui để tìm hiểu về 1 vấn đề mà bản chất họ đã biết tới dưới 1 cái tên khác.

Use Problem Domain Names

Khi làm việc với những phần mà không giành cho lập trình viên, ạn nên sử dụng các tên theo hướng về nghiệp vụ. Ít nhất như vậy những người bảo trì cũng nắm rõ được nghiệp vụ thông qua việc đọc mã nguồn.

Tách biết được phần solution và problem là một 1 phần của lập trình viên và 1 nhà thiết kế tốt. NHững đoạn mã mà chỉ cần quan tâm tới những khái niệm nghiệp vụ thì nên mang tên nghiệp vụ.

Thêm bối cảnh có ý nghĩa ( add meaningful context )

Có 1 số ít tên mà bản thân nó tự có nghĩa, đa phần thì là không. Thay vào đó, chúng ta cần đặt các tên này vào ngữ cảnh/bỗi cảnh của người đọc và đặt vào trong class, function, namespace.

Nếu trong trường hợp không thể làm như vậy, việc thêm tiền tố vào tên là phương án khả dĩ có thể xem xét.

Tưởng tượng rằng, bạn có các biến tên là: firstName, lastName, street, houseNumber, city, state, zipcode. Khi các biến này được đặt cùng nhau, chúng ta đều hiểu rằng đoạn mã đang muốn nói về địa chỉ. Tuy nhiên nếu state chỉ đứng 1 mình thì sao? liệu chúng ta có hiểu rằng nó là 1 phần của địa chỉ ?

Chúng ta có thể bổ sung ngữ cảnh bằng cách thêm tiền tố vào như sau: addrFirstName, addrLastName, addrState… Tuy nhiên phương án tốt hơn cả là nên tạo 1 class tên là Address. Như vậy cả trình biên dịch cũng biết rằng các biến này thuộc về 1 cấu trúc lớn hơn.

1 ví dụ với tên biến không rõ ràng về mặt ngữ cảnh

private void printGuessStatistics(char candidate, int count) {

    String number;

    String verb;

    String pluralModifier;

    if (count == 0) {

          number = "no";

          verb = "are";

          pluralModifier = "s";

    } else if (count == 1) {

          number = "1";

          verb = "is";

          pluralModifier = "";

    } else {

          number = Integer.toString(count);

          verb = "are";

          pluralModifier = "s";

    }

        String guessMessage = String.format(

       "There %s %s %s%s", verb, number, candidate, pluralModifier

   );

        print(guessMessage);

}

Hàm trên đây quá dài, các biến thì được sử dụng xuyên suốt cả hàm này. Để chia nhỏ hàm này thành các phần nhỏ hơn, chúng ta cần tạo class GuessStatisticMessage và đưa 3 biến verb, number, pluralModifier trở thành thuộc tính của class đó.

Việc cải thiện ngữ cảnh cũng cho phép làm sạch mã code bằng cách tách nhỏ thành nhiều hàm khác nhau.

Dưới đây là đoạn mã được chỉnh lại với sự rõ ràng hơn về ngữ cảnh.

public class GuessStatisticsMessage {

   private String number;

   private String verb;

   private String pluralModifier;

   public String make(char candidate, int count) {

     createPluralDependentMessageParts(count);

     return String.format(

     "There %s %s %s%s",

     verb, number, candidate, pluralModifier );

   }

    private void createPluralDependentMessageParts(int count) {

      if (count == 0) {

          thereAreNoLetters();

      } else if (count == 1) {

          thereIsOneLetter();

      } else {

          thereAreManyLetters(count);

     }

  }

    private void thereAreManyLetters(int count) {

      number = Integer.toString(count);

      verb = "are";

      pluralModifier = "s";

    }

  private void thereIsOneLetter() {

     number = "1";

     verb = "is";

     pluralModifier = "";

}

private void thereAreNoLetters() {

   number = "no";

   verb = "are";

   pluralModifier = "s";

}

}

Không thêm bối cảnh 1 cách tùy tiện ( Don’t add Gratuitous Context )

Giả sử chúng ta có ứng dụng tên là “Gas Station Deluxe”, nó là 1 ý tưởng rất tệ nếu mỗi class đều bắt đầu bằng GSD. Thật vậy, các IDE đều hỗ trợ tính năng autocomplete code, và khi chúng ta ấn G, sẽ hàng loạt các biến gợi ý ra, thật là rắc rối và phiền phức.

Tên ngắn thì tốt hơn các tên dài, nếu nó thực sự rõ nghĩa. Đừng cố gắng thêm bối cảnh vào tên nếu không thực sự cần thiết.

Tổng kết

Để đặt được 1 cái tên phù hợp đòi hỏi chúng ta phải có kỹ năng mô tả tốt cùng với 1 nền văn hóa chia sẻ (viết code ra để người khác có thể hiểu được).

Sử dụng các kĩ thuật đặt tên đã nêu được sử dụng trong việc bảo trì, refactoring code sau này. Chính việc đặt tên một cách có chủ đích sẽ tiết kiệm rất nhiều thời gian của chính bạn sau này đấy.

    Liên hệ với chúng tôi

    Để lại thông tin để nhận được các bài viết khác

    Rate this post

    Xem thêm nhiều bài tin mới nhất về Clean code

    Xem thêm