24
Coding best practices The Jaxara IT Ltd. Mahmudul Haque Azad

Coding Best Practices

  • Upload
    mhazad

  • View
    3.054

  • Download
    2

Embed Size (px)

Citation preview

Page 1: Coding Best Practices

Coding best practices

The Jaxara IT Ltd.

Mahmudul Haque Azad

Page 2: Coding Best Practices

(C) The Jaxara IT Ltd 2

Coding… Anybody can write code. With a few months of programming experience, you can

write 'working applications'. Making it work is easy, but doing it the right way requires more work, than just making it work.

Believe it, majority of the programmers write 'working code', but not ‘good code'. Writing 'good code' is an art and you must learn and practice it.

Following are the characteristics of good code. Reliable Maintainable Efficient

If your code is not reliable and maintainable, you (and your company) will be spending lot of time to identify issues, trying to understand code etc throughout the life of your application.

Page 3: Coding Best Practices

(C) The Jaxara IT Ltd 3

Naming Conventions and Standards

The terms Pascal Casing and Camel Casing are used throughout this document. Pascal Casing - First character of all words are Upper Case and other characters

are lower case. Example: BBackackCColorolor

Camel Casing - First character of all words, except the first word are Upper Case and other characters are lower case.

Example: bbackackCColorolor

Page 4: Coding Best Practices

(C) The Jaxara IT Ltd 4

Naming Conventions and Standards (cont.)1. Use 1. Use Pascal casing for casing for ClassClass names

public class public class HHelloelloWWorldorld{{

......}}

22. Use Pascal casing for MethodMethod names void void SSayayHHelloello(string (string namename)){{

......}}

3. 3. Use Camel casing for variablesvariables and method parametersmethod parameters int int ttotalotalCCountount = 0;= 0;void void SSayayHHello(ello(string string name)name){{

string string ffullullMMessageessage = "Hello " = "Hello " + + namename;;......

}}

4. 4. Use the prefix “Use the prefix “II” with Camel ” with Camel Casing for for interfacesinterfaces ( Example: IEntity ) )

Page 5: Coding Best Practices

(C) The Jaxara IT Ltd 5

Naming Conventions and Standards (cont.)5. Use5. Use meaningful meaningful, descriptive words to name variables. Do not use abbreviations., descriptive words to name variables. Do not use abbreviations. GoodGood

stringstring addressaddressintint salarysalary

Not Good:Not Good:stringstring namnamstringstring addraddrintint salsal

6. 6. Do not useDo not use single character variable names like i, n, s etc. Use names like index, temp single character variable names like i, n, s etc. Use names like index, temp One exception in this case would be variables used for iterations in loops: One exception in this case would be variables used for iterations in loops:

forfor ( ( intint i = 0; i < count; i++ ) i = 0; i < count; i++ ){{

......}}

If the variable is used only as a counter for iteration and is not used anywhere else in the loop, If the variable is used only as a counter for iteration and is not used anywhere else in the loop, many people still like to use a single char variable (i) instead of inventing a different suitable name.many people still like to use a single char variable (i) instead of inventing a different suitable name.

Page 6: Coding Best Practices

(C) The Jaxara IT Ltd 6

Naming Conventions and Standards (cont.)7. Do not use underscores (_) for local variable names. 7. Do not use underscores (_) for local variable names.

8. All member variables must be prefixed with underscore (_) so that they can be 8. All member variables must be prefixed with underscore (_) so that they can be identified from other local variables.identified from other local variables.

9. Do not use variable names that resemble keywords.9. Do not use variable names that resemble keywords.

10. Prefix 10. Prefix booleanboolean variables, properties and methods with “ variables, properties and methods with “isis” or similar prefixes.” or similar prefixes.Ex: Ex: private bool _isFinishedprivate bool _isFinished

11. File name should match with class name.11. File name should match with class name. For example, for the class HelloWorld, the file name should be HelloWorld.cs (or, For example, for the class HelloWorld, the file name should be HelloWorld.cs (or,

HelloWorld.vb) HelloWorld.vb) 12. Use Pascal Case for file names.12. Use Pascal Case for file names.

Page 7: Coding Best Practices

(C) The Jaxara IT Ltd 7

Naming Conventions and Standards13. Use appropriate prefix for the UI elements so that you can identify them from the rest of the variables. A brief list is given below. Since .NET has given several controls, you may have to arrive at a complete list of standard prefixes for each of the controls (including third party controls) you are using.

Example:

Page 8: Coding Best Practices

(C) The Jaxara IT Ltd 8

Naming Conventions and Standards

1. Use TAB for indentation. Do not use SPACES. Define the Tab size as 4.1. Use TAB for indentation. Do not use SPACES. Define the Tab size as 4.

2. Comments should be in the same level as the code (use the same level of indentation). 2. Comments should be in the same level as the code (use the same level of indentation).

Good:Good:// Format a message and display// Format a message and displaystringstring fullMessage = "Hello " + name; fullMessage = "Hello " + name;DateTimeDateTime currentTime = DateTime.Now; currentTime = DateTime.Now;stringstring message = fullMessage + ", Thanks " message = fullMessage + ", Thanks " MessageBoxMessageBox.Show ( message );.Show ( message );Not Good:Not Good:// Format a message and display// Format a message and display stringstring fullMessage = "Hello " + name; fullMessage = "Hello " + name; DateTimeDateTime currentTime = DateTime.Now; currentTime = DateTime.Now; stringstring message = fullMessage + ", Thanks ” message = fullMessage + ", Thanks ” MessageBoxMessageBox.Show ( message );.Show ( message );

Page 9: Coding Best Practices

(C) The Jaxara IT Ltd 9

Naming Conventions and Standards3. Curly braces ( 3. Curly braces ( {}{} ) should be in the same level as the code outside the braces. ) should be in the same level as the code outside the braces.

4. There should be one and only one single blank line between each method inside the class. 4. There should be one and only one single blank line between each method inside the class.

5. The curly braces should be on a separate line and not in the same line as 5. The curly braces should be on a separate line and not in the same line as if, forif, for etc. etc. Good:Good:

if ( ... )if ( ... ){{

// Do something// Do something}}

Not Good:Not Good: if ( ... )if ( ... ) {{

// Do something// Do something}}

Page 10: Coding Best Practices

(C) The Jaxara IT Ltd 10

Naming Conventions and Standards6. Use one blank line to separate logical groups of code. 6. Use one blank line to separate logical groups of code. Good:Good:

boolbool SayHello ( SayHello ( stringstring name ) name ){{stringstring fullMessage = "Hello " + name; fullMessage = "Hello " + name;DateTimeDateTime currentTime = currentTime = DateTime.DateTime.Now;Now;

stringstring message = fullMessage + ", the time is : " + currentTime.ToShortTimeString(); message = fullMessage + ", the time is : " + currentTime.ToShortTimeString();MessageBoxMessageBox.Show ( message );.Show ( message );

ifif ( ... ) ( ... ){{// Do something// Do something// ...// ...returnreturn falsefalse;;}}returnreturn truetrue;;}}

Not Good:Not Good:boolbool SayHello ( SayHello (stringstring name) name){{stringstring fullMessage = "Hello " + name; fullMessage = "Hello " + name;DateTimeDateTime currentTime = currentTime = DateTimeDateTime.Now;.Now;stringstring message = fullMessage + ", the time is : " + currentTime.ToShortTimeString(); message = fullMessage + ", the time is : " + currentTime.ToShortTimeString();MessageBoxMessageBox.Show ( message );.Show ( message );ifif ( ... ) ( ... ){{// Do something// Do something// ...// ...returnreturn falsefalse;;}}returnreturn truetrue;; }}

Page 11: Coding Best Practices

(C) The Jaxara IT Ltd 11

Naming Conventions and Standards7. Use a single space before and after each operator and brackets. 7. Use a single space before and after each operator and brackets.

Good: Good: if if ( showResult == ( showResult == truetrue ) ){{

forfor ( ( intint i = 0; i < 10; i++ ) i = 0; i < 10; i++ ){{

////}}

}}

Not Good:Not Good: ifif(showResult==(showResult==truetrue)){{

forfor((intint i= 0;i<10;i++) i= 0;i<10;i++){{

////}}

}}

8.8. Keep private member variables, properties and methods in the top of the file and public members Keep private member variables, properties and methods in the top of the file and public members in the bottom.in the bottom.

Page 12: Coding Best Practices

(C) The Jaxara IT Ltd 12

Indentation and SpacingIndentation and Spacing9. Use 9. Use #region#region to group related pieces of code together. If you use proper grouping using to group related pieces of code together. If you use proper grouping using #region#region, the page should like this when all definitions are collapsed., the page should like this when all definitions are collapsed.

Page 13: Coding Best Practices

(C) The Jaxara IT Ltd 13

Good Programming Good Programming practicespractices

1. Avoid writing very long methods. A method should typically have 1~25 lines of code. If a method 1. Avoid writing very long methods. A method should typically have 1~25 lines of code. If a method has more than 25 lines of code, you must consider re factoring into separate methods. has more than 25 lines of code, you must consider re factoring into separate methods.

2. Method name should tell what it does. Do not use mis-leading names. If the method name is 2. Method name should tell what it does. Do not use mis-leading names. If the method name is obvious, there is no need of documentation explaining what the method does. obvious, there is no need of documentation explaining what the method does.

Good:Good: voidvoid SavePhoneNumber ( SavePhoneNumber ( stringstring phoneNumber ) phoneNumber ){{

// Save the phone number.// Save the phone number.}}

Not Good: Not Good: // This method will save the phone number.// This method will save the phone number.voidvoid SaveDetails ( SaveDetails ( stringstring phoneNumber ) phoneNumber ){{

// Save the phone number.// Save the phone number.}}

Page 14: Coding Best Practices

(C) The Jaxara IT Ltd 14

Good Programming Good Programming practicespractices3. A method should do only 'one job'. Do not combine more than one job in a single 3. A method should do only 'one job'. Do not combine more than one job in a single method, even if those jobs are very small. method, even if those jobs are very small.

Good: Good: // Save the address.// Save the address.SaveAddress ( address );SaveAddress ( address );

// Send an email to the supervisor to inform that the address is updated.// Send an email to the supervisor to inform that the address is updated.SendEmail ( address, email );SendEmail ( address, email );

voidvoid SaveAddress ( SaveAddress ( stringstring address ) address ){{

// Save the address.// Save the address.// ...// ...

}}

voidvoid SendEmail ( SendEmail ( stringstring address, address, stringstring email ) email ){{

// Send an email to inform the supervisor that the address is changed.// Send an email to inform the supervisor that the address is changed.// ...// ...

}}

Not Good: Not Good: // Save address and send an email to the supervisor to inform that // Save address and send an email to the supervisor to inform that

// the address is updated.// the address is updated.SaveAddress ( address, email );SaveAddress ( address, email );void SaveAddress ( void SaveAddress ( stringstring address, address, stringstring email ) email ){{

// Job 1.// Job 1.// Save the address.// Save the address.// ...// ...// Job 2.// Job 2.// Send an email to inform the supervisor that the address is changed.// Send an email to inform the supervisor that the address is changed.// ...// ...

}}

Page 15: Coding Best Practices

(C) The Jaxara IT Ltd 15

Good Programming Good Programming practicespractices4. Use the c# or VB.NET specific types (aliases), rather than the types defined in4. Use the c# or VB.NET specific types (aliases), rather than the types defined in System namespace.System namespace.

int int age; (not age; (not IIntnt1616))stringstring name; (not name; (not SStringtring))objectobject contactInfo; (not contactInfo; (not OObjectbject))

5. Do not hardcode numbers. Use constants instead. Declare constant in the top of5. Do not hardcode numbers. Use constants instead. Declare constant in the top of the file or in a separate constant file and use it in your code.the file or in a separate constant file and use it in your code. However, using constants are also not recommended. You should use the constantsHowever, using constants are also not recommended. You should use the constants in the config file or database so that you can change it later. Declare them as in the config file or database so that you can change it later. Declare them as constants only if you are sure this value will never need to be changed.constants only if you are sure this value will never need to be changed.

6. Do not hardcode strings. Use resource files i.e. a separate constant file.6. Do not hardcode strings. Use resource files i.e. a separate constant file.

7. Convert strings to lowercase or upper case before comparing. This will ensure the string will match 7. Convert strings to lowercase or upper case before comparing. This will ensure the string will match even if the string being compared has a different case.even if the string being compared has a different case.if ( name.ToLower() == “john” )if ( name.ToLower() == “john” ){{

//…//…}}

Page 16: Coding Best Practices

(C) The Jaxara IT Ltd 16

Good Programming Good Programming practicespractices9. 9. Always watch for unexpected values. For example, if you are using a parameter with 2 possible Always watch for unexpected values. For example, if you are using a parameter with 2 possible

values, never assume that if one is not matching then the only possibility is the other value.values, never assume that if one is not matching then the only possibility is the other value.

Good:Good:ifif ( memberType == eMemberTypes.Registered ) ( memberType == eMemberTypes.Registered ){{

// Registered user… do something…// Registered user… do something…}}else ifelse if ( memberType == eMemberTypes.Guest ) ( memberType == eMemberTypes.Guest ){{

// Guest user... do something…// Guest user... do something…}}elseelse{{

// Un expected user type. Throw an exception// Un expected user type. Throw an exceptionthrow new Exception (“Un expected value “ + memberType.ToString() + “’.”)throw new Exception (“Un expected value “ + memberType.ToString() + “’.”)// If we introduce a new user type in future, we can easily find // If we introduce a new user type in future, we can easily find

// the problem here.// the problem here.}}

Not Good:Not Good:if if ( memberType == eMemberTypes.Registered )( memberType == eMemberTypes.Registered ){{

// Registered user… do something…// Registered user… do something…}}elseelse{{// Guest user... do something…// Guest user... do something…// If we introduce another user type in future, this code will // If we introduce another user type in future, this code will // fail and will not be noticed.// fail and will not be noticed.}}

Page 17: Coding Best Practices

(C) The Jaxara IT Ltd 17

Good Programming Good Programming practicespractices10. Use String.Empty instead of “”10. Use String.Empty instead of “”

Good:Good:If ( name == String.Empty )If ( name == String.Empty ){{

// do something// do something}}Not Good:Not Good:If ( name == “” )If ( name == “” ){{

// do something// do something}}

11. Do not make the member variables public or protected. Keep them private and expose 11. Do not make the member variables public or protected. Keep them private and expose public/protected Properties. public/protected Properties.

12. The event handler should not contain the code to perform the required action. Rather call another 12. The event handler should not contain the code to perform the required action. Rather call another method from the event handler.method from the event handler.

13. Do not programmatically click a button to execute the same action you have written in the button 13. Do not programmatically click a button to execute the same action you have written in the button click event. Rather, call the same method which is called by the button click event handler.click event. Rather, call the same method which is called by the button click event handler.

14. Never hardcode a path or drive name in code. Get the application path programmatically and use 14. Never hardcode a path or drive name in code. Get the application path programmatically and use relative path.relative path.

Page 18: Coding Best Practices

(C) The Jaxara IT Ltd 18

Good Programming Good Programming practicespractices15. Use enum wherever required. Do not use numbers or strings to indicate discrete values. 15. Use enum wherever required. Do not use numbers or strings to indicate discrete values. Good: Good:

enumenum MailType MailType{{Html,Html,PlainText,PlainText,AttachmentAttachment}}voidvoid SendMail ( SendMail (stringstring message, message, MailTypeMailType mailType) mailType){{switchswitch ( mailType ) ( mailType ){{casecase MailType.Html: MailType.Html:// Do something// Do somethingbreakbreak;;casecase MailType.PlainText: MailType.PlainText:// Do something// Do somethingbreakbreak;;casecase MailType.Attachment: MailType.Attachment:// Do something// Do somethingbreakbreak;;defaultdefault::// Do something// Do somethingbreakbreak;;}}}}

Not Good: Not Good: voidvoid SendMail ( SendMail (stringstring message, message, stringstring mailType) mailType){{switchswitch ( mailType ) ( mailType ){{casecase "Html": "Html":// Do something// Do somethingbreakbreak;;casecase "PlainText": "PlainText":// Do something// Do somethingbreakbreak;;casecase "Attachment": "Attachment":// Do something// Do somethingbreakbreak;;defaultdefault::// Do something// Do somethingbreakbreak;;}}}}

Page 19: Coding Best Practices

(C) The Jaxara IT Ltd 19

Good Programming Good Programming practicespractices16. Error messages should help the user to solve the problem. Never give error messages like "Error 16. Error messages should help the user to solve the problem. Never give error messages like "Error

in Application", "There is an error" etc. Instead give specific messages like "Failed to update in Application", "There is an error" etc. Instead give specific messages like "Failed to update database. Please make sure the login id and password are correct.“database. Please make sure the login id and password are correct.“

17. Show short and friendly message to the user. But log the actual error with all possible information. Show short and friendly message to the user. But log the actual error with all possible information. This will help a lot in diagnosing problems.This will help a lot in diagnosing problems.

18. Do not have more than one class in a single file.18. Do not have more than one class in a single file.

19. Avoid having very large files. If a single file has more than 1000 lines of code, it is a good 19. Avoid having very large files. If a single file has more than 1000 lines of code, it is a good candidate for refactoring. Split them logically into two or more classes.candidate for refactoring. Split them logically into two or more classes.

20. Avoid public methods and properties, unless they really need to be accessed from outside the 20. Avoid public methods and properties, unless they really need to be accessed from outside the class. Use “class. Use “internalinternal” if they are accessed only within the same assembly.” if they are accessed only within the same assembly.

Page 20: Coding Best Practices

(C) The Jaxara IT Ltd 20

Good Programming Good Programming practicespractices21. Avoid passing too many parameters to a method. If you have more than 4~5 parameters, it is a 21. Avoid passing too many parameters to a method. If you have more than 4~5 parameters, it is a

good candidate to define a class or structure.good candidate to define a class or structure.

22. If you have a method returning a collection, return an empty collection instead of null, if you have 22. If you have a method returning a collection, return an empty collection instead of null, if you have no data to return. For example, if you have a method returning an ArrayList, always return a valid no data to return. For example, if you have a method returning an ArrayList, always return a valid ArrayList. If you have no items to return, then return a valid ArrayList with 0 items. This will make ArrayList. If you have no items to return, then return a valid ArrayList with 0 items. This will make it easy for the calling application to just check for the “count” rather than doing an additional it easy for the calling application to just check for the “count” rather than doing an additional check for “null”.check for “null”.

23. If you are opening database connections, sockets, file stream etc, always close them in the 23. If you are opening database connections, sockets, file stream etc, always close them in the finallyfinally block. This will ensure that even if an exception occurs after opening the connection, it block. This will ensure that even if an exception occurs after opening the connection, it will be safely closed in the will be safely closed in the finallyfinally block. block.

24. Declare variables as close as possible to where it is first used. Use one variable declaration per 24. Declare variables as close as possible to where it is first used. Use one variable declaration per line.line.

Page 21: Coding Best Practices

(C) The Jaxara IT Ltd 21

Good Programming Good Programming practicespractices25.25. Use StringBuilder class instead of String when you have to manipulate string objects in a loop. The Use StringBuilder class instead of String when you have to manipulate string objects in a loop. The

String object works in weird way in .NET. Each time you append a string, it is actually String object works in weird way in .NET. Each time you append a string, it is actually discarding the old string object and recreating a new object, which is a relatively expensive discarding the old string object and recreating a new object, which is a relatively expensive operations.operations.

Consider the following example:Consider the following example:publicpublic stringstring ComposeMessage ( ComposeMessage (stringstring[] lines)[] lines){ {       stringstring message = message = stringstring.Empty; .Empty;       for (for (intint i = 0; i < lines.Length; i++) i = 0; i < lines.Length; i++)      { {             message += lines [i]; message += lines [i];       }}      returnreturn message; message;}}

In the above example, it may look like we are just appending to the string object ‘message’. But what is happening in In the above example, it may look like we are just appending to the string object ‘message’. But what is happening in reality is, the string object is discarded in each iteration and recreated and appending the line to it.reality is, the string object is discarded in each iteration and recreated and appending the line to it.

If your loop has several iterations, then it is a good idea to use StringBuilder class instead of String object.If your loop has several iterations, then it is a good idea to use StringBuilder class instead of String object.See the example where the String object is replaced with StringBuilder.See the example where the String object is replaced with StringBuilder.

publicpublic stringstring ComposeMessage ( ComposeMessage (stringstring[] lines)[] lines){{        StringBuilderStringBuilder message = message = newnew StringBuilderStringBuilder();();        for (for (intint i = 0; i < lines.Length; i++) i = 0; i < lines.Length; i++)        {{              message.Append( lines[i] ); message.Append( lines[i] );         }}        returnreturn message.ToString(); message.ToString();}}

Page 22: Coding Best Practices

(C) The Jaxara IT Ltd 22

Good Programming Good Programming practicespractices

26.26. Do not use session variables throughout the code. Use session variables only within Do not use session variables throughout the code. Use session variables only within the classes and expose methods to access the value stored in the session the classes and expose methods to access the value stored in the session variable. A class can access session usingvariable. A class can access session using System.Web.HttpCOntext.Current.SessionSystem.Web.HttpCOntext.Current.Session

27. Do not store large objects in session. Storing large objects in session may consume 27. Do not store large objects in session. Storing large objects in session may consume lot of server memory depending on the number of users.lot of server memory depending on the number of users.

28. Always use style sheet to control the look and feel of the pages. Never specify font 28. Always use style sheet to control the look and feel of the pages. Never specify font name and font size in any of the pages. Use appropriate style class. This will help name and font size in any of the pages. Use appropriate style class. This will help you to change the UI of your application easily in future. Also, if you like to support you to change the UI of your application easily in future. Also, if you like to support customizing the UI for each customer, it is just a matter of developing another style customizing the UI for each customer, it is just a matter of developing another style sheet for themsheet for them

Page 23: Coding Best Practices

(C) The Jaxara IT Ltd 23

Good Programming Good Programming practicespractices29. Never access database from the UI pages. Always have a data layer class which performs all the 29. Never access database from the UI pages. Always have a data layer class which performs all the

database related tasks. This will help you support or migrate to another database back end database related tasks. This will help you support or migrate to another database back end easily.easily.

30. Use try-catch in your data layer to catch all database exceptions. This exception handler should 30. Use try-catch in your data layer to catch all database exceptions. This exception handler should record all exceptions from the database. The details recorded should include the name of the record all exceptions from the database. The details recorded should include the name of the command being executed, stored proc name, parameters, connection string used etc. After command being executed, stored proc name, parameters, connection string used etc. After recording the exception, it could be re thrown so that another layer in the application can catch recording the exception, it could be re thrown so that another layer in the application can catch it and take appropriate action.it and take appropriate action.

Page 24: Coding Best Practices

(C) The Jaxara IT Ltd 24

Thank you!