The goal of the Plugin pattern is to provide a centralized configuration runtime to promote modularity and scalability. The criteria that determines which implementation to select can be the environment, or anything else, like account type, user group, etc. The factory is just one way to create the desired plugin instance based on the selection criteria.
Implementation Selection Criteria
How your factory reads the selection criteria (environment state) depends on your implementation. Some common approaches are:
Command-Line Argument
, for example, CLI calls from different CI/CD pipeline stages can pass a dev/staging/production argument
YAML Config Files
could be deserialized into an object or parsed
Class Annotations
to tag each implementation with an environment
Feature Flags
, e.g. SaaS like Launch Darkly
Dependency Injection
framework like Spring IoC
Product Line Engineering
software like Big Lever
REST Endpoint
, e.g. http://localhost/test/order can create a test order object without notifying any customers
HTTP Request Parameter
, such as a field in the header or body
Dependency on Factory
Since the DomainObject
calls the factory to create an object with the desired implementation, the factory will be a dependency of the domain object. That being said, the modern approach is to use a dependency injection (DI) library (Guice, Dagger) or a framework with built-in DI (Spring DI, .Net Core). In these cases, there still is a dependency on the DI library or framework, but not explicitly on any factory class.
Note: The Plugin
design pattern described on pp.499-503 of PEAA
was written by Rice and Foemmel, not Martin Fowler.