1) The first constructor is using static dependency injection. This pattern allows classes derived from Provider
to be injected for testing purposes, or as an alternative to the default Provider
implementation at runtime. Provider
itself may be a service locator - that depends on what objects or services it actually provides.
In this example, though, Provider
is injected into Consumer
. That's dependency injection, not service locator (which requires a class to determine it's own dependencies, causing close coupling between them). Thanks to the dependency injection, it doesn't matter to the Consumer
class if it gets the default implementation of Provider
, or a class derived from it. The classes could be more loosely coupled if a) Provider
was an interface, and b) if client code always determined which instance to inject, instead of having a default.
2) Personally, I think static providers are a code smell, but they do work, and may be completely appropriate in your code-base. Ideally, Provider
should be a singleton factory injected by a dependency injection framework. We have static providers in the code-base I work on at the moment, and I'm slowly replacing them in this way. Consumer
should have a single constructor - the second one.