Single responsibility ( a class have only one reason to change, do not mix up (mess up) everything in a class)
Open for extend, close for modification( move common behavior to interface, flip injection - Uncle Bob)
Liskov Substitution Principle, eg: same output format (array , json, specify type of Type- signature must match, preconditions cannot be greater, post conditional at least equal to, exception type must match). All of the derived class (sub class) could be substitutable (interchangeable)
A client should not be forced to implement an Interface that it does not use (return null in a override function ) - split fat interface to smaller interface.
The higher level of inheritance should not depend on the low level of code, it should depend on the abstract class (Inversion of control, Dependency inversion not Dependency injection, not opposite, but complementary) - decoupling code
TODO: translate to Vietnamese, add more code and explanation