Object-Oriented Design Principles (SOLID)
=================================

In general, aim for loosely coupled classes:
   Each class has, or makes use of, little or no knowledge of other classes.  
   (Opposite is tightly coupled.)

The term loosely coupled is related to encapsulation.
Objects manipulate their own data. Objects of other classes don't.
A public interface is provided (the public member functions).

(S) Single Responsibility Principle (SRP)
-----------------------------------

   A class should have only one reason to change.

   A class (type) definition should be highly cohesive.  Modifications
   to a class then are focused on the core functionality of the type.
   Multiple, varied changes implied that the class definition is
   not cohesive.

(O) Open/Closed Principle (OCP -- Bertrand Meyers)
-------------------------

   Classes (modules) should be open for extension but closed for modification.

   The chief idea here is to design software that can be modified
   without requiring changes in application code that uses that software. 
   The idea is to "add new code, but do not change working code". 
   At minimum, the interface needs to remain the same.  Moreover,
   working (class) functions should not change; isolate features.

   If a class hierarchy adheres to this principle, then a new subclass
   can be added without impacting old application code.  In C++, this
   kind of design is accomplished by using virtual functions.

(L) Substitution Principle (Liskov)
--------------------------

   An instance of a derived should be able to stand in for an instance of
   the base class.

   In other words, the application programmer can use derived classes through
   the base class interface without needing to know whether base or derived
   instances are being manipulated. This means it is a strong is-a relationship.
   Substitutability comes into play with dynamic binding: the application
   programmer need not perform subtype checking in order to invoke the
   appropriate function.

(I) Interface Segregation Principle
-----------------------------------

   A user should depend only on methods used, i.e., a class interface should
   be confined to a core functionality.

   Like the Single Responsibility Principle, this principle promotes a tightly
   defined class.

(D) Dependency Inversion Principle 
----------------------------------

   Details should depend on abstractions.  Abstractions should not depend
   upon details.

   All high level functions and data should be independent of low level
   functions and data structures.  An abstract class defines the interface.
   The interface should not depend on implementation details, otherwise
   it cannot be reused.

