“Objects in a program should be replaceable
with instances of their subtypes
without altering the correctness of that program.”
—R. Martin
This principle proposes that any sub-type must conform and acts like its super-type, without defrauding its clients. The Gof principle of «programming to interface, not to implementation» means that clients should call base objects, but at runtime the execution is performed by concrete sub-types. Those sub-types should conform with the client call expectations, avoiding the override of base code behavior, and respect the contract of the method (pre-conditions, invariants, and post-conditions, Design by Contract principle).
In the example, the Client directly calls the AbstractClass via a Factory or a Factory Method (GoF pattern), the Factory will return the ConcreteClass instance that the configured settings determine. This concrete instance should behave as expected for the client of the abstraction.
The above construct or ensemble is a very common layout for object-oriented solutions.
The application of this pattern implies other requirements for implementation:
- Declare all class variables as abstracts or interfaces
- Class variables should only be of interfaces, abstract classes or primitive types
- Declare function arguments as abstract or interfaces
- Return abstracts of interface types from methods
- Use factories and factory methods to load concrete classes
- Use external settings configuration (via files or any other external resources) to retrieve concrete classes specifications.