Just a very quick entry today, motivated by some weekend examinations, contemplations, reflections, and probably some other *tions that I can't remember.
I often come across code that has assorted extensibility hooks built right into it. And even nice iron-clad reliability hooks. Indeed Microsoft guidelines suggest these practices and they are surely not evil ones.
However, too much of a good thing is not always so good.
When you are designing a library, whether for use by others or just as service code within your own application, you must consider what reasonable expectations the callers of your library will have. If we're talking about a very simple service that your audience will expect to be blazingly fast you will doom them to fall into pit of bad performance -- which they will have to climb out of -- if you fail to live up to those expectations. That's a great way to kill all the productivity benefits you thought you were delivering by creating this library.
To be a little more concrete: if you are writing a worker function which would need only a few clocks to do it's main job, you should proceed very carefully before adding assorted generalizations that would increase it's cost to the dozen cycles range -- that's a factor of 5 on a low level worker function. Often a very bad idea as the extra cost would be surprising to callers.
To get the right features in your library at a good cost, you frequently have to consider which services and durability should be present at which level of your abstraction stack. Features to consider include:
- thread safety
- full argument scrubbing
- extensibilty (via subtyping or otherwise)
- error recovery
Which level of your stack is the appropriate place to introduce these? Which levels should rely on the functions of those levels above them? Which should rely on what is below? Which should only have those tests which are present in all verifiable managed code? Which services would be surprising by their presence or absence?
There is no one answer to these questions but a good framework/application will have given them due consideration and balanced them to get the desired mix. Many choices are possible. Our design guidelines speak to how to introduce all of these notions when you decide they are warranted.
Put the right services at the right level.