The answer is, it kinda depends.
Basically there are two schools of thought; small, optimal shaders for everything and the uber-shader camp.
The small shaders are just that; do one thing, and do it well. Uber-shaders either control their functionality at runtime through uniforms, or compile into a bunch of different shaders through preprocessor macros (and/or generated shader sources).
The optimal solution is probably neither, but some kind of hybrid. Perhaps a few uber-shaders or uber-shaders combined with specialized shaders for some cases.
Small shader
Pros:
- Likely to be faster/more optimal
- Does just what you want it to do
- Can do weird, custom stuff easily
Cons:
- Easily gets out of hand, especially when the number of features grows
- Probably more work, unless you have a very small number of shaders
Uber-shader
Pros:
- Everything in one place
- More artist-friendly (using feature A with feature X for the first time doesn't necessarily require coder time)
Cons:
- Longer shader compile times
- Less optimal results (esp. if uniforms are used to switch features on/off)
- May be more difficult to debug/optimize