1. Program to an interface, not an implementation
Don't declare variables to be instances of particular concrete classes. Instead, commit only to an interface defined by an abstract class.
2. Favor object composition over class inheritance
This keeps each class encapsulated and focused on one task.