GoF Design Patterns
Java Core Libraries
Programming
Software Design
Code Examples

Examples of GoF Design Patterns in Java's core libraries

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

GoF design patterns are easier to understand when you can point to real library code instead of textbook diagrams. Java’s core libraries contain many pattern-shaped APIs, although the examples are often practical approximations rather than perfect one-to-one implementations of the Gang of Four descriptions.

Factory Method in Calendar and NumberFormat

Factory Method appears whenever an API exposes a creation method that returns an appropriate implementation without the caller naming the concrete class directly.

java
1import java.text.NumberFormat;
2import java.util.Calendar;
3import java.util.Locale;
4
5public class Demo {
6    public static void main(String[] args) {
7        Calendar cal = Calendar.getInstance();
8        NumberFormat nf = NumberFormat.getInstance(Locale.US);
9
10        System.out.println(cal.getTime());
11        System.out.println(nf.format(12345.67));
12    }
13}

The caller asks for an instance, and the library chooses the concrete implementation behind the scenes.

Singleton in Runtime

Runtime.getRuntime() is one of the clearest Java-library examples of the Singleton pattern.

java
1public class Demo {
2    public static void main(String[] args) {
3        Runtime runtime = Runtime.getRuntime();
4        System.out.println(runtime.availableProcessors());
5    }
6}

There is one runtime object representing access to JVM-level capabilities. That fits the classic “single shared instance with global access point” idea closely.

Decorator in the I/O Streams

The java.io stream classes are a classic Decorator example. You wrap one stream in another to add behavior without changing the underlying source.

java
1import java.io.BufferedInputStream;
2import java.io.ByteArrayInputStream;
3import java.io.DataInputStream;
4import java.io.IOException;
5
6public class Demo {
7    public static void main(String[] args) throws IOException {
8        byte[] bytes = {0, 0, 0, 7};
9        try (DataInputStream in = new DataInputStream(
10                new BufferedInputStream(
11                        new ByteArrayInputStream(bytes)))) {
12            System.out.println(in.readInt());
13        }
14    }
15}

ByteArrayInputStream provides the raw data source. BufferedInputStream adds buffering. DataInputStream adds typed reads. That is decorator layering in everyday Java.

Adapter in Arrays.asList

Adapter appears when one interface is presented in a more useful or expected form. Arrays.asList adapts an array into a List view.

java
1import java.util.Arrays;
2import java.util.List;
3
4public class Demo {
5    public static void main(String[] args) {
6        String[] names = {"A", "B", "C"};
7        List<String> list = Arrays.asList(names);
8        System.out.println(list.get(1));
9    }
10}

The returned list is backed by the original array, which is a reminder that this is an adapter-style view, not a brand-new general-purpose ArrayList.

Observer-Like Behavior in Event Listeners

Modern Java avoids the old deprecated Observable API, but listener models in GUI frameworks still show the Observer idea clearly: one subject notifies many interested listeners.

java
1import javax.swing.JButton;
2
3public class Demo {
4    public static void main(String[] args) {
5        JButton button = new JButton("Click");
6        button.addActionListener(e -> System.out.println("clicked"));
7    }
8}

The button publishes events, and registered listeners react to them. That is the basic observer relationship.

Iterator Is a Pattern and an API

Some GoF patterns became so fundamental in Java that they are visible directly as interfaces. Iterator is a standard example.

java
1import java.util.List;
2
3public class Demo {
4    public static void main(String[] args) {
5        Iterator<String> it = List.of("x", "y", "z").iterator();
6        while (it.hasNext()) {
7            System.out.println(it.next());
8        }
9    }
10}

This is useful to mention because Java’s libraries do not only use patterns internally. They often expose them directly as public API shapes.

Common Pitfalls

A common mistake is trying to force every library class into exactly one GoF box. Real APIs are usually pragmatic hybrids.

Another issue is using examples from deprecated parts of the JDK and assuming they represent current best practice.

A third problem is memorizing pattern names without noticing the motivation behind them, such as decoupled creation, behavior extension, or event notification.

Summary

  • Java core libraries contain many practical examples of GoF-style patterns.
  • 'Runtime.getRuntime() is a strong Singleton example.'
  • I/O stream wrappers are a classic Decorator example.
  • Factory Method appears in APIs such as Calendar.getInstance().
  • Learn the pattern purpose, not just the label attached to a class.

Course illustration
Course illustration

All Rights Reserved.