Depend on abstractions, not implementations
This is just clients should reference the interface of a module, not its implementation. Otherwise this would defeat the purpose of the Abstraction Principle.
Ideally, as abstraction increases, so should stability:
Martin's Main Sequence inverted
We have also seen that the coupling degree depends inversely on the stability of the provider. Therefore, if we introduce a dependency, we should depend on something abstract rather than concrete.
Concrete classes should be viewed as module implementations, while abstract classes should be viewed as module interfaces. The DIP says that we should depend on the interface of a module so that the implementation is free to change.
As a quick demonstration of this, consider the following class:
class Company {
LinkedList<Employee> staff;
public Company() {
staff = new
LinkedList<Employee>();
}
// etc.
}
Note that the Company class depends directly on the linked list implementation of the List interface. Throughout the code there may be calls to methods only available in the LinkedList class, making it difficult to switch to ArrayList or some other implementation of Collection should the need arise. Instead, the author should depend on the interface implemented by LinkedList. When we think about interfaces, we may see that what we need isn't a list at all, but rather a set or a collection:
class Company {
Set<Employee> staff;
public Company() {
staff = new
ArraySet<Employee>();
}
// etc.
}