Program To An Interface, Not An Implementation

Depend on abstractions rather than concrete classes. Design collaborations between objects around shared interfaces or abstract types so that you can swap implementations freely without changing the code that uses them.

Examples:

  • A Company class that directly instantiates Designer and Developer objects is tightly coupled. Extract an Employee interface with a doWork() method, make each employee type implement it, and have Company depend only on Employee. Adding a new employee type then requires no changes to Company.