SlideShare a Scribd company logo
1 of 35
SEMINAR: CLEAN CODE
PRESENTERS:
NGUYEN VAN THIEU
TRAN THE ANH
1. THẾ NÀO LÀ CLEAN CODE
• Là làm tốt 1 việc
• Là đơn giản và trực tiếp, giống như đọc văn xuôi được viết tốt, không làm lu mờ ý định của thiết kế nhưng
vẫn đầy đủ các khái niệm trừu tượng sắc nét và đường kiểm soát đơn giản.
• Là mã sạch có thể đọc, nhận biết và có ý nghĩa.
• Là code sẽ có thể được đọc, và được cài thiện hoặc viết tiếp được bởi developer khác. Nó có đơn vị chấp
nhận và kiểm tra. Nó có tên đầy ý nghĩa. Nó cung cấp một cách khá hơn nhiều cách để làm một điều. Nó có
phụ thuộc tối thiểu, được định nghĩa một cách rõ ràng, và cung cấp một API rõ ràng và tối thiểu.
• Luôn luôn giống những gì mà được viết bởi 1 người quan tâm nó thật sự
• Giảm sự lặp lại, biểu cảm cao, và xây dựng ban đầu của sự trừu tượng đơn giản.
• Là mã chạy tất cả các bài test để kiểm tra, mã không chứa trùng lặp mà vẫn bày tỏ đầy đủ những ý tưởng
thiết kế trong hệ thống.
• Là mã giảm thiếu số lượng các classes, functions, methods.
2. LÀM THẾ NÀO ĐỂ CODE "TRONG SÁNG"
• Khi làm dự án hay lập trình bất kỳ thứ gì ta phải có các quy tắc
code (code convention)
• Để code trong sáng thì ta phải có quy tắc code chuẩn, rõ ràng,
và làm theo được các chuẩn đó đó.
3. NHỮNG NGUYÊN TẮC CƠ BẢN (CODE
CONVERSION)
• Quy tắc đặt tên
• Quy tắc với Hàm (Functions)
• Quy tắc với Comments
• Định dạng code (Formatting)
• Quy tắc với Objects và Data Structures
• Quy tắc xử lý lỗi
3.1. Quy tắc đặt tên
1. Sử dụng tên có ý nghĩa
2. Tránh dùng các chữ cái gây hiểu lầm, hoặc đặt tên quá ngắn gây hiểu lầm
3. Làm cho sự phân biệt có ý nghĩa.
4. Sử dụng tên phát âm được để có thể dễ nhớ, dễ hình dung.
5. Đặt tên dễ tìm kiếm trong phần mềm.
6. Tên classes và object thì nên để là danh từ và phải rõ nghĩa, không nên là động từ.
7. Tên hàm dùng prefixed để rõ nghĩa với set, get, is..
3.1. Quy tắc đặt tên
1. Sử dụng tên có ý nghĩa (Tên thể hiện rõ được mục đích của biến, hàm...)
Vd:
int d // Không có ý nghĩa gì
int dayOfThisMonth // Hiểu được là số ngày trong tháng
2. Tránh dùng các chữ cái gây hiểu lầm, hoặc đặt tên quá ngắn gây hiểu lầm
Vd:
int o // Đây là biến o
if (o == 1)
a = o
else
b = o // Nhìn nó giống số 0 nên dễ gây hiểu lầm
3.1. Quy tắc đặt tên
3. Làm cho sự phân biệt có ý nghĩa.
Vd:
public static void copyChars(char a1[], char a2[]) {
for (int i = 0; i < a1.length; i++) {
a2[i] = a1[i];
}
}
public static void copyChars(char source[], char destination[]) {
for (int i = 0; i < source.length; i++) {
destination[i] = source[i];
}
}
3.1. Quy tắc đặt tên
4. Sử dụng tên phát âm được để có thể dễ nhớ, dễ hình dung.
Vd: class DtaRcrd102 {
private Date genymdhms;
private Date modymdhms;
private final String pszqint = "102";
};
class Customer {
private Date generationTimestamp;
private Date modificationTimestamp;;
private final String recordId = "102";
};
3.1. Quy tắc đặt tên
5. Đặt tên dễ tìm kiếm trong phần mềm.
Vd:
3.1. Quy tắc đặt tên
6. Tên classes và object thì nên để là danh từ và phải rõ nghĩa, không nên là động từ.
Vd:
Manager, Processor, Data. (Không nên dùng)
Customer, WikiPage,Account, and AddressParser. (Nên dùng)
8. Tên hàm
Vd:
postPayment, deletePage, save.  Tên hàm thường viết dạng cammelCase hoăc cammel_case
- Dùng prefixed để rõ nghĩa với set, get, is..
Vd:
string name = employee.getName();
customer.setName("thieunv");
if(paycheck.isPosted()) {
...
}
3.2. QUY TẮC VỚI HÀM
1. Nhỏ gọn
2. Blocks và Indenting
3. Làm 1 việc .
4. Một cấp độ trừu tượng trên 1 hàm.
5. Reading code from Top to Bottom : The Stepdown Rule
6. Switch Statements
7. Sử dụng tham số của hàm
8. Command Query Separation
9. Prefer Exceptions to Returning Error Codes
10. Trích xuất try/catch block.
11. Error Handling Is One Thing
12. How Do You Write Functions Like This?
3.2. QUY TẮC VỚI HÀM
1. Nhỏ gọn
• 1 dòng không nên quá 150 ký tự
• 1 hàm không nên quá 30 dòng (1 trang giấy)
2. Blocks và Indenting
• Với các block if,else không nên nối tiếp lặp quá sâu (quá 3 mức)
• Lùi đầu dòng chuẩn, nên dùng tab.
3. Làm 1 việc
• FUNCTIONS SHOULD DO ONE THING. THEY SHOULD DO IT WELL. THEY SHOULD DO
IT ONLY.
4. Một cấp độ trừu tượng trên 1 hàm.
5. Reading code from Top to Bottom : The Stepdown Rule
3.2. QUY TẮC VỚI HÀM
6. Switch Statements
==> 1. Quá lớn, khi thêm loại của employee nó sẽ lớn hơn nữa.
2. Nó làm nhiều hơn 1 việc.
3. Xâm phạm nguyên tắc Single Responsibility Principle (SRP)
4. Xâm phạm nguyên tắc Open Closed Principle (OCP)
3.2. QUY TẮC VỚI HÀM
3.2. QUY TẮC VỚI HÀM
7. Sử dụng tham số của hàm
- Nhiều nhất nên là 2 tham số đầu vào
- Nếu có nhiều tham số hơn 2 thì nên bao chúng lại trong 1 class
Vd:
Circle makeCircle(double x, double y, double radius);
Circle makeCircle(Point center, double radius);
- Đối với tham số đầu ra cần rõ ràng, giải thích như tham số đầu vào.
3.2. QUY TẮC VỚI HÀM
8. Command Query Separation
- Hàm nên làm việc gì đó hoặc trả lời gi đó nhưng không nên làm cả 2.
Vd phổ biến:
public boolean set(String attribute, String value);
==> Hàm này set giá trị của attribute là value. Nếu thành công thì trả về true.
==> Nó sẽ dẫn đến câu lệnh sau:
if (set("username", "unclebob"))...
==> Nếu ta là reader. Ta sẽ tự hỏi. cái hàm set này nó làm nhiệm vụ gì? Đã là set tại sao lại cho được trong if.
==> Để fix được ta có thể đổi tên là: setAndCheckIfExists ==> Cũng không mấy khả quan.
==> Để thật sự fix được ta nên chia rẽ nhiệm vụ của chúng ra như sau:
if (attributeExists("username")) {
setAttribute("username", "unclebob");
...
}
3.2. QUY TẮC VỚI HÀM
9. Prefer Exceptions to Returning Error Codes
- Trả về lỗi code từ hàm là vi phạm sự tinh tế của gọi lệnh tách biệt.
if (deletePage(page) == E_OK)
- Điều này không gây nhầm lẫn hay dẫn đến xử lý cấu trúc lặp. Nhưng khi trả về lỗi code, ta phải giải quyết
ngay nó.
3.2. QUY TẮC VỚI HÀM
- Thay vì phải dùng nhiều if như trên ta có thể dùng Exceptions để xử lý.
3.2. QUY TẮC VỚI HÀM
- Một lợi thế khác của Exceptions nữa là:
public enum Error {
OK,
INVALID,
NO_SUCH,
LOCKED,
OUT_OF_RESOURCES,
WAITING_FOR_EVENT;
}
==> Khi ta có các lỗi code như trên. Sẽ rất nhiều nơi phải import enum vào. Nếu giờ Error có thêm lỗi. Ta
phải thay đổi enum.
==> Sẽ dẫn đến việc các nơi khác dùng Error sẽ phải thay đổi ==> Ta phải recompile and rebuild lại.
==> Giờ nếu ta dùng Exceptions
3.2. QUY TẮC VỚI HÀM
10. Trích xuất try/catch block.
- Bản thân try/catch đã là rất tồi. Nó bị trộn lẫn giữa lỗi và xử lý tự nhiên.
- Để giúp dễ đọc, dễ hiểu và khiến code trong sáng hơn thì ta nên tách biệt thân ra hàm.
Vd:
- Hàm delete bên trên chỉ về xử lý lỗi. Hàm deletePageAndAllReferences chỉ về xử lý việc xóa page. xử lý lỗi không trộn lẫn.
public void delete(Page page) {
try {
deletePageAndAllReferences(page);
}
catch (Exception e) {
logError(e);
}
}
private void deletePageAndAllReferences(Page page) throws
Exception {
deletePage(page);
registry.deleteReference(page.name);
configKeys.deleteKey(page.name.makeKey());
}
private void logError(Exception e) {
logger.log(e.getMessage());
}
3.2. QUY TẮC VỚI HÀM
11. Error Handling Is One Thing
- Hàm làm 1 việc. Xử lý lỗi làm 1 việc. Vậy hàm xử lý lỗi không nên làm việc gì khác.
- Giống vd bên trên. Trong hàm delete chỉ có duy nhất khối try/catch.
3.2. QUY TẮC VỚI HÀM
12. How Do You Write Functions Like This?
- Viết hàm giống như viết paper, article hay bất cứ thứ gì về viết.
- Đầu tiên ta nên có bản nháp, sau đó tổ chức lại, đặt tên lại, chia nhỏ nó ra, giảm sự trùng
lăp...
- Có thể lúc đầu ta cảm thấy làm vậy mất thời gian, nhưng khi về sau phải debug hoặc
maintain thì ta mới thấy được sự
lợi hại thật sự của việc viết nó clean.
- Không những vậy nó còn làm ta trở thành better programmer.
3.3. QUY TẮC VỚI COMMENTS
1. Comment giải thích đúng rõ mục đích của nó.
2. Comment tốt và hợp lý
3. Bad Comments
4. Redundant Comments
5. Noise Comments, Comments sai lêch
6. Commented-Out Code
3.3. QUY TẮC VỚI COMMENTS
1. Comment giải thích đúng rõ mục đích của nó.
- Comment không trang điểm cho bad code nhưng nó nói lên rằng code của bạn không
clean.
- Trước khi comment, ta hãy nghĩ tại sao ta lại phải cần comment.
- Nếu ta thấy đoạn code lằng nhằng, khó hiểu phải cần comment. Thì ta nên giành thời
gian để clean đoạn code đó thay vì ngồi comment nó.
- Vd:
// Check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))
if (employee.isEligibleForFullBenefits())
- Thay vì phải viết comment và 1 đống logic như trên. Ta chỉ cần tống chúng vào hàm và
đặt tên dễ hiểu thì code clean hơn.
3.3. QUY TẮC VỚI COMMENTS
2. Comment tốt và hợp lý
Vd:
// Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the GNU General Public License version 2 or later.
- Khi publish dự án thì ta nên viết comment thế nào vào source để nói quyền sở hữu,
version...
3.3. QUY TẮC VỚI COMMENTS
3. Bad Comments
- Đa phần chúng ta rơi vào đây.
- Có nhiều lúc ta không cần comment, nhưng ta lại cảm thấy cần comment. vậy là ta giành thời gian để viết comment.
Vd:
==> Ta có thể thấy đoạn comment trên có thể có ý nghĩa nào đó với người viết, nhưng chắc chắn sẽ vô nghĩa với reader.
- Ta có thể hiểu nếu rơi vào catch thì sẽ không có file nào được load.
- Nhưng nếu file được load thì sẽ load ở đâu, load lúc nào (tác giả chưa nói bên trên)
3.3. QUY TẮC VỚI COMMENTS
4. Redundant Comments
Vd:
- Ta thấy comment trên kia là sự lặp lại thông tin của hàm, không những thế nó còn cho ta
biết
it thông tin hơn của hàm. Nếu đọc lần đầu vào comment bạn sẽ không hiểu gì.
3.3. QUY TẮC VỚI COMMENTS
5. Noise Comments, Comments sai lêch
- Nhiều khi comments thật sự là noise. Nó không thật sự cung cấp cho ta thông tin mới gì cả.
Vd:
/**
* @param title The title of the CD
* @param author The author of the CD
* @param tracks The number of tracks on the CD
* @param durationInMinutes The duration of the CD in minutes
*/
public void addCD(String title, String author, int tracks, int durationInMinutes) {
CD cd = new CD();
cd.title = title;
cd.author = author;
cd.tracks = tracks;
cd.duration = duration;
cdList.add(cd);
}
/**
* Default constructor.
*/
protected AnnualDateRule() {}
/** The day of the month. */
private int dayOfMonth;
/**
* Returns the day of the month.
*
* @return the day of the month.
*/
public int getDayOfMonth() {
return dayOfMonth;
}
3.3. QUY TẮC VỚI COMMENTS
6. Commented-Out Code
- Không bao giờ nên làm điều này.
- Người sau đọc sẽ thấy khó hiểu, và không dám xóa vì ngỡ nó quan trọng.
- Nó còn gây ra hiểu lầm. Do đó tốt nhất nên xóa đi luôn.
InputStreamResponse response = new InputStreamResponse();
response.setBody(formatter.getResultStream(), formatter.getByteCount());
// InputStream resultsStream = formatter.getResultStream();
// StreamReader reader = new StreamReader(resultsStream);
// response.setContent(reader.read(formatter.getByteCount()));
3.4. ĐỊNH DẠNG CODE (FORMATTING)
1. Vertical Formatting
2. Variable Declarations
• Instance variables
• Dependent Functions.
• Horizontal Formatting
• Indentation
• Breaking Indentation
• Team Rules
3.4. ĐỊNH DẠNG CODE (FORMATTING)
1. Vertical Formatting
- Số dòng trong 1 file tùy theo các lập trình viên viết code của họ thế nào.
- Nhưng một file nên có ít nhất 10 dòng và tối đa là 500 dòng, thường trung bình là 150-300.
- Như vậy code sẽ không quá lớn để đọc hiểu 1 file.
2. Variable Declarations
- Ta nên khai báo biến gần nơi mà nó sử dụng nhất có thể. Bởi vì hàm rất ngắn, biến local nên xuất hiện ở đầu
của hàm.
- Biến điều khiển thì nên khai báo luôn trong vòng lặp.
Vd:
3.4. ĐỊNH DẠNG CODE (FORMATTING)
3. Instance variables
- Biến thể hiện thì nên khai báo ở ngay đầu của class. Điều quan trọng ở đây là các biến
instance thì nên khai báo cùng 1 nơi, để reader có thể thể biết mà đọc.
3.4. ĐỊNH DẠNG CODE (FORMATTING)
4. Dependent Functions.
- Nếu có 1 hàm gọi hàm khác. Thì nên đặt hàm gọi trên đầu.
- Như vậy reader có thể đọc hiểu theo 1 cách tự nhiên theo top-down.
5. Horizontal Formatting
- Lời khuyên là nên để 120 ký tự là max trên 1 dòng.
- Nên để ý đến khoảng trắng giữa các ký tự.
3.4. ĐỊNH DẠNG CODE (FORMATTING)
6. Breaking Indentation
- Đôi lúc ta gặp vài trường hợp mà ta có thể phá vỡ được việc lùi đầu dòng.
Vd:
--> Mặc dù việc làm này rút gọn được số dòng code, nhưng nó lại làm cho ta khó nhìn hơn, tốt
nhất nên để dạng chuẩn như bên dưới.
3.4. ĐỊNH DẠNG CODE (FORMATTING)
7. Team Rules
- Mỗi programmer đều có formatting rule riêng. Nhưng nếu anh ta tham gia vào 1 team thì
team đó phải có rule rõ ràng và chi tiết.
- Cả nhóm cần thống nhất 1 rule. Không nên tồn tại ý kiến cá nhân rằng có người không
thích theo rule này.
- Hãy nhớ, hệ thống phần mềm tốt là tập hợp các tài liệu đọc tốt. Người đọc chấp được
style của team đó.

More Related Content

What's hot

Nhập môn BDD
Nhập môn BDDNhập môn BDD
Nhập môn BDD
Ngoc Dao
 
Kỹ năng quản lý thời gian hiệu quả
Kỹ năng quản lý thời gian hiệu quảKỹ năng quản lý thời gian hiệu quả
Kỹ năng quản lý thời gian hiệu quả
Lê Tưởng
 
Coding standards for java
Coding standards for javaCoding standards for java
Coding standards for java
maheshm1206
 

What's hot (20)

23 Time Management Techniques of Insanely Busy People
23 Time Management Techniques of Insanely Busy People23 Time Management Techniques of Insanely Busy People
23 Time Management Techniques of Insanely Busy People
 
SOLID & Design Patterns
SOLID & Design PatternsSOLID & Design Patterns
SOLID & Design Patterns
 
Nhập môn BDD
Nhập môn BDDNhập môn BDD
Nhập môn BDD
 
Javascript Clean Code
Javascript Clean CodeJavascript Clean Code
Javascript Clean Code
 
Quản lý thời gian đỉnh cao
Quản lý thời gian đỉnh caoQuản lý thời gian đỉnh cao
Quản lý thời gian đỉnh cao
 
Sử Dụng Thời Gian Hiệu Quả
Sử Dụng Thời Gian Hiệu Quả Sử Dụng Thời Gian Hiệu Quả
Sử Dụng Thời Gian Hiệu Quả
 
Clean code
Clean codeClean code
Clean code
 
Writing clean code
Writing clean codeWriting clean code
Writing clean code
 
The Art of Clean code
The Art of Clean codeThe Art of Clean code
The Art of Clean code
 
Kỹ năng quản lý thời gian hiệu quả
Kỹ năng quản lý thời gian hiệu quảKỹ năng quản lý thời gian hiệu quả
Kỹ năng quản lý thời gian hiệu quả
 
Grokking Techtalk: Problem solving for sw engineers
Grokking Techtalk: Problem solving for sw engineersGrokking Techtalk: Problem solving for sw engineers
Grokking Techtalk: Problem solving for sw engineers
 
Clean code
Clean codeClean code
Clean code
 
Introducing Clean Architecture
Introducing Clean ArchitectureIntroducing Clean Architecture
Introducing Clean Architecture
 
Time Management
Time Management Time Management
Time Management
 
PL-SQL, Cursors & Triggers
PL-SQL, Cursors & TriggersPL-SQL, Cursors & Triggers
PL-SQL, Cursors & Triggers
 
Event Driven-Architecture from a Scalability perspective
Event Driven-Architecture from a Scalability perspectiveEvent Driven-Architecture from a Scalability perspective
Event Driven-Architecture from a Scalability perspective
 
TypeScript
TypeScriptTypeScript
TypeScript
 
Coding standards for java
Coding standards for javaCoding standards for java
Coding standards for java
 
Coding standards and guidelines
Coding standards and guidelinesCoding standards and guidelines
Coding standards and guidelines
 
clean code book summary - uncle bob - English version
clean code book summary - uncle bob - English versionclean code book summary - uncle bob - English version
clean code book summary - uncle bob - English version
 

Similar to Seminar clean code

Haiphongit.com.tai lieu-learning-php-my sql
Haiphongit.com.tai lieu-learning-php-my sqlHaiphongit.com.tai lieu-learning-php-my sql
Haiphongit.com.tai lieu-learning-php-my sql
Giang Nguyễn
 
Code Refactoring: Thay đổi nhỏ - Lợi ích lớn
Code Refactoring: Thay đổi nhỏ - Lợi ích lớnCode Refactoring: Thay đổi nhỏ - Lợi ích lớn
Code Refactoring: Thay đổi nhỏ - Lợi ích lớn
Nhật Nguyễn Khắc
 

Similar to Seminar clean code (20)

How to write good code
How to write good code How to write good code
How to write good code
 
Chap 5 6 - The Art of Readable Code
Chap 5 6 - The Art of Readable CodeChap 5 6 - The Art of Readable Code
Chap 5 6 - The Art of Readable Code
 
Coding standard
Coding standardCoding standard
Coding standard
 
Vb6 16 (10)
Vb6 16 (10)Vb6 16 (10)
Vb6 16 (10)
 
Hacking de4dot for fun - Bài dịch
Hacking de4dot for fun - Bài dịchHacking de4dot for fun - Bài dịch
Hacking de4dot for fun - Bài dịch
 
Phân tích Confuser 1.9.0.0 - Constant Protection - Bản dịch
Phân tích Confuser 1.9.0.0 - Constant Protection - Bản dịchPhân tích Confuser 1.9.0.0 - Constant Protection - Bản dịch
Phân tích Confuser 1.9.0.0 - Constant Protection - Bản dịch
 
Programming
ProgrammingProgramming
Programming
 
Phong cach lap trinh c++
Phong cach lap trinh c++Phong cach lap trinh c++
Phong cach lap trinh c++
 
Phong cach lap trinh c++
Phong cach lap trinh c++Phong cach lap trinh c++
Phong cach lap trinh c++
 
10 nguyên tắc lập trình cơ bản mà mọi lập trình viên phải biết
10 nguyên tắc lập trình cơ bản mà mọi lập trình viên phải biết10 nguyên tắc lập trình cơ bản mà mọi lập trình viên phải biết
10 nguyên tắc lập trình cơ bản mà mọi lập trình viên phải biết
 
The art of readable code - Chapter I,II
The art of readable code - Chapter I,IIThe art of readable code - Chapter I,II
The art of readable code - Chapter I,II
 
Bồi dưỡng HSG Tin chuyên đề thuật toán
Bồi dưỡng HSG Tin chuyên đề thuật toánBồi dưỡng HSG Tin chuyên đề thuật toán
Bồi dưỡng HSG Tin chuyên đề thuật toán
 
Haiphongit.com.tai lieu-learning-php-my sql
Haiphongit.com.tai lieu-learning-php-my sqlHaiphongit.com.tai lieu-learning-php-my sql
Haiphongit.com.tai lieu-learning-php-my sql
 
Slide ESLint.pptx
Slide ESLint.pptxSlide ESLint.pptx
Slide ESLint.pptx
 
Phân tích Confuser 1.9.0.0 - Anti-tamper protection - Bản dịch
Phân tích Confuser 1.9.0.0 - Anti-tamper protection - Bản dịchPhân tích Confuser 1.9.0.0 - Anti-tamper protection - Bản dịch
Phân tích Confuser 1.9.0.0 - Anti-tamper protection - Bản dịch
 
Code Refactoring: Thay đổi nhỏ - Lợi ích lớn
Code Refactoring: Thay đổi nhỏ - Lợi ích lớnCode Refactoring: Thay đổi nhỏ - Lợi ích lớn
Code Refactoring: Thay đổi nhỏ - Lợi ích lớn
 
Quy tắc thiết kế giao diện và viết code C#
Quy tắc thiết kế giao diện và viết code C#Quy tắc thiết kế giao diện và viết code C#
Quy tắc thiết kế giao diện và viết code C#
 
PMMNM.docx
PMMNM.docxPMMNM.docx
PMMNM.docx
 
Yii
YiiYii
Yii
 
Store procedure
Store procedureStore procedure
Store procedure
 

Seminar clean code

  • 1. SEMINAR: CLEAN CODE PRESENTERS: NGUYEN VAN THIEU TRAN THE ANH
  • 2. 1. THẾ NÀO LÀ CLEAN CODE • Là làm tốt 1 việc • Là đơn giản và trực tiếp, giống như đọc văn xuôi được viết tốt, không làm lu mờ ý định của thiết kế nhưng vẫn đầy đủ các khái niệm trừu tượng sắc nét và đường kiểm soát đơn giản. • Là mã sạch có thể đọc, nhận biết và có ý nghĩa. • Là code sẽ có thể được đọc, và được cài thiện hoặc viết tiếp được bởi developer khác. Nó có đơn vị chấp nhận và kiểm tra. Nó có tên đầy ý nghĩa. Nó cung cấp một cách khá hơn nhiều cách để làm một điều. Nó có phụ thuộc tối thiểu, được định nghĩa một cách rõ ràng, và cung cấp một API rõ ràng và tối thiểu. • Luôn luôn giống những gì mà được viết bởi 1 người quan tâm nó thật sự • Giảm sự lặp lại, biểu cảm cao, và xây dựng ban đầu của sự trừu tượng đơn giản. • Là mã chạy tất cả các bài test để kiểm tra, mã không chứa trùng lặp mà vẫn bày tỏ đầy đủ những ý tưởng thiết kế trong hệ thống. • Là mã giảm thiếu số lượng các classes, functions, methods.
  • 3. 2. LÀM THẾ NÀO ĐỂ CODE "TRONG SÁNG" • Khi làm dự án hay lập trình bất kỳ thứ gì ta phải có các quy tắc code (code convention) • Để code trong sáng thì ta phải có quy tắc code chuẩn, rõ ràng, và làm theo được các chuẩn đó đó.
  • 4. 3. NHỮNG NGUYÊN TẮC CƠ BẢN (CODE CONVERSION) • Quy tắc đặt tên • Quy tắc với Hàm (Functions) • Quy tắc với Comments • Định dạng code (Formatting) • Quy tắc với Objects và Data Structures • Quy tắc xử lý lỗi
  • 5. 3.1. Quy tắc đặt tên 1. Sử dụng tên có ý nghĩa 2. Tránh dùng các chữ cái gây hiểu lầm, hoặc đặt tên quá ngắn gây hiểu lầm 3. Làm cho sự phân biệt có ý nghĩa. 4. Sử dụng tên phát âm được để có thể dễ nhớ, dễ hình dung. 5. Đặt tên dễ tìm kiếm trong phần mềm. 6. Tên classes và object thì nên để là danh từ và phải rõ nghĩa, không nên là động từ. 7. Tên hàm dùng prefixed để rõ nghĩa với set, get, is..
  • 6. 3.1. Quy tắc đặt tên 1. Sử dụng tên có ý nghĩa (Tên thể hiện rõ được mục đích của biến, hàm...) Vd: int d // Không có ý nghĩa gì int dayOfThisMonth // Hiểu được là số ngày trong tháng 2. Tránh dùng các chữ cái gây hiểu lầm, hoặc đặt tên quá ngắn gây hiểu lầm Vd: int o // Đây là biến o if (o == 1) a = o else b = o // Nhìn nó giống số 0 nên dễ gây hiểu lầm
  • 7. 3.1. Quy tắc đặt tên 3. Làm cho sự phân biệt có ý nghĩa. Vd: public static void copyChars(char a1[], char a2[]) { for (int i = 0; i < a1.length; i++) { a2[i] = a1[i]; } } public static void copyChars(char source[], char destination[]) { for (int i = 0; i < source.length; i++) { destination[i] = source[i]; } }
  • 8. 3.1. Quy tắc đặt tên 4. Sử dụng tên phát âm được để có thể dễ nhớ, dễ hình dung. Vd: class DtaRcrd102 { private Date genymdhms; private Date modymdhms; private final String pszqint = "102"; }; class Customer { private Date generationTimestamp; private Date modificationTimestamp;; private final String recordId = "102"; };
  • 9. 3.1. Quy tắc đặt tên 5. Đặt tên dễ tìm kiếm trong phần mềm. Vd:
  • 10. 3.1. Quy tắc đặt tên 6. Tên classes và object thì nên để là danh từ và phải rõ nghĩa, không nên là động từ. Vd: Manager, Processor, Data. (Không nên dùng) Customer, WikiPage,Account, and AddressParser. (Nên dùng) 8. Tên hàm Vd: postPayment, deletePage, save.  Tên hàm thường viết dạng cammelCase hoăc cammel_case - Dùng prefixed để rõ nghĩa với set, get, is.. Vd: string name = employee.getName(); customer.setName("thieunv"); if(paycheck.isPosted()) { ... }
  • 11. 3.2. QUY TẮC VỚI HÀM 1. Nhỏ gọn 2. Blocks và Indenting 3. Làm 1 việc . 4. Một cấp độ trừu tượng trên 1 hàm. 5. Reading code from Top to Bottom : The Stepdown Rule 6. Switch Statements 7. Sử dụng tham số của hàm 8. Command Query Separation 9. Prefer Exceptions to Returning Error Codes 10. Trích xuất try/catch block. 11. Error Handling Is One Thing 12. How Do You Write Functions Like This?
  • 12. 3.2. QUY TẮC VỚI HÀM 1. Nhỏ gọn • 1 dòng không nên quá 150 ký tự • 1 hàm không nên quá 30 dòng (1 trang giấy) 2. Blocks và Indenting • Với các block if,else không nên nối tiếp lặp quá sâu (quá 3 mức) • Lùi đầu dòng chuẩn, nên dùng tab. 3. Làm 1 việc • FUNCTIONS SHOULD DO ONE THING. THEY SHOULD DO IT WELL. THEY SHOULD DO IT ONLY. 4. Một cấp độ trừu tượng trên 1 hàm. 5. Reading code from Top to Bottom : The Stepdown Rule
  • 13. 3.2. QUY TẮC VỚI HÀM 6. Switch Statements ==> 1. Quá lớn, khi thêm loại của employee nó sẽ lớn hơn nữa. 2. Nó làm nhiều hơn 1 việc. 3. Xâm phạm nguyên tắc Single Responsibility Principle (SRP) 4. Xâm phạm nguyên tắc Open Closed Principle (OCP)
  • 14. 3.2. QUY TẮC VỚI HÀM
  • 15. 3.2. QUY TẮC VỚI HÀM 7. Sử dụng tham số của hàm - Nhiều nhất nên là 2 tham số đầu vào - Nếu có nhiều tham số hơn 2 thì nên bao chúng lại trong 1 class Vd: Circle makeCircle(double x, double y, double radius); Circle makeCircle(Point center, double radius); - Đối với tham số đầu ra cần rõ ràng, giải thích như tham số đầu vào.
  • 16. 3.2. QUY TẮC VỚI HÀM 8. Command Query Separation - Hàm nên làm việc gì đó hoặc trả lời gi đó nhưng không nên làm cả 2. Vd phổ biến: public boolean set(String attribute, String value); ==> Hàm này set giá trị của attribute là value. Nếu thành công thì trả về true. ==> Nó sẽ dẫn đến câu lệnh sau: if (set("username", "unclebob"))... ==> Nếu ta là reader. Ta sẽ tự hỏi. cái hàm set này nó làm nhiệm vụ gì? Đã là set tại sao lại cho được trong if. ==> Để fix được ta có thể đổi tên là: setAndCheckIfExists ==> Cũng không mấy khả quan. ==> Để thật sự fix được ta nên chia rẽ nhiệm vụ của chúng ra như sau: if (attributeExists("username")) { setAttribute("username", "unclebob"); ... }
  • 17. 3.2. QUY TẮC VỚI HÀM 9. Prefer Exceptions to Returning Error Codes - Trả về lỗi code từ hàm là vi phạm sự tinh tế của gọi lệnh tách biệt. if (deletePage(page) == E_OK) - Điều này không gây nhầm lẫn hay dẫn đến xử lý cấu trúc lặp. Nhưng khi trả về lỗi code, ta phải giải quyết ngay nó.
  • 18. 3.2. QUY TẮC VỚI HÀM - Thay vì phải dùng nhiều if như trên ta có thể dùng Exceptions để xử lý.
  • 19. 3.2. QUY TẮC VỚI HÀM - Một lợi thế khác của Exceptions nữa là: public enum Error { OK, INVALID, NO_SUCH, LOCKED, OUT_OF_RESOURCES, WAITING_FOR_EVENT; } ==> Khi ta có các lỗi code như trên. Sẽ rất nhiều nơi phải import enum vào. Nếu giờ Error có thêm lỗi. Ta phải thay đổi enum. ==> Sẽ dẫn đến việc các nơi khác dùng Error sẽ phải thay đổi ==> Ta phải recompile and rebuild lại. ==> Giờ nếu ta dùng Exceptions
  • 20. 3.2. QUY TẮC VỚI HÀM 10. Trích xuất try/catch block. - Bản thân try/catch đã là rất tồi. Nó bị trộn lẫn giữa lỗi và xử lý tự nhiên. - Để giúp dễ đọc, dễ hiểu và khiến code trong sáng hơn thì ta nên tách biệt thân ra hàm. Vd: - Hàm delete bên trên chỉ về xử lý lỗi. Hàm deletePageAndAllReferences chỉ về xử lý việc xóa page. xử lý lỗi không trộn lẫn. public void delete(Page page) { try { deletePageAndAllReferences(page); } catch (Exception e) { logError(e); } } private void deletePageAndAllReferences(Page page) throws Exception { deletePage(page); registry.deleteReference(page.name); configKeys.deleteKey(page.name.makeKey()); } private void logError(Exception e) { logger.log(e.getMessage()); }
  • 21. 3.2. QUY TẮC VỚI HÀM 11. Error Handling Is One Thing - Hàm làm 1 việc. Xử lý lỗi làm 1 việc. Vậy hàm xử lý lỗi không nên làm việc gì khác. - Giống vd bên trên. Trong hàm delete chỉ có duy nhất khối try/catch.
  • 22. 3.2. QUY TẮC VỚI HÀM 12. How Do You Write Functions Like This? - Viết hàm giống như viết paper, article hay bất cứ thứ gì về viết. - Đầu tiên ta nên có bản nháp, sau đó tổ chức lại, đặt tên lại, chia nhỏ nó ra, giảm sự trùng lăp... - Có thể lúc đầu ta cảm thấy làm vậy mất thời gian, nhưng khi về sau phải debug hoặc maintain thì ta mới thấy được sự lợi hại thật sự của việc viết nó clean. - Không những vậy nó còn làm ta trở thành better programmer.
  • 23. 3.3. QUY TẮC VỚI COMMENTS 1. Comment giải thích đúng rõ mục đích của nó. 2. Comment tốt và hợp lý 3. Bad Comments 4. Redundant Comments 5. Noise Comments, Comments sai lêch 6. Commented-Out Code
  • 24. 3.3. QUY TẮC VỚI COMMENTS 1. Comment giải thích đúng rõ mục đích của nó. - Comment không trang điểm cho bad code nhưng nó nói lên rằng code của bạn không clean. - Trước khi comment, ta hãy nghĩ tại sao ta lại phải cần comment. - Nếu ta thấy đoạn code lằng nhằng, khó hiểu phải cần comment. Thì ta nên giành thời gian để clean đoạn code đó thay vì ngồi comment nó. - Vd: // Check to see if the employee is eligible for full benefits if ((employee.flags & HOURLY_FLAG) && (employee.age > 65)) if (employee.isEligibleForFullBenefits()) - Thay vì phải viết comment và 1 đống logic như trên. Ta chỉ cần tống chúng vào hàm và đặt tên dễ hiểu thì code clean hơn.
  • 25. 3.3. QUY TẮC VỚI COMMENTS 2. Comment tốt và hợp lý Vd: // Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved. // Released under the terms of the GNU General Public License version 2 or later. - Khi publish dự án thì ta nên viết comment thế nào vào source để nói quyền sở hữu, version...
  • 26. 3.3. QUY TẮC VỚI COMMENTS 3. Bad Comments - Đa phần chúng ta rơi vào đây. - Có nhiều lúc ta không cần comment, nhưng ta lại cảm thấy cần comment. vậy là ta giành thời gian để viết comment. Vd: ==> Ta có thể thấy đoạn comment trên có thể có ý nghĩa nào đó với người viết, nhưng chắc chắn sẽ vô nghĩa với reader. - Ta có thể hiểu nếu rơi vào catch thì sẽ không có file nào được load. - Nhưng nếu file được load thì sẽ load ở đâu, load lúc nào (tác giả chưa nói bên trên)
  • 27. 3.3. QUY TẮC VỚI COMMENTS 4. Redundant Comments Vd: - Ta thấy comment trên kia là sự lặp lại thông tin của hàm, không những thế nó còn cho ta biết it thông tin hơn của hàm. Nếu đọc lần đầu vào comment bạn sẽ không hiểu gì.
  • 28. 3.3. QUY TẮC VỚI COMMENTS 5. Noise Comments, Comments sai lêch - Nhiều khi comments thật sự là noise. Nó không thật sự cung cấp cho ta thông tin mới gì cả. Vd: /** * @param title The title of the CD * @param author The author of the CD * @param tracks The number of tracks on the CD * @param durationInMinutes The duration of the CD in minutes */ public void addCD(String title, String author, int tracks, int durationInMinutes) { CD cd = new CD(); cd.title = title; cd.author = author; cd.tracks = tracks; cd.duration = duration; cdList.add(cd); } /** * Default constructor. */ protected AnnualDateRule() {} /** The day of the month. */ private int dayOfMonth; /** * Returns the day of the month. * * @return the day of the month. */ public int getDayOfMonth() { return dayOfMonth; }
  • 29. 3.3. QUY TẮC VỚI COMMENTS 6. Commented-Out Code - Không bao giờ nên làm điều này. - Người sau đọc sẽ thấy khó hiểu, và không dám xóa vì ngỡ nó quan trọng. - Nó còn gây ra hiểu lầm. Do đó tốt nhất nên xóa đi luôn. InputStreamResponse response = new InputStreamResponse(); response.setBody(formatter.getResultStream(), formatter.getByteCount()); // InputStream resultsStream = formatter.getResultStream(); // StreamReader reader = new StreamReader(resultsStream); // response.setContent(reader.read(formatter.getByteCount()));
  • 30. 3.4. ĐỊNH DẠNG CODE (FORMATTING) 1. Vertical Formatting 2. Variable Declarations • Instance variables • Dependent Functions. • Horizontal Formatting • Indentation • Breaking Indentation • Team Rules
  • 31. 3.4. ĐỊNH DẠNG CODE (FORMATTING) 1. Vertical Formatting - Số dòng trong 1 file tùy theo các lập trình viên viết code của họ thế nào. - Nhưng một file nên có ít nhất 10 dòng và tối đa là 500 dòng, thường trung bình là 150-300. - Như vậy code sẽ không quá lớn để đọc hiểu 1 file. 2. Variable Declarations - Ta nên khai báo biến gần nơi mà nó sử dụng nhất có thể. Bởi vì hàm rất ngắn, biến local nên xuất hiện ở đầu của hàm. - Biến điều khiển thì nên khai báo luôn trong vòng lặp. Vd:
  • 32. 3.4. ĐỊNH DẠNG CODE (FORMATTING) 3. Instance variables - Biến thể hiện thì nên khai báo ở ngay đầu của class. Điều quan trọng ở đây là các biến instance thì nên khai báo cùng 1 nơi, để reader có thể thể biết mà đọc.
  • 33. 3.4. ĐỊNH DẠNG CODE (FORMATTING) 4. Dependent Functions. - Nếu có 1 hàm gọi hàm khác. Thì nên đặt hàm gọi trên đầu. - Như vậy reader có thể đọc hiểu theo 1 cách tự nhiên theo top-down. 5. Horizontal Formatting - Lời khuyên là nên để 120 ký tự là max trên 1 dòng. - Nên để ý đến khoảng trắng giữa các ký tự.
  • 34. 3.4. ĐỊNH DẠNG CODE (FORMATTING) 6. Breaking Indentation - Đôi lúc ta gặp vài trường hợp mà ta có thể phá vỡ được việc lùi đầu dòng. Vd: --> Mặc dù việc làm này rút gọn được số dòng code, nhưng nó lại làm cho ta khó nhìn hơn, tốt nhất nên để dạng chuẩn như bên dưới.
  • 35. 3.4. ĐỊNH DẠNG CODE (FORMATTING) 7. Team Rules - Mỗi programmer đều có formatting rule riêng. Nhưng nếu anh ta tham gia vào 1 team thì team đó phải có rule rõ ràng và chi tiết. - Cả nhóm cần thống nhất 1 rule. Không nên tồn tại ý kiến cá nhân rằng có người không thích theo rule này. - Hãy nhớ, hệ thống phần mềm tốt là tập hợp các tài liệu đọc tốt. Người đọc chấp được style của team đó.