Some of the principles and guidelines on which oo design of software systems is based are discussed here:
The Open-Closed Principle
This principle was coined by Bertrand Meyer in 1988. It states that: The modules, methods, and classes should be open for extension, while closed for modifications. It encourages software professionals to write their code in such a manner that adding new functionality would involve making minimal modifications to existing codebase. Making changes to existing code is always tricky and runs the risk of introducing new bugs and problems.
Liskov’s Substitution Principle
The principle states that: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T. In other words, when your code is expecting an object of a base class, you should be able to pass an instance of your derived class without any problems and without changing the behavior of your program!!
Loose coupling (dependeny), High cohesion
Cohsion refers to how strongly the operations within a routing (class) are related. Coupling refers to the strength of connection or dependency between two routines (classes). Coupling is the complement to cohesion.
Favor composition over inheritance
Inheritance isn’t necessarily the best answer when you have to spread a changeable task over several generations of classes. Separate the part of the code that will change the most from the rest of your application.