The 5 architectural pillars for writing maintainable and scalable object-oriented code.
A class should have one, and only one, reason to change.
Entities should be open for extension, but closed for modification.
Subtypes must be substitutable for their base types without breaking the program.
Clients 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.