Designing good, reusable object-oriented software is hard. Design patterns make it easier to reuse successful designs and architectures.

What Makes a Design Pattern?
A pattern describes a recurring problem, then describes the solution to that problem in a particular context. The solution can be used repeatedly, without ever doing it in the same way.

Elements of a Pattern
  1. Name: A word or two that's used as a handle to describe the problem and its solution. It increases our design vocabulary, lets us design at a higher level of abstraction, and aids in communication. 
  2. Problem: Describes when to apply the pattern, by explaining the problem and its context. 
  3. Solution: Elements that make up the design, their responsibilities and relationships. It's an abstract template that can be applied in many different situations. Not concrete. 
  4. Consequences: Results and trade-offs of applying each pattern. Critical for evaluating and comparing the patterns. 
Problems Patterns Solve
  1. Finding appropriate objects
  2. Determining object granularity
  3. Specifying object interfaces
  4. Specifying object implementations
  5. Programming to an interface, not an implementation
Designing For Change
A design that doesn't take change into account risks major redesign in the future. Some common causes of change include:
  1. Creating an object by concrete class, instead of interface
  2. Dependence on specific operations
  3. Dependence on hardware and software platforms
  4. Dependence on object representations/implementations 
  5. Algorithmic dependencies
  6. Tight coupling
  7. Inability to alter classes conveniently
Design patterns help us avoid this by ensuring that a system can change in specific ways. Each design pattern lets some aspect of system structure vary independently of other aspects, making a system more robust to a particular kind of change.

Consider what should be variable in the design. Instead of considering what might force a change to a design, consider what you want to be able to change without a major redesign. The focus is on encapsulating the concept that changes.

How to use a Design Pattern
  1. Read the patterns for an overview
  2. Study the structure, elements and their relationships in the pattern
  3. Look at the sample code for the pattern
  4. Define the classes and methods with meaningful names in your application context
  5. Implement the operations to carry out the functionality
How not to use a Design Pattern
Do not apply a pattern indiscriminately. Often the flexibility comes at a cost of readability, as a pattern adds more indirection in terms of delegation. Using patterns without a thought can complicate the design and make the code unreadable.