Most common reasons for project failure: Poor requirements/planning/management

Most common *technical* reason for project failure: unmanaged complexity

Abstraction: from the outside, we view an object or function as a coherent idea on a high level of detail

Information hiding / encapsulation: from the outside, internal implementation details are not viewable

Loose coupling:
	* Size (prefer fewer methods and parameters)
	* Visibility (e.g. avoid sneaking info between objects through a global variable)
	* Flexibility (objects and functions can be rearanged with relative ease)
	Example: Passing primitives is looser coupling than passing complex objects
	Avoid: some object/function requires knowledge of *internal* workings of another object/function.

High cohesion: Methods and data in a class are highly related and belong together

All of this (abstraction, information hiding, loose coupling, high cohesion) mainly comes down to two motivations:
	Limit the amount of complexity we deal with at a time
	Limit the effects when a change is made to the code
This reduces the cognitive load required to understand any given part of the system at a time.



[The CouplingVsCohesion.svg image is public domain, obtained from https://upload.wikimedia.org/wikipedia/commons/0/09/CouplingVsCohesion.svg]
