常用设计模式
了解单例、工厂、建造者、观察者模式在 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));
}
} // 发布/订阅模式广泛应用于消息队列、事件系统