Tuesday, July 27, 2010

Programmers - Do's and Don'ts

The art of writing code
How do we write beautiful code. Every time I start to write an application/module, no less than a week, I fell the code smells and want to re-write it. Guess, every technologist would feel the same (a better one will smell it in 2 days).

So what is beautiful code?

Apart from scripting a solid working code we strive for the following 4 items
  1. Readability
  2. Maintainability
  3. Speed of development
  4. Beauty
Ask this question to 4 different technologists, you will get 4 different answers. As the saying goes “Beauty lies in the eye of beholder” beautiful code is nothing more than "simple code". Simplicity is the argument of writing a workable code. Think about some of the source code you had read in the past from as many websites, open sources……you liked them because it was simple and easy to understand. May be you'd appreciate obfuscated code, but may never want to write or like it.
Many people opine constriction of 20 lines of code into 5 lines is beauty. For few others it is comments, comments and more comments while for some others it is OO approach (make 20 functions/classes even for a simple solution) and there is another savage group that would infest then entire project with frameworks. All of them are right in their perspective. But simplicity is the mother of all.

Rule for programmers
I came across this adage in some book….and I loved it “Always leave the camp ground cleaner than you found”. There are a lot of variations of this including MJ’s song – Make the world a better place for tomorrow. Same rules apply to programmers too.
Check-in module/code that is better & cleaner then when you checked out. If you come across some code that smells, don't hesitate to refactor. you may break few things, that’s alright. Effort should be made to correct the issue, instead of hiding rotten code. Agile development has become a defacto standard in the industry. Software development has become all the more difficult when executed from different geographical locations. Every resource needs to be on their toes and should make sure they check-in better code all the time.
“Care not just for your code, but for others too”. Refactor is a term that perhaps is not much appreciated by management people, many consider it as a drag to SW development. But I have never seen anything developed right the first time or even the second time. It take at least 6 to 7 attempts to get it right. Refactor will some people wild. It may make you unpopular among PM’s…so be it, that’s how you start and then when things fall in place the same people will hail you for the good work. Care for the code not for other living objects that causes hemorrhage to Software development

Code Refactor
Tell me about it…..Through out my life I have done this and I will do it in my present & furture projects too. One of the architects I really love to work with Chuck Wagner did that to me. He’s an amazing guy. I can talk about him all day, but here’s what my 5 cents on Refactor and how/when you do it
  1. Take stock of how much is the change: There are no easy ways to do it. It take a while to figure out dependencies. I’ll come to that a little later (a mathematical way to find out dependencies…….PM’s will be very happy to know that there’s a way to capture this).
  2. Scrap and start all over: Though I love to do this, avoid it in all sense, because you never know the problems encountered, may be you have a different team that will have a different understanding of things. But if the code is bad, even if there is a stiff resistance, don’t care, blast the code and start all over. I have never know any project that has not be re-written. If code is not re-written, then the code stinks. Art of programming naturally comes to people who can sense the stink and immediately rewrite it to make it a scent. If you are not one among them, then develop it
  3. Continuous Changes: Always make the changes incrementally. Unit tests are the way to go here. Even if you decide to blast entire code, try to integrate yours with the old one and make progress on incremental basis
  4. One of the factors that I always fancied for re-writing is technology. It took me a lot of time to understand that new/fancy technology is no solution to refactor. Perhaps problems can be more. Programming language is just an expression for requirement. Unless there is a compelling change, don’t rewrite in different language. I’ll certainly talk about functional programming in a little while, until then remember this…..
First Check your code before blaming others
I guess it was in my college days that I read a book on software Engineering that talked about how debugging should proceed. It read some what close to this. If Qa/customer reports a bug, then go with the thought process that your code has a bug. Keep debugging until it's crystal clear that the problem manifests from someone else code. But in practise, it's always been the other way. Talk to people how many times architects and managers have bad worded team or a team member only to know in a little while that it was thier code that cause chaotic behavior. And the same hold good before you blame a programming language or OS.

Choose tools that are really needed
There are a lot of assembled tools out there in the open world - libraries, controls, utilities, frameworks. There are a number of good reasons why we want to use them
  1. As we develop application, complexity increases by multi-fold. It make more sense for developers to keep their focus as much as possible on business and domain-models, and consume infrastructure code from open sources
  2. Widely used components are more stable and well tested
  3. Lower development costs
  4. It's less intensive to use an available good quality product
Inspite of all these advantages, we may want to dwell on the following, before we decide to take on
  1. Check to see if the product/library suits your architecture, if not you may end up doing a lot of hacks
  2. Most of the tools require external configuration, make sure your application is alright to use the configuration methodologies. For e.g. You application may not like .config/.xml files hanging around or .txt/.ini configurations may not fit the architecture
  3. If you are developing applications for vendors, make sure you make it transparent to the clients on the open s/w you consume. You don;t want any surprises at the last minute
  4. Make sure licensing issues are covered and appropriate agreements are signed before the application installation
In short consume tools that are necessary. Don't use tools because you like them or for their cheap availability. It's a dangerous trap out there....

Code is the best documentation
Traditional approaches of having a detailed design before development seems to have become talk of the past. World is moving at rapid pase (of course a day still has only 24 hours). There is no time to make a detailed design and keep the design in sync with application development. With Agile development it's become all the more impossible. Code & requirements change like a wild river on rampage.
Best way to handle things is to follow standards of coding practises and comments. Modern IDE's have remarkable capability to generate documentation out of comments. Alternatively, we can write macros that will do the job.
This does not mean we need verbose documentation, with explanation of each line. This will bloat the code and nobody will like to look into a code that's got too many lines. Keep it simple and clear. If you are not able to explain what the code intends to do in 2 -3 lines, it mean the code needs a refactor.
If no one can understand your code, then it has only 2 meanings - You are a genius or your code sucks. It more often turns out to be the second case.

Coding standards across board
Writing code is always an art, great programmers take a lot of pride in writing their code. Pride does not come out of false ego, but because of the quality of the code that has been churned out. Here are some simple standards that I pulled out from the best of the developers
  1. If you are writing OO programs, after the completion of each (public) function the state of the instance should be as expected
  2. Using global variables across modules will increase the coupling of application and take you away from standard. Slowly, bad code creeps in
  3. Each variable should have smallest possible scope
  4. Make return values immutable where ever necessary. This is something that I have learnt after I burnt my figures in onsite-offshore model. A small hole in the system can become mighty in no time.
  5. Code should be so simple that it requires no documentation
  6. If you have nested section, break them in to multiple functions. Don't hesitate to do recursions
  7. Restrict the number of parameters passed to a function. Less than 5 is always a good number
  8. public setters should be avoided. Use constructors to set values for fields
  9. Classes should be defined with behaviors.
  10. Add comments and usage where ever necessary
  11. Make it a habit to read others code. There is no better teacher then reading someone else's code.
  12. Never copy someone's code
Error Handling
There are a number of ways by which errors are handled in applications. Improper handling of error code is just like a fracture caused by a freak accident, not handled on time. Taking pain killers for a fracture can hold it for a maximum of 8 hours but the pain will eventually take over after 8 hours.
Errors are reported in different ways from with in the application
Return codes
If there was an error with the function, we communicate it to the caller by different return values.

Exceptions
Modern day languages handle issues through exception handlers. What do you do with catch'ed/thrown exceptions are more important
Not handling error at appropriate time will make the code brittle/fragile. Application becomes insecure because a failure may cause the system to hang around in an unstable condition.

Handling errors
There are normally different ways adopted by people to handle errors. Error handling should essentially be a part of design in every project. Tracing and error handling should be well thought out and should be designed in such a way that all components in the application have a way to log errors that is easy to interpret. Avoid using EventLog's unless you are alright with a customer calling you in the middle of night about some error messages in EventLog of OS.

Learn, learn and learn....
I had chance to work on quite a few technologies in quick succession, I have hardly had time to read about a technology, before I get on with project. In this process I have seen a lot of people sulk and quit. I am always of the thought that you should keep learning else you might become a dinosaur struck in the same job. We should make ourselves marketable and the only way out is to learn.
Some of the ways I do (learning this from my idols and well-wishers) are
  1. Books - The best way
  2. Subscribe for magazines and Blogs
  3. If you a staunch technologist, try out code from BLOGS and books, instead of just going through them. There is no bigger truth than code
  4. Always have a mentor and follow him. Thinking and having no mentor will make you the top most person. Sooner than later EGO can kill your progress
  5. Learn things in depth. If you are using a library or framework, make sure you read through the complete documentation. Understand the product completely. That will help you use it better
  6. Share your knowledge through talks, BLOGS, etc...this way people will ask you questions that you may not have thought of. That will make your understanding of the technology even better
  7. Attend conferences. They are expensive, but worth the money
  8. Take exams. There is no better way to test yourself. Certification is not for your resume or to prate about. It will make you read in-depth technology that you will otherwise ignore. Take certifications for the sake of knowing technology and nothing more
Technology keeps changing, if you are left out, then you will end up way behind.

Deploy utility should be a part of build
Installation/Deployment is the first piece QA/Managers/clients see. Make sure the fiurst step keeps performing well. Also this gives a frontal view of the application. Identify how the application needs to be installed - whether this will be downloaded from internet/FTP, does it require auto update process, etc. Have we included all the .dlls, .jar, .exe and other modules. Is the help module integrated, can we uninstall the application and get rid of all our files.
By having deployment as one of the fore-runner application, we can also identify issues that arise out of repeated installation/uninstallation, version related issues, DB creating/removal issues, registry issues and a raft of others. If you feel deployment is very simple and does not need any attention, there are a lot of projects in the past that have thought the same way and ended up spending a week to identify and resolve issues in the last minute. Don't be one among them. Do it as the first step and keep it updated.

Bust those 3 myths
Great programmers are born
In my little experience in this industry, I have more often seen people give up and say we need a super human called "Architect" or a "Technical Specialist" to resolve this issue. That's so untrue. Industry study has clearly reveled that attributes and qualities acquired from birth contribute less than 10% of industrial giants. Rest 90% of stalwarts have stood tall by their determination, dedicated and hard-work. Agreed, that if one is born intelligent he is gifted, but that does not mean it's only "he" who can solve all issues. If you have talk to the people you idolize/drool over find ways they have come up to the current incubation. More often you will hear same response. They all follow a pattern called "focus", good "decision making", "reading" and putting what you read into "practice". One of the greatest cricketer (Cricket is one of the most preferred sport in south Asia) by name "Rahul Dravid" once said, it takes "10,000 deliveries to make your shot natural to your body, and another 10, 000 shots to play it fluently". He's called one of the gifted cricketer's in the industry. If you can practice same number of deliveries then you can become Rahul Dravid. This saying hold's ground for developers too. If you want to be a wonderful programmer, practice things over and over again, until it becomes natural. Have you ever wondered why it does not take anytime for you to create a class, function, variables (in your preferred programming languages), however there are other gray areas in the same language that keeps slipping form our mind. It's all practice. Do it 10, 000 times, you will become the master. You want to become an expert don't ask you idol for solution, learn the technique by which he has arrived at the solution, accumulate it and in time you can become one like him or may be better than him

Need training on this programming language
When ever there 's a new project on some unfamiliar technology, developers sulk or say they need training. Let's not discuss on the sailplane experience a developer undergoes for the request. I have often wondered how I can call myself a "professional", if I keep asking for training. Here are some of the other professionals in the world, they pay for their professional learning and survival
  1. Doctors
  2. Mechanical Engineers (of course they receive some minimal training - only if they badly need one)
  3. Scientists
If you want to be a true professional, hit the web, work out samples, look for PODCASTS, tutorials and learn it on your own. That's the hallmark of a true professional. Of course share with others, this way you get benefited more than you anticipated.

Taking managers for granted
Many programmers have felt and said that PM's are a drain in projects. In my opinion I'd say developers have never really understood the value PM's bring to the project (provided they are efficient managers). In my experience I have seen a lot of managers inspire developers. It's because they analyze team dynamics and team's output better than architects. It's a known fact that Architects are more often lost in their own virtual world of development and delivery. PM's are the magicians with magic wand, who bring out the best in developers by variety of means -encouragement, appreciation, honest feedbacks, escalations...... I can write pages on some of the best PM's I have worked and involved with - Sam Wilson, Aravind Ramamurthy, to site a few. PM's identify issues and cracks before they happen, bring it to Architects/clients notice. They call for help for resources (Architects ego refuses to take help from others and live in the false-world of making the delivery in spite of gazillion failures and issues......come on don't deny this). Learn to appreciate PM's and the value they bring to the project.

Never change Production code
All development have a deployment process and deployment is done at multiple levels and stages, before product is released.
  1. Developer system - Daily builds and code changes are tested on developer system.
  2. Developer Intergration Server - Code changes from Source Integrity is continuously build and deployed in this server. This will contain all the latest code changes from all developers in the team. If all unit and integration test pass, release gradually moves into QA server
  3. QA server - Application in this server is tested from edge to edge by QA team and if all is fine, release is done to staging server
  4. Stage Server - This is almost like production environment. Normally code is allowed to reside here for (at least) 24 hours. Rapid testing is done before it finally make it's way into Production server.
  5. Production Server - Ultimate server.

I have seen a few projects where-in people debug on production server and fix code in PRODUCTION server. That's a strict NO-NO. Who knows what holes your fix may have introduced. Code changes made directly in production server is done without QA certification. This cause a huge delta between the code tested by QA in QA, STAGING and PRODUCTION server. That's a mockery of process. Avoid any such hasty fixes. If production release code has got issues, block the suspect operation, follow a proper release procedure. It's a safe life for you, your company and client. That's a much better life.

Keep removing that code
More often people hesitate to touch code that works, even though it may smell. Application undergoes a lot of changes from the time it was conceived, and not to forget the number of people who made changes at later point in time. Though the functionality is achieved, code may contain some pieces that are not needed. JUST REMOVE IT. Colloquial term for it is YAGNI - Your aren't gonna need it. When the module for perceived initially a lot of thought was given and constructed in certain ways. It was festooned with extra bells that may not be need any longer. Take them off, application will start to breath easy and will make it even easier for maintenance. Make sure your unit tests pass for these, else you have broken the functionality.