
A component should have a single responsibility & no reason to change
The degree of cohesive responsibility is measured in relevance to its local scope
Example 1: calculateArea() & calculatePermiter() methods should be in one class. Whereas draw() & rotate() should be in a different class.
Example 2: A student class that also serializes the data to a particular database is not flexible if the database changes. Create another class that saves data.

Components should be closed for modification, but open for extension
New features or behaviors should NOT have to modify existing code
Example: Composition and interfaces ("Has A" relationship), along with method overriding can be used to avoid changing existing code.

Objects should be replaceable with their subtypes
Unimplemented methods are almost always indicative of a design flaw
Example 1: Decouple the inheritance that has unimplemented methods and give a new common parent class to inherit.
Example 2: Add another local method inside the inherited/overridden method to avoid changing the surround code.

No client should be forced to depend on methods it does not use
Interfaces should be divided based on functionalities (responsibility)
Example: Too many/empty methods most likely means we are not following the Single Responsibility Principle. Make sure each interface has methods with higher cohesiveness.

Lower and higher level details should not depend on each other
A middle abstraction increases re-usability of higher layers while retaining the free lower ones
Example: Implement the abstraction/interface for lower layers and use composition at higher layers to separate the return data from the operations