Z
ZHANK
实战进阶

常用设计模式

了解单例、工厂、建造者、观察者模式在 Java 中的实现

常用设计模式

设计模式是经过验证的、针对常见问题的代码组织方案。它不是新语法,而是"怎么把类和方法组织得更合理"的经验总结。

学完本章你将: 了解单例、工厂、建造者、观察者四种最常用的模式。


单例模式 —— 全局只有一个实例

有些对象全局只需要一个(数据库连接池、配置管理器)。单例模式保证类只有一个实例,并提供全局访问点。

java
// 饿汉式 —— 类加载时就创建(最简单,线程安全)
public class Config {
    private static final Config INSTANCE = new Config();
    private Config() {}  // 私有构造,禁止外部 new
    public static Config getInstance() { return INSTANCE; }
}

// 枚举式 —— 最安全的单例,防反射、防序列化破解
public enum Database {
    INSTANCE;
    public void connect() { /* ... */ }
}
// Database.INSTANCE.connect();

使用场景: 配置管理、日志器、数据库连接池、Spring 的 Bean(默认单例)。


工厂模式 —— 隐藏创建细节

当创建对象的逻辑很复杂(需要判断条件、读取配置),或者你希望统一管理对象创建时,用一个"工厂"来封装创建过程。

java
interface Animal { void speak(); }
class Dog implements Animal { public void speak() { System.out.println("汪汪"); } }
class Cat implements Animal { public void speak() { System.out.println("喵喵"); } }

// 工厂:把"创建哪种动物"的逻辑集中管理
class AnimalFactory {
    public static Animal create(String type) {
        return switch (type) {
            case "dog" -> new Dog();
            case "cat" -> new Cat();
            default -> throw new IllegalArgumentException("未知类型: " + type);
        };
    }
}

// 调用者不需要知道 Dog 和 Cat 的存在,只需要知道"我要一只 dog"
Animal pet = AnimalFactory.create("dog");
pet.speak(); // 汪汪

使用场景: Spring 的 BeanFactory、JDBC 的 DriverManager、支付渠道选择。


建造者模式 —— 优雅构造复杂对象

当一个对象有很多可选参数时,构造方法会变得臃肿。建造者模式用链式调用让构造过程清晰可控。

java
public class User {
    private final String name;     // 必填
    private final int age;         // 可选
    private final String email;    // 可选

    private User(Builder b) {      // 私有的,只能通过 Builder 创建
        this.name = b.name;
        this.age = b.age;
        this.email = b.email;
    }

    public static class Builder {
        private final String name; // 必填字段放构造
        private int age;
        private String email;

        public Builder(String name) { this.name = name; }
        public Builder age(int age)    { this.age = age; return this; }
        public Builder email(String e) { this.email = e; return this; }
        public User build() { return new User(this); }
    }
}

// 链式调用,只填需要的字段
User user = new User.Builder("Alice")
    .age(25)
    .email("a@test.com")
    .build();

使用场景: StringBuilder、HttpClient.Builder、Lombok 的 @Builder。


观察者模式 —— 发布-订阅

一个对象的状态变化时,自动通知所有依赖它的对象。解耦了"发消息"和"收消息"的两端。

java
// 发布者
class NewsPublisher {
    private final List<Consumer<String>> subscribers = new ArrayList<>();

    public void subscribe(Consumer<String> subscriber) {
        subscribers.add(subscriber);
    }

    public void publish(String news) {
        subscribers.forEach(s -> s.accept(news)); // 通知所有订阅者
    }
}

NewsPublisher pub = new NewsPublisher();
pub.subscribe(news -> System.out.println("用户A收到: " + news));
pub.subscribe(news -> System.out.println("用户B收到: " + news));
pub.publish("Java 25 发布了!");

使用场景: 消息队列、GUI 事件监听、Spring Event、RxJava。

public void subscribe(Consumer<String> observer) {
    observers.add(observer);
}
public void publish(String news) {
    observers.forEach(o -> o.accept(news));
}

} // 发布/订阅模式广泛应用于消息队列、事件系统