Wednesday, May 4, 2011

Best Practices

I had to write this out for work, but I felt it would probably be useful for others. While this was written mainly in reference to .NET development, most of these points translate to development in general.
  1. Reuse code as best as you can. If you know there is something that was used to fix a problem in another project make it generic and common. We want as few lines of code in the code base as is neccesary to get the job done.
  2. ReSharper is probably one of your best friends when developing code in .NET (Resharper is available here)
  3. Code Repositories should not be considered optional. Check in early, check in often.
  4. Continuous Integration should be your religion, and if your code breaks the build, FIX IT BEFORE YOU LEAVE. Other people like to get work done too.
  5. TDD is mandatory - write tests *before* you develop functionality
    • Resharper is excellent for this and helps tremendously
    • If you have to temporarily disable a test use the Ignore attribute with a reason. This makes it easier to track, and allows us to see a print out on CI so we can make fun of you for not fixing the test later.
    • TDD will be your friend if you ever have to refactor the code. You will thank yourself later. (And you will refactor the code. OVER AND OVER AND OVER)
  6. When Resharper makes a suggestion for code clarity as a general rule follow the suggestion. The one exception to this is when a LINQ statement makes the code less legible.
  7. Cyclomatic complexity is bad. Keep nested loops and if statements to a minumum unless ABSOLUTELY neccesary.
  8. Optimal method length is 5 - 10 lines (This will also make it much easier to wrap tests around.)
  9. Use guard statements to simplify methods.
  10. SOLID is not optional (Definition is below)
    • Single Responsibility - object should have only a single responsibility
    • Open Closed Principle - classes should be open for extension, closed for modification
    • Liskov Substitution Principle - Methods that use a base class should also be able to use classes derived from that base class
    • Interface Segregation Principle - many client specific interfaces are better than one general purpose interface (i.e. don't use huge-ass interfaces)
    • Dependency Inversion Principle - Depend on Abstractions, not on Absolutes i.e. Use a base class in the parameter definition for a method rather than a derived class. (see Dependency Injection which is a great tool for TDD)
  11. DRY - Don't Repeat Yourself (EVER!)
  12. Mocking is fun. Especially the coding kind for tests. ( I personally like MOQ)
  13. usewhitespacetoenhancereadability
  14. Do not use regions. PERIOD. If you need to hide something, your method is too long.
  15. If you have to write comments on every other line, your code probably isn't very readable.
    • use descriptive variable names
    • use smaller private methods with descriptive names.
    • EXCEPTION: jokes in the code are ok.
    • use comments to explain "why" something is done that way, the code should explain "what" is being done.
For further reading:
* CLR via C# revision 3 (Jeffrey Richter)
* Test-Driven Development in Microsoft .NET (James W. Newkirk and Alexei A. Vorontsov)
Design Patterns: Elements of Reusable Object-Oriented Software (Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides)