• One class = one job • Each class should have only one reason to change
• Open for extension, closed for modification • Add new features without changing existing code
• Child classes should work wherever parent classes work • Subtypes must be substitutable for their base types
• Many small, specific interfaces > few large, general ones • Don't force classes to implement methods they don't need
• Depend on abstractions, not concrete implementations • High-level modules shouldn't depend on low-level modules