Upload
tran-hieu
View
87
Download
4
Embed Size (px)
Citation preview
The art of readable code
Chương I & II
GMO VNLAB Trần Thanh Hiếu
Dustin Boswell and Trevor Foucher
1
Giới thiệu
• Mục đích của cuốn sách là giúp lậptrình viên tạo ra những đoạn code tốt hơn, dễ đọc, dễ hiểu.
• Cuốn sách không nói về những thứ như architecture hay design pattern mà sẽ tập trung vào những kiến thức căn bản nhất liên quan đến code như tên biến hay cáchviết vòng lặp.
2
Giới thiệu
Cuốn sách chia làm 4 phần• Surface-level improvements
Cách đặt tên biến, chú thích …
• Simplifying loops and logicCách thức cải tiến vòng lặp, logic, biến để chương
trình dễ hiểu hơn
• Reorganizing your codeCách thức tổ chức lại code
• Selected topicsCode dễ hiểu, dễ test và vấn đề về code cho cấu
trúc dữ liệu lớn
3
Chapter I
Code Should Be Easy to Understand
4
Cái gì làm code trở nên tốthơn?
Lựa chọn khi code
• Ngắn gọn, tối giản nhưng mất nhiềuthời gian cho người khác hiểu
• Dài dòng nhưng dễ hiểu
Chapter I 5
Nguyên lý cơ bản
“Code should be written to minimize the time it would take for someone else to understand it.”
Code dễ đọc có thể giúp cho nhữngngười mới tham gia dự án hay chochính bản thân khi mấy tháng saucần nhìn lại phần code này.
Ngoài ra cũng dễ dàng cho việctái sử dụng vào các dự án khác.
Chapter I 6
Is Smaller Always Better?
Giảm số dòng code là mục tiêu tốtnhưng tối giản được thời gian hiểumới là mục tiêu tốt nhất.
Do đó có thể đánh đổi thêm 1 vàidòng code và comment để code dễhiểu hơn
Chapter I 7
Does Time-Till-Understanding Conflict with Other Goals?
Mục tiêu làm code dễ hiểu có bị xungđột với các mục tiêu khác?
Theo kinh nghiệm của tác giả, các mụctiêu khác cũng không bị ảnh hưởngnhiều.
Dù đó là mức độ tối ưu code cao thìcũng có phương án để code dễ hiểu.
Hơn nữa code dễ hiểu cũng thường cócấu trúc tốt và thuận lợi hơn cho quátrình kiểm thử.
Chapter I 8
Chapter II
Surface-Level Improvements
Cải tiến ở cấp độ bề mặt
Cách chọn tên biến, comment, format
Chapter I 9
Surface-Level Improvements
Nhiều sự thay đổi nhỏ sẽ tạo nên sựcải thiện không ngờ cho toàn bộ code.
Không mất quá nhiều công sức nhưngchắc chắn chỉ với việc đặt tên biến, comment, và format tốt cũng sẽ làmcode dễ đọc, dễ hiểu hơn rất nhiều.
Cải tiến bề mặt đáng để quan tâm vàthực hiện trước tiên
Chapter II 10
Packing Information into Names
• Hãy nghĩ tên cũng như những comment nhỏ
• Good name có thể truyền đạt được rất nhiềuthông tin
Chapter II 11
6 Topics
• Choose Specific Words• Avoid Generic Names Like tmp and retval
• Using concrete names instead of abstract names
• Attaching extra information to a name, by using a suffix or prefix
• Deciding how long a name should be• Using name formatting to pack extra information
Chapter II 12
1.Choose Specific Words
• Chọn từ rõ ràng, tránh những từkhông có ý nghĩa.
class BinaryTree { int Size(); …}
Size ở là size gì ?
Good name: MemoryBytes()
KEY IDEA:“It’s better to be clear and precise than to be cute”
Rõ ràng, chính xác thì tốt hơn.
Chapter II 13
2.Avoid Generic Names Like tmp
Thay vì chọn những cái empty name như tmp, retval, foo thì hãy chọnnhững cái tên mô tả giá trị củabiến.
Chapter II 14
Avoid Generic Names Like tmp
Ví dụ kinh điển:
if (right < left) { tmp = right;
right = left;
left = tmp; }
tmp ở đây được cho là hợp lý.
Lý do: Mục đích của nó chỉ lưu trú tạm thờitrong 3 line code và không có nhiệm vụ nàokhác.
Chapter II 15
Avoid Generic Names Like tmp
String tmp = user.name();
tmp += " " + user.phone_number(); tmp += " " + user.email();
...
template.set("user_info", tmp);
Trường hợp trên thì việc sử dụngtmp là một sự lười biếng
Lời khuyên:
Chỉ sử dụng tmp trong trường hợpthời gian sống của biến ngắn.
Chapter II 16
Avoid Generic Names Like tmp
Loop Iterators
Liên quan đến vòng lặp, ngoàiviệc sử dụng những chỉ mục thôngthường như i,j, trong một số trườnghợp nên sử dụng những chỉ mục vớitên chính xác hơn.
Chapter II 17
Avoid Generic Names Like tmp
for (int i = 0; i < clubs.size(); i++)for (int j = 0; j < clubs[i].members.size(); j++)
for (int k = 0; k < users.size(); k++) if (clubs[i].members[k] == users[j])
cout << "user[" << j << "] is in club[" << i << "]" << endl;
Thay vìif (clubs[i].members[k] == users[j])
Sử dụngif (clubs[ci].members[mi] == users[ui])
Chữ cái c,m,u sẽ giúp dễ dàng phát hiện ra giá trị tương ứng vớimỗi vòng lặp. Người khác cũng sẽ nắm bắt được code nhanh hơn rấtnhiều.Lời khuyên: Cần xây dựng thói quen suy nghĩ đặt tên hợp lý
Chapter II 18
Prefer Concrete Names over Abstract Names
Khi đặt tên biến, hàm, thuộc tínhhay mô tả:
Cụ thể luôn tốt hơn trừu tượngThay vì
ServerCanStart()
Sử dụng
CanListenOnPort()
Chapter II 19
4. Attaching Extra Information to a Name
Chapter II 20
Mỗi tên biến hãy coi như một chú thích nhỏ. Đảm bảo rằngmỗi khi tên biến được nhìn thấy thì những thông tin quantrọng nhất cũng được nắm bắt.
string id; // Example: "af84ef845cd8“Sử dụng hex_id thay thế cho id người đọc dễ dàng hiểu
được format id
Values with Units
Giá trị và đơn vị
Thay vìvar start = (new Date()).getTime(); // top of
the page
Sử dụng
var start_ms = (new Date()).getTime(); // top of
the page
Có thể dễ dàng nhận ra giá trịtrả về là milliseconds
Chapter II 21
Values with Units
Function parameter Renaming parameter to encode units
Start(int delay) delay → delay_secs
CreateCache(int size) size → size_mb
ThrottleDownload(float limit) limit → max_kbps
Rotate(float angle) angle → degrees_cw
Chapter II 22
Encoding Other Important Attributes
Hãy đính kèm định danh những thuộctính quan trọng
Dựa vào cách đặt tên này có thể dễdàng nhận ra password đang ở dạngplaintext và cần được xử lý mã hóa
Mã html đã được chuyển đổi sang utf8
Chapter II 23
password plaintext_password
html html_utf8
HUNGARIAN NOTATION
Tham khảo hệ thống cách đặt tênđược sử dụng nhiều tại Microsoft
Đính kèm kiểu của tất cả các biếntrong tiền tố
Name Meaning
pLast A pointer (p) to the last element in some data structure
pszBuffer A pointer (p) to a zero-terminated (z) string (s) buffer
cch A count (c) of characters (ch)
mpcopx A map (m) from a pointer to a color (pco) to a pointer to an x-axis length (px)
24Chapter II
5.How Long Should a Name Be?
Có một ràng buộc ngầm là không nênđặt tên quá dài
newNavigationControllerWrappingViewControllerForDataSourceOfClass
Quá khó nhớ và tiêu tốn nhiều khônggian.
Cân nhắc:Đánh đổi giữa việc bao gồm nhiều nội dung và độ dàicủa tên.
Chapter II 25
Shorter Names Are Okay for Shorter Scope
Những định danh có phạm vi nhỏkhông cần mang quá nhiều thông tin
Phạm vi có thể hiểu là số lượng dòng code có thể nhìn thấy định danh này.
Định danh sử dụng trong một phạmvi lớn cần mang đủ thông tin để dễdàng nắm bắt.
Chapter II 26
Typing Long Names—Not a Problem Anymore
• Hầu hết các lập trình viên đều khôngchú ý tới tính năng “word completion” của các text editor
• Hãy dùng thử ngay và đừng ngạc nhiên vìsự chính xác bất ngờ của nó.
Chapter II 27
Editor Command
Vi Ctrl-p
Emacs Meta-/ (hit ESC, then /)
Eclipse Alt-/
IntelliJ IDEA Alt-/
TextMate ESC
Acronyms and Abbreviations
Lập trình viên vẫn hay sử dụng các từviết tắt để có các định ngắn gọn hơn
BEManager <-> BackEndManager
Sự ngắn gọn này có đáng cho những hiểunhầm có thể xảy ra?
Quy tắc:
Đồng đội mới phải hiểu được định danh có ý nghĩa gì.
Với những từ viết tắt phổ biến nhưstr,doc có thể được sử dụng nhưng như vd ở trên BEManager thực sự khó có thể phánđoán chính xác
28Chapter II
Throwing Out Unneeded Words
• Hãy loại bỏ những từ không cầnthiết
Chapter II 29
ConvertToString ToString
DoServeLoop ServeLoop
6.Use Name Formatting to Convey Meaning
Chỉ với việc sử dụng dấu gạchdưới, gạch ngang hay viết hoa cũngsẽ giúp truyền đạt thêm nhiều thôngtin.
Phần lớn các class chúng ta hay viết có dạngCamelCase
Phần lớn các biến sẽ có dạnglower_separated
Chapter II 30
Other Formatting Conventions
JAVASCRIPT
Tác giả của cuốn sách avaScript : The Good Parts (Douglas Crokford) khuyên rằng constructor nên sử dụngviết hoa và function bình thườngnên bắt đầu với ký tự low var x = new DatePicker(); // DatePicker() is a "constructor" function
var y = pageHeight(); // pageHeight() is an ordinary function
Chapter II 31
Other Formatting Conventions
JQUERYvar $all_images = $("img"); // $all_images is a jQuery
object
var height = 250; // height is not
Sử dụng tiền tố $
Dễ dàng nắm bắt được$all_images là 1 jquery result object
Chapter II 32
Other Formatting Conventions
HTML-CSS
<div id="middle_column" class="main-content">
Thiết lập quy tắc sử dụng “_ “đốivới id và “– “đối với class
Chapter II 33
Other Formatting Conventions
• Cho dù sử dụng hế thống quy tắcnào thì nó cũng sẽ giúp ích rấtnhiều cho hoạt động chung của cảteam.
• Và 1 hệ thống nên được duy trìxuyên suốt project
Chapter II 34
Summary
• Use specific wordsFeatch, Download thì tốt hơn Get
• Avoid generic namestmp, retval chỉ sử dụng khi có lý do đặc biệt
• Use concrete namesCanListenOnPort() tốt hơn là ServerCanStart()
• Attach important detailsappend_ms ms sẽ cho biết giá trị của nó là dạng milliseconds
• Use longer names for larger scopesTên ngắn chỉ tốt khi được sử dụng tại vài line code. Với phạm vi rộng
cần chứa nhiều thông tin để dễ nắm bắt
• Use capitalization, underscores, and so on in a meaningful way
Sử dụng hợp lý ký tự viết hoa, gạch chân để truyền đạt nhiều ý nghĩa hơn
35