Single responsibility
A module should have one and only one reason to change
Open closed
A module should be closed for modification but open for extension
Liskov substitution
It should be possible to substitute a base class with a subclass without breaking the application.
- There should be covariance of return types
- Parameters should be contravariant
- No new exceptions should be raised in the sub class
class BaseClass { } class SubClass : BaseClass { } class Program { delegate BaseClass Covariance(SubClass subClass); delegate BaseClass ContraVariance(SubClass subClass); static SubClass MethodA(SubClass subClass) { Console.WriteLine("Method A"); return new SubClass(); } static BaseClass MethodB(SubClass subClass) { Console.WriteLine("Method B"); return new BaseClass(); } static void main() { Covariance covarianceExample = MethodA; ContraVariance contraVarianceExample = MethodB; var baseClass1 = MethodA(new SubClass()); // var baseClass2 = MethodA(new BaseClass()); // Contravariance allows base class to be passed instead of sub class } }
Interface seggregation
Clients should not be forced to depend upon an interface that they do not use
Dependency inversion
High level module should not depend on low level modules. Both should use abstrations