)救中国研究院 10 Things You Can Do To Write Better Code 写好代码的十个秘诀 林斌 Development Manager Microsoft research. China
1 10 Things You Can Do To Write Better Code 写好代码的十个秘诀 林斌 Development Manager Microsoft Research, China
流代码的特性 )救中国研究院 鲁棒- Solid and robust code 简洁- Maintainable and Simple Code 高效- Fast Code 流 简短- Small code 代码 共享- Re-usable Code 可测试- Testable Code 可移植- Portable code 2
2 一流代码的特性 • 鲁棒 - Solid and Robust Code • 简洁 - Maintainable and Simple Code • 高效 - Fast Code • 简短 - Small Code • 共享 - Re-usable Code • 可测试 - Testable Code • 可移植 - Portable Code 一流 代码
Why is this code bad? Microsoft 软中国研究院 void MyGirlFriendFunc(CORP DATA InputRec, int Crntotr EMP DATA EmpRec, float EstimRevenue, float YTDRevenue, int Screen, int ScreenY, COLOR TYPE newColor COLOR TYPE Prevcolor, STATUS TYPE status, int ExpenseType) I int ii for (i=l; 1<100, 1++) InputRec revenue[i] =0; for(主=1;主<100;i++) InputRec expense [i]= CorpExpense[il i UpdateCorpDatabase(EmpRec)i EstimRevenue =YTDRevenue*4. 0/(float)CrntQtr NewColor Recolor S七atus .f(ExpenseType== 1) for (i=l; i<12;i++) Profit[il Revenue [i]-Expense Typel[i] else if (ExpenseType = 2) Profit[i] Revenue [i] Expense. Type2[ili else if (ExpenseType==3)( Profit[i] =Revenue [i] Expense. Type3[i]
3 Why is this code bad? void MyGirlFriendFunc(CORP_DATA InputRec, int CrntQtr, EMP_DATA EmpRec, float EstimRevenue, float YTDRevenue, int ScreenX, int ScreenY, COLOR_TYPE newColor, COLOR_TYPE PrevColor, STATUS_TYPE status, int ExpenseType) { int i; for (i=1; i<100; i++) InputRec.revenue[i] = 0; for (i=1; i<100; i++) InputRec.expense[i]= CorpExpense[i]; UpdateCorpDatabase(EmpRec); EstimRevenue =YTDRevenue*4.0/(float)CrntQtr; NewColor = PreColor; Status = Success; if (ExpenseType== 1) for (i=1;i<12;i++) Profit[i] = Revenue[i]-Expense.Type1[i]; else if (ExpenseType == 2) Profit[i] = Revenue[i] - Expense.Type2[i]; else if (ExpenseType==3) { Profit[i] =Revenue[i] - Expense.Type3[i]; }
Why is this code bad? Microsoft 软中国研究院 void MyGirlFriendFunc(CORP DATA InputRec, int Crntotr EMP DATA EmpRec, float EstimRevenue, float YTDRevenue, int Screen, int ScreenY, COLOR TYPE newColor COLOR TYPE Prevcolor, STATUS TYPE status, int ExpenseType) I int ii for (i=l; 1<100, 1++) InputRec revenue[i] =0; for(主=1;主<100;i++) InputRec expense [i]= CorpExpense[il i UpdateCorpDatabase(EmpRec)i EstimRevenue =YTDRevenue*4. 0/(float)CrntQtr NewColor Recolor status Success i f(ExpenseType== 1) for (1=1:1<12:1++) Profit[il Revenue [i]-Expense. Typel[il else if (ExpenseType = 2) Profit[i] Revenue [i] Expense. Type2[ili else if (ExpenseType==3)( Profit[i] =Revenue [i] Expense. Type3[i]
4 Why is this code bad? void MyGirlFriendFunc(CORP_DATA InputRec, int CrntQtr, EMP_DATA EmpRec, float EstimRevenue, float YTDRevenue, int ScreenX, int ScreenY, COLOR_TYPE newColor, COLOR_TYPE PrevColor, STATUS_TYPE status, int ExpenseType) { int i; for (i=1; i<100; i++) InputRec.revenue[i] = 0; for (i=1; i<100; i++) InputRec.expense[i]= CorpExpense[i]; UpdateCorpDatabase(EmpRec); EstimRevenue =YTDRevenue*4.0/(float)CrntQtr; NewColor = PreColor; Status = Success; if (ExpenseType== 1) for (i=1;i<12;i++) Profit[i] = Revenue[i]-Expense.Type1[i]; else if (ExpenseType == 2) Profit[i] = Revenue[i] - Expense.Type2[i]; else if (ExpenseType==3) { Profit[i] =Revenue[i] - Expense.Type3[i]; }
Because 软中国研究院 Bad function name Maintainability Crash if CrntQtr equals 0- Robustness No comments - Maintainability Unnecessary for loop- Performance The function has no single purpose Reusa bility Bad layout -Simplicity Maintaina bility None testable if ExpenseType is 1-Testability Many more: too many arguments, abuse usage of 100, 4.0, etc, un-use parameters, none documented parameters ●。●
5 Because… • Bad function name – Maintainability • Crash if CrntQtr equals 0 – Robustness • No comments – Maintainability • Unnecessary for loop – Performance • The function has no single purpose – Reusability • Bad layout – Simplicity & Maintainability • None testable if ExpenseType is 1 – Testability • Many more: too many arguments, abuse usage of 100, 4.0, etc, un-use parameters, nonedocumented parameters…
代码高手十大秘诀 以中国研究院 1.集百家之长,归我所用 Follow basic Coding Style 2.取个好名字- Use Naming Conventions 3.凌波微步,未必摔跤- Evil gotos? Maybe Not 4.先发制人,后发制于人- Practice Defensive Coding 5.见招拆招,滴水不漏- Handle the error Cases: They will occur!
6 代码高手十大秘诀 1. 集百家之长, 归我所用- Follow Basic Coding Style 2. 取个好名字 - Use Naming Conventions 3. 凌波微步, 未必摔跤 - Evil goto’s? Maybe Not… 4. 先发制人, 后发制于人- Practice Defensive Coding 5. 见招拆招, 滴水不漏 - Handle The Error Cases: They Will Occur!
代码高手十大秘诀(Cont) )救中国研究院 6.熟习剑法刀术,所向无敌- Learn win32 API Seriously 7.双手互搏,无坚不摧-Test, but dont stop there 8.活用段言-Use,don' t abuse, assertions 9.草木皆兵,不可大意- Avoid Assumptions 10.最高境界,无招胜有招- Stop writing So much code
7 代码高手十大秘诀 (Cont.) 6. 熟习剑法刀术, 所向无敌- Learn Win32 API Seriously 7. 双手互搏, 无坚不摧 - Test, but don’t stop there 8. 活用段言 - Use, don’t abuse, assertions 9. 草木皆兵, 不可大意 - Avoid Assumptions 10. 最高境界, 无招胜有招- Stop writing so much code
1.集百家之长,归我所用 Follow Basic Coding Style Microsoft 软中国研究院 Your code may outlive you or your memory Think about the maintainer Comment your code File header Function Header Inline Commenting Pick a good name for your functions and variables Set Tab/Indent to 4 characters Align your code Less arguments
8 • Your code may outlive you or your memory! • Think about the maintainer • Comment your code – File Header – Function Header – Inline Commenting • Pick a good name for your functions and variables • Set Tab/Indent to 4 characters • Align your code! • Less arguments 1. 集百家之长, 归我所用 - Follow Basic Coding Style
Coding Style(Cont) )救中国研究院 Use all uppercase with underscores for macro define MY MACRO NUMBER 100 Declare all your variables at the start of function Avoid hard coding constant. Use enum or macro define MY MAX LENGTH 1024 User braces for one line code 工E(mf工 nitia1ized) hr = S OK; Limit the length of a single function
9 Coding Style (Cont.) • Use all uppercase with underscores for macro. #define MY_MACRO_NUMBER 100 • Declare all your variables at the start of function. • Avoid hard coding constant. Use enum or macro. #define MY_MAX_LENGTH 1024 • User braces for one line code If (m_fInitialized) { hr = S_OK; } • Limit the length of a single function
Spot the defect 以中国研究院 DWORD status NO ERROR LPWSTR ptri Status f( &ptr if( Status isnot NO ERROR or ptr is NULL goto cleanup i
10 Spot the defect DWORD Status = NO_ERROR; LPWSTR ptr; Status = f( ..., &ptr ); if( Status isnot NO_ERROR or ptr is NULL ) goto cleanup;