Udostępnij za pośrednictwem


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

Comments

  • Anonymous
    October 08, 2005
    Good list. To help out with point 2, Steven Clark, a usability engineer in VS Core working on API usability, has some tips. You can find his blog at http://blogs.msdn.com/stevencl

    Point 1 is also extremely valid. Yesterday, I saw some code in the community that if used as per expectations would work fine. However, if it were used in an unexpected use case then there would be a memory leak, the dev was calling new in a set accessor method and assigning the returned pointer to a class attribute. If they were then to call the setter method twice the first address retrieved from new is lost. So, I would expand on point 1 and say also design for use cases that you don't expect, as it's likely someone will try them.

  • Anonymous
    October 10, 2005
    All good points. I am glad that you are finding the blog worth reading.

  • Anonymous
    May 28, 2009
    PingBack from http://paidsurveyshub.info/story.php?title=marklon-ways-to-make-libraries-that-don-t-stink

  • Anonymous
    June 15, 2009
    PingBack from http://edebtsettlementprogram.info/story.php?id=23167