Ways to make libraries that don't stink

Since the short list format seems popular, here are 20 things to consider when writing a component (assembly or COM or framework) for other people to use. Some are blindingly obvious. Others are perhaps less so.

1. If you don’t say that something can’t be done then people will try to do it. I have seen score of horrible designs. When I gently suggested that the design was unwise, I always get told "But it doesn’t say that we shouldn’t do that". I would advise that usage advice should contain recommendation and prohibitions. Yes, I know that Microsoft doesn’t do that.

2. A thing should be made as simple as possible and no simpler.

3. Never expose any implementation details that you can hide. Trust me. It will pay off when you redesign the implementation.

4. Assume that the developer who is using your component hates you and wants to break your code. If you are not paranoid enough about error checking then he will have cause to hate you.

5. When developing, use lots of assert statements. They compile away to nothing.

6. If two things always have to be done in the same order then maybe they are not two things but one.

7. Don’t make users poll. Let them block with a timeout. Then they can poll if they want by using a short timeout.

8. Try to present a conventional interface. Your ideas may be fresh and original but you have to meet the expectations of the user.

9. Give good error information. Returning False with no other information is not helpful. Your user won’t know your code like you do. Logging errors should be cheap since they *should* be exceptional. The performance of code that habitually errors is a low priority.

10. Build good test harnesses when unit testing. All real world code spends longer in maintenance than any other phase. The harness will be useful long after ship date. With released code, a serious bug can cost thousands per minute. If the harness gets you a solution ten minutes early then it costs minus several thousand to produce.

11. Keep symbols for everything always. Compile in release mode with symbols. The code is just as fast.

12. Remember that compiling for small code often gives faster code than compiling for fast code. Processor caches have changed the game.

13. Don’t assume that the code does the same thing when optimised. Always test. Optimised code is faster because it does less stuff.

14. As well as testing for correct behaviour, test for incorrect behaviour. Does it leak? Does it free other people’s handles? Tools such as the application compatibility toolkit can be helpful.

15. Test in life-like environments. If your user-base is on Windows 98 then you need to test under that as well. We try to make things compatible. How much money would you like to bet that we didn’t miss anything?

16. Remember that someone will have to support this code and if you are unlucky then that person could be you. Best make it easy to support.

17. Fight DLL hell. Add a function that returns your version number. You can’t make the client check but you can make it easier.

18. If a value is reserved for future expansion then document that it MUST be 0 or null. Check that it is. Error if it isn’t. Alternatively, expect applications to fall over when you start using it for something.

19. Add logging code that is off by default. You can conditionally compile it out if performance is an issue

20. Remember that there is always one more bug

Signing off

Mark