Java 设计模式:单例、工厂、观察者模式
直接掌握三种最常用的 Java 设计模式实现方法,避免重复造轮子与代码臃肿。本文按模块提供可直接复制运行的标准模板与实操步骤。
第一阶段:实现单例模式
核心目标:保证全局仅存在一个实例对象,节省系统资源并统一状态管理。
通俗解释:单例就像操作系统的回收站。无论你从哪个磁盘删除文件,最终都会进入同一个回收站实例,防止数据分散与逻辑冲突。
- 声明私有静态变量,类型与当前类保持一致,并将初始值赋为
null。 - 设置构造函数的访问修饰符为
private,彻底阻断外部代码通过new关键字创建新对象。 - 添加公共静态方法
getInstance(),在方法内部实现双重检查逻辑:先判断实例是否为空,若为空则进入同步块,再次判断并执行初始化。 - 使用
volatile关键字修饰静态变量,防止 Java 虚拟机在底层进行指令重排序,确保多线程环境下获取到的对象始终是完全初始化状态。
public class DatabaseConfig {
// 步骤1 & 4:声明 volatile 静态实例
private static volatile DatabaseConfig instance;
// 步骤2:私有化构造函数
private DatabaseConfig() {}
// 步骤3:提供线程安全的获取方法
public static DatabaseConfig getInstance() {
if (instance == null) {
synchronized (DatabaseConfig.class) {
if (instance == null) {
instance = new DatabaseConfig();
}
}
}
return instance;
}
}
下表对比不同实现方案的适用场景与缺陷:
| 实现方案 | 内存占用 | 线程安全性 | 适用场景 |
|---|---|---|---|
| 饿汉式(类加载即创建) | 启动即占满 | 天然安全 | 实例轻量且必须提前就绪 |
| 懒汉式(调用才创建) | 按需分配 | 需手动加锁 | 实例消耗大且可能永不调用 |
| 静态内部类 | 按需分配 | JVM 底层保证 | 生产环境推荐的标准写法 |
| 枚举式 | 启动即占满 | 绝对安全 | 需要防止反射与反序列化破坏单例 |
第二阶段:实现工厂模式
核心目标:集中管理对象创建逻辑,隔离调用方与具体实现类的直接依赖。
通俗解释:工厂就像餐厅点餐系统。顾客只需告诉服务员要某道菜,厨房自动调用对应配方制作。顾客无需知道油温、刀工与调味细节,后续更换厨师或菜谱也不影响点餐流程。
- 抽取各产品共有的核心功能,定义标准接口或抽象基类。
- 编写多个具体实现类,实现接口中声明的所有业务方法。
- 创建静态工厂类,内部声明一个
Map容器,建立标识字符串与对象构造函数的映射关系。 - 编写核心生产方法,接收类型参数作为键,从容器中提取对应的构造函数并执行实例化。
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
// 1. 定义产品接口
public interface Notification {
void send(String receiver, String content);
}
// 2. 编写具体产品
class EmailNotification implements Notification {
public void send(String receiver, String content) {
System.out.println("通过邮件发送至: " + receiver);
}
}
class SmsNotification implements Notification {
public void send(String receiver, String content) {
System.out.println("通过短信发送至: " + receiver);
}
}
// 3. 封装工厂
public class NotificationFactory {
private static final Map<String, Supplier<Notification>> factoryMap = new HashMap<>();
static {
factoryMap.put("email", EmailNotification::new);
factoryMap.put("sms", SmsNotification::new);
}
// 4. 暴露生产方法
public static Notification create(String type) {
Supplier<Notification> supplier = factoryMap.get(type.toLowerCase());
if (supplier == null) {
throw new IllegalArgumentException("不支持的推送类型: " + type);
}
return supplier.get();
}
}
第三阶段:实现观察者模式
核心目标:建立一对多的事件广播机制,实现核心模块与扩展模块的彻底解耦。
通俗解释:观察者就像气象局的监测终端。气象站(被观察者)更新气压数据时,会自动唤醒所有已绑定的终端(观察者),各终端根据新数据刷新屏幕显示或触发预警广播,气象站本身不干涉终端的具体处理逻辑。
- 定义观察者接口,声明唯一的数据更新回调方法
update(String message)。 - 构建被观察者类,声明线程安全的列表容器用于存储已注册的观察者对象。
- 提供注册与注销方法,分别使用
List.add与List.remove管理监听关系。 - 触发业务变更时,调用内部广播方法,遍历观察者列表并逐一执行
update回调,传递最新数据。
import java.util.ArrayList;
import java.util.List;
// 1. 观察者接口
public interface Observer {
void update(String eventData);
}
// 2. 被观察者(主题)
public class StockMarket {
private final List<Observer> observers = new ArrayList<>();
public void register(Observer observer) { observers.add(observer); }
public void unregister(Observer observer) { observers.remove(observer); }
// 4. 触发更新
public void broadcast(String priceInfo) {
List<Observer> snapshot = new ArrayList<>(observers);
for (Observer obs : snapshot) {
obs.update(priceInfo);
}
}
}
// 使用示例
public class Client {
public static void main(String[] args) {
StockMarket market = new StockMarket();
// 3. 注册观察者
market.register(msg -> System.out.println("【A终端】收到行情: " + msg));
market.register(msg -> System.out.println("【B终端】记录日志: " + msg));
// 4. 发送数据
market.broadcast("AAPL上涨2.5%");
}
}
在项目中遇到对象复用、创建逻辑复杂化或跨模块状态同步需求时,直接替换模板中的业务类名与接口方法名,将现有散落的 new 关键字与硬编码逻辑迁移至对应结构内,即可快速完成架构解耦。

暂无评论,快来抢沙发吧!