A class should have only one reason to change.
Software entities (classes, modules, functions, etc.) should be open for extension but closed for modification.
Changing by adding new code rather than by changing existing code.
Keep the things that change frequently away from things that don't change.
Subtypes must be substitutable for their base types.
Clients (callers/implementers) should not be forced to depend on methods they do not use.
High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.