If you add new configuration options to a program, it can often have tons of ripple effects in terms of getting the options to where they need to be acted upon. There are three basic ways to deal with this that I'm aware of:
Pass all configuration settings to the parts of your program that need them explicitly as primitives. This is the most explicit way and the way that decouples things the most. The downside is that this is both verbose and brittle.
Make the most frequently used configuration settings global/static. This is the simplest way but introduces action at a distance, hinders testability and assumes that the configuration truly is global (that you'd only want one configuration at any given time).
Make a configuration class/struct that contains all the configuration options for the whole program or for each major concern within the program, and then pass this around explicitly. This is less explicit than (1) but more explicit than (2). If you want to change a setting just for one function call, you can clone the config object and change this one value. This is useful in both testing and in practice. However, you still end up potentially passing tons of info to a function that it doesn't need and changing a value in the config class/struct can still cause action at a distance.
Would you consider (3) a pattern or an anti-pattern? If it's an anti-pattern, what do you do instead?