Wow, you could fill a book on this subject. And some people do.
The guidelines for coding in Java, my language of choice, are fairly fluid but there is usually a general consensus of opinion on most topics. Here are a few:
Always declare variables as final.
I only explained this one last night so it’s still fresh, and yes, in a sense it’s not a variable if it’s final.
The idea is that if a variable can have its value changed it can be confusing and lead to bugs. If every variable is final you have only to know what value it was initialized with. There is a peculiarity when this style is adopted (and eclipse will do this for you if you configure it) – anything non-final appears like a warning, particularly useful for parameters which should remain constant through a method invocation. Imagine a function working on width and height that changes the height halfway through.
Making all variables final used to be tough as some people believed in having only one return point in a method. This argument has been answered in the Java world by Kent Beck, one of the founders of XP / Agile and creator of the JUnit framework. Single Entry Single Exit, he says,
was to prevent the confusion possible when jumping into and out of many locations in the same routine. It made good sense when applied to FORTRAN or assembly language programs written with lots of global data where even understanding which statements were executed was hard work … with small methods and mostly local data, it is needlessly conservative.
Use static methods sparingly.
This didn’t matter a great deal in the past and in projects without unit tests will be less important. If you don’t have unit tests but do have business logic then you may have bigger problems.
Originally, static methods were ok as they indicated a stateless method or function. This sounds good because you don’t need to create an object to provide you some functionality – just call a method on a class. The problem with this approach is that you cannot override static methods. It’s not very ‘object oriented’ – there is no object doing the work, just a hard-coded reference to the implementing method. No abstraction – this is the implementation. Always. Well, you can override this using some mocking frameworks with functionality generally considered for ‘legacy code.’ This should tell you all you need to know. If you are hard-wiring this method into your production code but need different behavior (in tests) and achieve it with compiler tricks instead of polymorphism, some would consider this to be missing the point. I’ve seen people do very elaborate things and get into very long arguments about how to avoid using polymorphism. This seems to be missing the point on purpose. The same people will prefer untested private methods over tested package-private methods and good luck with that.