Best practices evolve. The best practices for writing software are no exception. Here are a number of conventions and practices that used to be considered good in the past, together with the new ways of doing things, and why.
Yesterday: Using i, j, and k as for-loop index names.
Today: Use intention-revealing names like sourceIndex and lastUsedBufferPosition. Also, nested loops are a sure sign that the method is too long and violates the “do one thing” rule. So, extract each inner loop to its own method.
Yesterday: Automatically writing code in interface/impl pairs, just in case you decide later that you need to swap in a second implementation.
Today: Writing just a single class and relying on an automated refactoring tool to extract the interface later if/when it’s needed.
Yesterday: Automatically writing public, pass-thru getters and setters on private fields, just in case you’ll want to insert logic later.
Today: Making the fields public and relying on an automated refactoring tool to generate a getter and/or setter later if/when it’s needed.
Yesterday: Lots of inheritance.
Today: Less inheritance and more aggregation/composition and delegation.
Yesterday: Super classes than can be instantiated.
Today: Super classes are always abstract. Only the “leaf nodes” of an object hierarchy should be instantiated.
Yesterday: Configuration data in external files (.xml, .properties)
Today: Configuration data in java source (where the refactoring tools can find them)