- vừa được xem lúc

Fine-grain refactoring deep dive (7) - Comment.

0 0 29

Người đăng: logbasex

Theo Viblo Asia

1. Introduction

In computer programming, a comment is a programmer-readable explanation or annotation in the source code of a computer program. They are added with the purpose of making the source code easier for humans to understand, and are generally ignored by compilers and interpreters.

Trong lập trình, comment là lời giải thích hoặc chú thích mà lập trình viên dễ dàng hiểu được trong mã nguồn của chương trình máy tính. Chúng được thêm vào với mục đích làm cho mã nguồn dễ hiểu hơn đối với con người, và thường bị các trình biên dịch và thông dịch bỏ qua.

Chúng ta sẽ kiểm tra lý thuyết trên thông qua Java class sau:

public class Comment { //Hello, I'm Logbasex. public static void main(String[] args) {}
}

Nếu bạn tiến hành disassemble class này trong trường hợp có comment và không có comment thì bạn sẽ thấy cả hai đều cho ra cùng một kết quả. Từ đấy chúng ta có thể khẳng định rằng việc comment không hề ảnh hưởng đến performance của code.

$ javac Comment.java
$ javap -v Comment.class Classfile /home/logbasex/IdeaProjects/java-demo/src/Comment.class Last modified Mar 7, 2022; size 259 bytes MD5 checksum d87a21ec88edb7b9ce782875eaef27d2 Compiled from "Comment.java"
public class Comment minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER
Constant pool: #1 = Methodref #3.#12 // java/lang/Object."<init>":()V #2 = Class #13 // Comment #3 = Class #14 // java/lang/Object #4 = Utf8 <init> #5 = Utf8 ()V #6 = Utf8 Code #7 = Utf8 LineNumberTable #8 = Utf8 main #9 = Utf8 ([Ljava/lang/String;)V #10 = Utf8 SourceFile #11 = Utf8 Comment.java #12 = NameAndType #4:#5 // "<init>":()V #13 = Utf8 Comment #14 = Utf8 java/lang/Object
{ public Comment(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=0, locals=1, args_size=1 0: return LineNumberTable: line 4: 0
}
SourceFile: "Comment.java"

2. Two bits of history

Nghe nói comment ra đời trong một đêm mưa gió, khi một tập tin hello.asm được viết như sau:

 global _start section .text
_start: mov rax, 1 mov rdi, 1 mov rsi, message mov rdx, 13 syscall mov rax, 60 xor rdi, rdi syscall section .data
message: db "Hello, World", 10 

Bạn thường được bảo rằng, comment explain WHY, not HOW, nhưng có vẻ với assembly code thì HOW lại là một điều cần thiết.

; ----------------------------------------------------------------------------------------
; Writes "Hello, World" to the console using only system calls. Runs on 64-bit Linux only.
; To assemble and run:
;
; nasm -felf64 hello.asm && ld hello.o && ./a.out
; ---------------------------------------------------------------------------------------- global _start section .text
_start: mov rax, 1 ; system call for write mov rdi, 1 ; file handle 1 is stdout mov rsi, message ; address of string to output mov rdx, 13 ; number of bytes syscall ; invoke operating system to do the write mov rax, 60 ; system call for exit xor rdi, rdi ; exit code 0 syscall ; invoke operating system to exit section .data
message: db "Hello, World", 10 ; note the newline at the end

Bởi vì cú pháp của ngôn ngữ không gần với ngôn ngữ tự nhiên nên là việc xử lý thông tin với bộ não thông thường sẽ gặp delay, đó cũng là lý do dẫn đến sự ra đời của những ngôn ngữ bậc cao sau này.

Bonus một ví dụ comment assembly code bằng high-level code =)) Thật không thể tin được 😂😂😂😂.

Nếu bạn muốn tìm hiểu thêm về lịch sử ra đời của comment thì có thể xem thêm ở đâyđây.

3. Issue

Sau khi có sự xuất hiện ngôn ngữ lập trình bậc cao, chúng ta có thể viết những đoạn code khá mượt mà và trực quan như sau:

private static final int EMPLOYEE_BONUS_PERCENTAGE = 10/100; public void calculateBonus() { List<Employee> employees = getAllEmployees(); for (Employee employee : employees) { if (employee.getType() == EmployeeEnum.MANAGER.getType()) { employee.setBonus(employee.getWage() * EMPLOYEE_BONUS_PERCENTAGE); } }
}

Không cần phải là chuyên gia thì bạn cũng dễ dàng nắm được đoạn code này làm cái gì rồi đúng không?

Trong tất cả các nhân viên, tìm ra những ai là quản lý và cấp cho họ khoản bonus tương ứng 10% tiền lương.

Tuy nhiên vấn đề ở đây đó chính là nhiều tháng sau, khi bạn quay lại maintain đoạn code này, bạn không biết tại sao lại có con số 10% cả.

Úi giời dễ, bạn bảo rằng bạn sẽ tìm người đã viết đoạn code này để hỏi, nhưng hồi đó còn chưa có git blame, chỉ có copy rồi patch code qua USB hay cái gì đó tương tự thôi 🤣🤣 .

// ********************************************************************
// * Logger helper *
// * *
// * 2005-03-01 First Version, Anders Abel *
// * 2007-08-17 Added Console Output, Anders Abel *
// * 2009-12-15 Removed file output, John Doe *
// * *
// * Usage: Call Logger.Write() with string to be logged. *
// ********************************************************************
public static class Logger { }

Thế thì bạn sẽ hỏi QA, Manager...kiểu gì cũng có người biết. Đồng ý là vấn đề của bạn sẽ được giải quyết nhưng đáng ra bạn sẽ tiết kiệm được thời gian nếu như đoạn code đó có một vài comment chẳng hạn. Nhưng đối với những đoạn tricky/clever code thì sẽ khó có ai giúp bạn hiểu được nếu như người viết đoạn code đó đã ra đi...

{ { while (.. ){ if (..){ } for (.. ){ } .... (just putting in the control flow here, imagine another few hundred ifs) if(..) { if(..) { if(..) { ... (another few hundred brackets) } } } //endif

Thật là mệt mỏi 🥲🥲🥲. image.png

4. Solution

  1. Trong Employee class có một trường type nhưng bạn không biết trường này định nghĩa cái gì, bao gồm những giá trị nào thì hãy dùng javadoc để reference đến enum của nó:
    /** * {@link com.logasex.enums.EmployeeEnum} */
    @Field(FieldConst.TYPE)
    private String type;
    
  2. Con số 10% được định nghĩa rõ ràng trong Jira ticket, vậy làm sao để comment như một hyper link?
    /** * {@link <a href="https://logbasex.atlassian.net/jira/software/c/projects/logbasex/boards/127?modal=detail&selectedIssue=logbasex-2949&assignee=5cf483a4757e4b0f2636c4c0"></a>} */
    private static final int EMPLOYEE_BONUS_PERCENTAGE = 10/100;
    
  3. Phương tính tính bonus và wage có sự liên quan chặt chẽ nhưng không gọi trực tiếp đến nhau, vậy thì làm sau để biểu diễn điều đó qua comment? Thật may mắn là javadoc đã support reference method với syntax như sau: image.png
    /** * {@link com.logbasex.WageServiceImpl#calculateWage()} */
    public void calculateBonus() {}
    

    Với những IDE hiện đại thì bạn có thể chuyển đến bất cứ reference link nào chỉ với một cú nhấp chuột. Thật là tiện lợi phải không?

5. Best practices

Trong trường hợp trên mình đang giả định là chúng ta đã có một đoạn code rõ ràng, dễ hiểu, tuy nhiên trong thực tế nhiều lúc sẽ không đạt được trạng thái lý tưởng đó. Vậy nên chúng ta cần một số kinh nghiệm để viết comment một cách hợp lí, tránh việc comment bừa bãi vừa làm ô nhiễm source code, vừa làm tăng cognitive complexity khiến bạn tốn thời gian không cần thiết cho việc đọc hiểu.

“Every time you write a comment, you should grimace and feel the failure of your ability of expression.” — Robert C. Martin

Good codes have rhythm while mediocre codes have a lot of pauses ... by comments.

Communicate via your codes, not your comments.

Code comment is a smell. If you write code comments as the last option to improve your code, it will force you to improve your self-documenting skills first. That's why it should be considered a smell.

Keep comment up to date. “Code never lies, comments sometimes do.” — Ron Jeffries

Self-documented code over comprehensive comments.

“Don’t comment bad code explaining what is happening, Rewrite it!”

“The only best comment is the comment you found a way not to write.”

Comments should describe the intended outcome of the code in a language-agnostic fashion. It should not restate the code itself.

One should be able to completely re-implement the code in any language, given only the comments. In other words, your intent comments are a living specification!

I don’t comment my code because if it was hard to write, then it should also be hard to read

image.png

image.png,.

References

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tổng hợp các bài hướng dẫn về Design Pattern - 23 mẫu cơ bản của GoF

Link bài viết gốc: https://gpcoder.com/4164-gioi-thieu-design-patterns/. Design Patterns là gì. Design Patterns không phải là ngôn ngữ cụ thể nào cả.

0 0 302

- vừa được xem lúc

Học Spring Boot bắt đầu từ đâu?

1. Giới thiệu Spring Boot. 1.1.

0 0 277

- vừa được xem lúc

Cần chuẩn bị gì để bắt đầu học Java

Cần chuẩn bị những gì để bắt đầu lập trình Java. 1.1. Cài JDK hay JRE.

0 0 50

- vừa được xem lúc

Sử dụng ModelMapper trong Spring Boot

Bài hôm nay sẽ là cách sử dụng thư viện ModelMapper để mapping qua lại giữa các object trong Spring nhé. Trang chủ của ModelMapper đây http://modelmapper.org/, đọc rất dễ hiểu dành cho các bạn muốn tìm hiểu sâu hơn. 1.

0 0 194

- vừa được xem lúc

[Java] 1 vài tip nhỏ khi sử dụng String hoặc Collection part 1

. Hello các bạn, hôm nay mình sẽ chia sẻ về mẹo check String null hay full space một cách tiện lợi. Mình sẽ sử dụng thư viện Lớp StringUtils download file jar để import vào thư viện tại (link).

0 0 71

- vừa được xem lúc

Deep Learning với Java - Tại sao không?

Muốn tìm hiểu về Machine Learning / Deep Learning nhưng với background là Java thì sẽ như thế nào và bắt đầu từ đâu? Để tìm được câu trả lời, hãy đọc bài viết này - có thể kỹ năng Java vốn có sẽ giúp bạn có những chuyến phiêu lưu thú vị. DJL là tên viết tắt của Deep Java Library - một thư viện mã ng

0 0 139