Programming Languages - Design Patterns

Last Updated: 2024-01-21


E.g. java.lang.System and java.sql.DriverManager, although they are not implemented using the approach recommended in the GoF book but with static methods.

Decorator Pattern

The Decorator Pattern enables you to change or configure the functionality of a specific object, such as adding buttons or functionality to a scrollbar, or defining exactly how to model sandwich orders from two different customers from the same set of ingredients.


final FileOutputStream fos = new FileOutputStream("/tmp/file");
final ObjectOutputStream oos = new ObjectOutputStream(fos);

Flyweight Pattern

Minimizes memory use by sharing as much data as possible with other similar objects.


String constant pool

System.out.println(Integer.valueOf(10) == Integer.valueOf(10));
System.out.println(Integer.valueOf(1000) == Integer.valueOf(1000));
  • String Interning: is a method of storing only one copy of each distinct string value, which must be immutable.

Dependency Injection

The main use case for DI was ease of testing

Google's 2 dependency injection frameworks:

  • Guice
  • Dagger

Services Locator Pattern

An alternative to dependency injection. There's a single object that provides access to all the other services. When other code require access to unrelated services, it requests it from the services locator.

Strategy Pattern

The Strategy Pattern enables you to easily swap specific implementation details of an algorithm without requiring a complete rewrite. You can even swap implementations at run time. The Strategy Pattern is often used in conjunction with dependency injection to allow implementations to be swapped out for test-specific code, or to allow mocked implementations to be used instead.


You can view Comparator as Strategy interface, defining compare() method, now it's up to the classes how they compare themselves. This method is utilized for sorting inside Collections.sort()

The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.


import org.apache.http.client.utils.URIBuilder;
import java.net.URI;

URIBuilder builder = new URIBuilder()
URI uri = builder.build();

Observer Pattern

  • java.util.Observable
  • java.util.Observer

The Java 1.1 event model is based on the observer pattern. In addition, the interface java.util.Observable and the class java.util.Observer provide support for this pattern.

Abstract Factory Pattern

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

Pass factory to constructor

// Abstract factory #1
AbstractFactory factory1 = new ConcreteFactory1();
Client client1 = new Client(factory1);

// Abstract factory #2
AbstractFactory factory2 = new ConcreteFactory2();
Client client2 = new Client(factory2);

Factory Method Pattern

e.g. The getInstance() method in java.util.Calendar

Prototype pattern

The Prototype pattern is supported in Java through the clone() method defined in class Object and the use of java.lang.Cloneable interface to grant permission for cloning.

Proxy Pattern

The Proxy pattern is used extensively in the implementation of Java's Remote Method Invocation (RMI) and Interface Definition Language (IDL) features.

Iterator Pattern

Iterator 模式可以把访问逻辑从不同的集合类中抽象出来,从而避免向客户端暴露集合的内部结构



  • Decorator: Converts one interface to another
  • Adapter: Doesn't alter the interface, but adds responsibility
  • Facade: Makes an interface simpler


  • Strategy: Clients treat collections of objects and individual objects uniformly
  • Adapter: Provides a way to traverse a collection of objects without exposing the collection’s implementation
  • Iterator: Simplifies the interface of a group of classes
  • Facade: Changes the interface of one or more classes
  • Composite: Allows a group of objects to be notified when some state changes
  • Observer: Encapsulates interchangeable behaviors and uses delegation to decide which one to use


  • State: Encapsulate interchangeable behaviors and use delegation to decide which behavior to use.
  • Strategy: Subclasses decide how to implement steps in an algorithm.
  • Template Method: Encapsulate state-based behavior and delegate behavior to the current state.