Here is a list of miscellaneous development tips which we find useful and for some quite original (we haven't listed the well known and spread ones). Some are language specific and some are general purpose.
It is a well known best practice that dependencies in between components should be made as minimum as possible (this avoids the object spaghetti reproducing on the component level). Furthermore, what should absolutely be avoided (except in specific cases) are mutual dependencies between two components.
What is less well known or noticed is the difference between static dependencies (as represented on a UML class diagram for example) and dynamic dependencies (as represented on a UML object diagram for example).
The classical dependency minimisation considerations (as the ones above) generally are implicitly aimed at the static model. This is often confusing because developers and designers try to apply them both on static and dynamic models. This in turn fails because these rules don't apply dynamically. Then the designers totally dismiss the whole dependency constraints and end up with intermangled components which are both statically and dynamically dependent.
The solution to this is to apply the dependency rules as meant to be, that is on the static model. The dynamic dependencies (for example business object change notification for GUI level components) must be handled by appropriate design patters, such as subject/observer.
These dynamic dependencies do not generate static dependencies, therefore it is possible to maintain clean dependency paths on the static model while allowing advanced interactions dynamically.
Memory management in C++
It's always surprising to hear people state that C++ lacks memory management automation (in particular garbage collection). This comment is often made when comparing to JAVA or .NET managed code.
However, our position is that this is mostly untrue. In most cases (that is around 99%) we consider memory management in C++ (and in particular garbage collecting) to be very good.
The main rule to benefit of C++'s strength is to never create situations where a 'delete' will be required. This is done by using STL templates and allocating in 'automatic storage' at the correct scope.
This of course requires thinking and good design, but is very efficient. You should therefore avoid allocating with 'new', and prefer automatic allocation.
In the rare cases (rare relative to the number of objects created in an application) where this is not possible (because of polymorphism for example) you should use the 'auto_ptr' template or something similar to handle automatic deleting of dynamically allocated objects.
Only comment code if you have no better solution. This is always a quite surprising best practice when first presented, as it is against mainstream practices. What this says is that the best thing is that the code is self explanatory via the architecture, naming, organisation, indentation, parameters, granularity, ... If the code seems to require commenting to make it understandable, it is better first to try to change this. Only if you don't manage to make the code understandable should you comment it. If you comment well written code you'll just have the impression you're repeating what's already there without adding anything.
Note that this applies at the code level. The overall system requires explanations about its functioning. This is probably the most important part about documenting software (with the above) and is most often not done (often because no one really has a clear vision of what's happening due to poor design, and automatic doc generators like javadoc work at source code level). The best is when this can be done with simple metaphors for example, which with a few simple statements describe the overall operation of the system (the details are then found in the clear code). Otherwise this can be achieved textually or with UML diagrams for example.