Using a method to create a new instance of an object rather than using the new keyword to call the constructor directly.
This decouples the two classes by allowing the higher level class to change from creating an instance to requesting an instance of the lower level class. The advantage of decoupling the two classes by changing the nature of the relationship between the two of them. The higher level class no longer creates an instance of the lower level class. Instead this pattern means that the higher level class requests an instance of an interface..
This presents a number of advantages;
- It allows for object pooling of the lower level class. Some objects may be expensive to create, consume a lot of memory, or may require that there are a limited set of them in existence. In these cases a pool of objects can be created and they can be passed out to consumers.
- It allows for the higher level class class to not know about what implementation of an interface or abstract class is provided. This allows for the consuming class to adhere to the Open Closed Principle by having functionality provided by the implementation. Meaning that the higher level class can differ the the decision about what approach to take until certain information is available rather than being forced to decide during it's instantiation.
- Encapsulating object creation within a package allows the the higher level class to be ignorant of the creation details of the lower level class, minimising the size of the interface presented by a module.
- Abstracting functionality to be decided on at runtime.
- Object pooling to minimise the creation of and maximise the reuse of objects that are expensive to create or consume a lot of memory.
- Implementing the singleton pattern.
- Creating a connection pool for constrained resources.
- Simplifying repeated object creation for tests.
- Code that is too flexible by abstracting away all of it's functionality can stop being single responsibility and no longer have a single reason to change.
- Object pooling with non read only objects can lead to race conditions around multi threading and asynchronous programming models.
- Applications may have unexpected side effects if the lower level classes do not adhere to the Liskov Substitution Principle and have unexpected behaviour for the methods they're implementing.