However, not always instantiating a dependency in the constructor leads to a Control Freak anti-pattern, it depends on the nature of the dependency, as explained in the following.
There are two types of dependencies:
- Volatile: A volatile dependency is something that depends on the external world, it requires some environment setup, such as a database or network access. If it uses random numbers or depends on time, or when the dependency is not ready because it's still in development, it will eventually be replaced. An effect of a volatile dependency is that it creates strong coupling; if it doesn't let us test or extend the dependent class, it means it is volatile.
- Stable: A dependency is stable if it's already there, it will not break software depending on it when a new version is installed, and you never need to replace that class with another. A good example of a stable dependency is the one in the Foundation framework. Ironically, the dependency containers also fall into this category and they should be considered stable dependencies. Only stable dependencies can be initiated in the constructor, whereas volatile dependencies must be injected.