Fundamentals 8 min read

Common Design Patterns in Java: Singleton, Adapter, Observer, Simple Factory, Factory Method, and Abstract Factory

This article introduces several core Java design patterns—including Singleton, Adapter, Observer, Simple Factory, Factory Method, and Abstract Factory—explaining their concepts, class diagrams, and providing complete code examples for each implementation variant.

Architecture Digest
Architecture Digest
Architecture Digest
Common Design Patterns in Java: Singleton, Adapter, Observer, Simple Factory, Factory Method, and Abstract Factory

1. Singleton Pattern

The Singleton pattern guarantees that only one instance of a class exists during the entire application lifecycle. The article presents the class diagram and three implementation approaches: eager initialization, lazy initialization, and double‑checked locking, each with full Java code.

public class Singleton {
    // eager initialization
    private static final Singleton instance = new Singleton();
    private Singleton() { /* do something */ }
    public static Singleton getInstance() { return instance; }
}
public class SingletonClass {
    private static SingletonClass instance = null;
    public static synchronized SingletonClass getInstance() {
        if (instance == null) {
            instance = new SingletonClass();
        }
        return instance;
    }
    private SingletonClass() { }
}
public class Singleton {
    private static Singleton instance = null;
    private Singleton() { /* do something */ }
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

2. Adapter Pattern

The Adapter pattern converts the interface of an existing class into another interface that clients expect, allowing incompatible classes to work together. It involves a target interface, an adaptee class, and an adapter class that delegates calls.

// Target interface
interface Target {
    void request();
}
// Existing class with a different interface
class Adaptee {
    public void specificRequest() {
        System.out.println("被适配类具有 特殊功能...");
    }
}
// Adapter class implementing Target and delegating to Adaptee
class Adapter implements Target {
    private Adaptee adaptee;
    public Adapter(Adaptee adaptee) { this.adaptee = adaptee; }
    public void request() { adaptee.specificRequest(); }
}
// Client test
public class Client {
    public static void main(String[] args) {
        Target adapter = new Adapter(new Adaptee());
        adapter.request();
    }
}

3. Observer Pattern

The Observer pattern defines a one‑to‑many dependency so that when the subject (observable) changes state, all its observers are automatically notified and updated. The article provides interfaces for observers and subjects, a concrete subject implementation, and a test example.

// Abstract observer
public interface Watcher {
    void update(String str);
}
// Concrete observer
public class ConcreteWatcher implements Watcher {
    @Override
    public void update(String str) { System.out.println(str); }
}
// Subject interface
public interface Watched {
    void addWatcher(Watcher watcher);
    void removeWatcher(Watcher watcher);
    void notifyWatchers(String str);
}
// Concrete subject
public class ConcreteWatched implements Watched {
    private List<Watcher> list = new ArrayList<>();
    @Override public void addWatcher(Watcher w) { list.add(w); }
    @Override public void removeWatcher(Watcher w) { list.remove(w); }
    @Override public void notifyWatchers(String str) {
        for (Watcher w : list) { w.update(str); }
    }
}
// Test class
public class Test {
    public static void main(String[] args) {
        Watched girl = new ConcreteWatched();
        Watcher w1 = new ConcreteWatcher();
        Watcher w2 = new ConcreteWatcher();
        Watcher w3 = new ConcreteWatcher();
        girl.addWatcher(w1);
        girl.addWatcher(w2);
        girl.addWatcher(w3);
        girl.notifyWatchers("开心");
    }
}

4. Simple Factory Pattern

The Simple Factory encapsulates object creation in a single method that returns different product instances based on input parameters. The article shows the class diagram and a Java example that creates arithmetic operation objects.

class OperationFactory {
    public static Operation createOperate(String operate) {
        Operation oper = null;
        switch (operate) {
            case "+": oper = new OperationAdd(); break;
            case "-": oper = new OperationSub(); break;
            case "*": oper = new OperationMul(); break;
            case "/": oper = new OperationDiv(); break;
        }
        return oper;
    }
}

Client usage example:

Operation oper = OperationFactory.createOperate("+");
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult();

5. Factory Method Pattern

In the Factory Method pattern each product has its own factory, allowing creation of different product families while adhering to the Open/Closed principle. The article provides class diagrams and discusses how concrete factories produce concrete products.

6. Abstract Factory Pattern

The Abstract Factory pattern defines an abstract factory that can produce families of related products without specifying concrete classes. The article includes interface definitions (e.g., IDept, IUser, IFactory) and diagrams illustrating the relationships between abstract factories, concrete factories, and products.

Overall, the article offers a concise yet comprehensive overview of these fundamental design patterns, complete with explanations, UML diagrams, and ready‑to‑run Java code snippets.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Design PatternsJavaSingletonAdapterFactoryObserver
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.