Friday, June 12, 2015

Good practices for Architects, Tech Leads & Developers

As developers we often get so excited about starting work on a new project that we omit some basic planning steps that can come back to haunt us in the future. This post discusses a few practices that can help with proper planning and keeping the build process smooth, code quality good and less stress for all. 

Things might differ for you based on team size, structure, timeline, technology etc but keeping these in mind when starting a project certainly help in the long run. I have used .NET for examples but these should be applicable to any framework / project.

1. Continuous Integration: Code should be built continuously using a CI environment. Build should execute on each code check-in or at least once a day. It should execute all unit tests and send out alerts when something fails. This encourages frequent and complete code check-ins as well as encourages developers to think of the solution as a whole instead on just focusing on some component they are working on. Examples: Jenkins, Team City

2. Standardize on frameworks: Whenever possible projects should use standard 
frameworks, coding practices, tools which are agreed upon as best practice by the team and are properly documented. Something’s that can be standardized are Backend frameworks for caching, exception handling, encryption, data access, authentication etc. Front end frameworks for both web and mobile development.

3. Documentation: Avoid producing large documentation that is disconnected from the codebase and becomes obsolete very quickly. Instead focus on writing clean self-documented code. If done properly the codebase can then be used to generate documentation on the fly.

4. Document and follow good coding habits. Some examples:

  • When handling strings use concat, string formatter and StringBuilder instead of manipulating them in memory.
  • Don’t hardcode values that are reused in multiple places and might change. Use constants or configuration values.
  • When using disposable objects (streams, file handlers etc) make sure you dispose them correctly, even if there is an exception. In C# the using statement should be used in these cases. Also implement IDisposable in your own classes whenever cleanup is required.


5. Don’t create everything from scratch: Use community / built-in code and frameworks whenever possible instead of custom writing your own implementations whenever possible. These are well tested and widely used and will cause fewer headaches for you, plus handing off the code to someone else is easier. For example use Enterprise Library, NHibernate, Entity Framework, Elmah, NLog etc to instead of rolling out your own implementation.

6. Unit testing your code should not be an afterthought and should be built into the project timeline. I can’t stress the importance of properly unit tested code and how much this will improve code quality, catch issues earlier and keep the team honest.

7. Dependency Injection: Using DI instead of manual object creation all over your code will really help with testing and maintenance in the long run. 
Examples: Ninject, Autofac, StructMap 

8. Concatenate and minify all resource (javascript, css etc) files. This increases  performance by having the browser make less requests, smaller download sizes, caching and parsing the code only once. Also use sprites for images. There are some very good tools available for this including .NET bundling, grunt tasks etc

9. Don’t over architect. This is just something to be aware of. Sometimes we tend to over complicate solutions by adding multiple layers, abstractions, tiers, unnecessary design patterns into our solutions. Keeping it simple can be better than designing for every possible future enhancement. I guess am saying weigh in the pros and cons of added complexity based on the project in hand.

10. Keep your web based systems stateless as much as possible. You should discourage server side sessions and any kind of state management. Each request should include all needed data. Using this pattern we have completely automated horizontal scalability making applications scale in and out very quickly while only paying for the resources when we need them.

11. Think Security: All team members should be aware and of the OWASP Top 10 issues as most of them can be avoided very easily with good design

12. Exception Handling and Logging: Have a well-defined exception handling and logging strategy. Using frameworks like Elmah, NLog, Enterprise Library. Having a good exception handling and logging strategy will give you a lot of insight into your codebase when actual users start using it. In most cases we are able to notice issues and fix them before they propagate to the live environments. It will also save you a lot of time debugging environmental issues later.

13. Code reviews are highly encouraged. These should be considered as learning and improving exercise. Generally you do a few hour-long sessions and focus on good and bad coding patterns instead of individual pieces of code.

Do share any insights you have gained or good practices you use.