Design Patterns are an important part of programming efforst.  They show patterns, or frameworks, to be followed when writing programs.  I have taken examples from the O'Reilly book Head First Design Patterns by Eric and Elisabeth Freeman.

These are the Design Patterns covered in the book:


Object Oriented Principles are also taken from the Head First Design Patterns book.  Here is the list with some examples.

Encapsulate what varies - Description:
If you've got some aspect of your code that is changing, say with every new requirement, then you know you've got a behavior that needs to be pulled out and separated from all the stuff that doesn't change.  Take the parts that vary and encapsulate them, so that later you can alter or extend the parts that vary without affecting those that don't.


Favor composition over inheritance - Example:
Without the Principle:

public class Duck {
	public abstract void quack();
	public abstract void fly();
	public abstract void display();
}
				
With the Principle:
public class Duck {
	private QuackBehavior quackBehavior;
	private FlyBehavior flyBehavior;
	public void quack() { quackBehavior.quack(); }
	public void fly() { flyBehavior.fly(); }
	public abstract void display();
}
				


Program to an interface, not to an implementation - Example:
Without the Principle:

public ArrayList getList() { return new ArrayList(); }
				
With the Principle:
public List getList() { return new ArrayList(); }
				


Strive for loosely coupled designs between objects that interact - Definition:
Loosely coupled designs allow us to build flexible OO systems that can handle change because they minimize the interdependency between objects.  The Observer Pattern provides an object design where subjects and observers are loosely coupled.


Classes should be open for extension, but closed for modification - Definition:
The goal is to allow classes to be easily extended to incorporate new behavior without modifying existing code.  This creates designs that are resilient to change and flexible enough to take on new functionality to meet changing requirements.  This principle cannot be applied everywhere!  It can be wasteful, unnecessary, and can lead to complex, hard to understand code.


Depend on abstractions.  Do not depend on concrete classes
This Principle is also called the "Dependancy Inversion Principle".  It suggests that our high-level components should not depend on our low-level components, rather they should both depend on abstractions.  The "inversion" in the name is there because it inverts the way you typiclly might think about your OO design.  You want low-level components to depend on a higher level abstraction.  Likewise the high-level component is tied to the same abstraction.  Here are some guidelines to help you avoid OO designs that violate this Principle:

Every Java program violates these guidelines!  But, they are something to strive for, when possible.


Only talk to your friends - Example:
Without the Principle:

public float getTemp() {
	Thermometer thermometer = station.getThermometer();
	return thermometer.getTemperature();
}
				
With the Principle:
public float getTemp() {
	return station.getTemperature();
}
				


Don't call us, we'll call you - Definition:
This principle gives us a way to prevent "dependency rot."  Dependency rot happens when you have high-level components depending on low-level components depending on sideways components depending on low-level components, and so on.  When rot sets in, no one can easily understand the way a system is designed.  With the Hollywood principle, we allow low-level components to hook themselves into a system, but the high-level components determine when they are needed, and how.  In other words, the high-level components give low-level components a "don't call us, we'll call you" treatment.


A class should have only one reason to change - Example:
If an aggregate of objects had to also provide the iteration responsibility, then if we changed the implementation of the aggregate, then we'd also have to change the iteration portion.  This means the aggregate had two responsibilities, maintaining the aggregate, and the iteration, or two reasons to change.  By separating the iteration, we give the aggregate only one responsibility, and only one reason to change.