文章目录

Java 设计模式:单例、工厂、观察者模式

发布于 2026-04-07 13:14:27 · 浏览 10 次 · 评论 0 条

Java 设计模式:单例、工厂、观察者模式

直接掌握三种最常用的 Java 设计模式实现方法,避免重复造轮子与代码臃肿。本文按模块提供可直接复制运行的标准模板与实操步骤。


第一阶段:实现单例模式

核心目标保证全局仅存在一个实例对象,节省系统资源并统一状态管理。
通俗解释:单例就像操作系统的回收站。无论你从哪个磁盘删除文件,最终都会进入同一个回收站实例,防止数据分散与逻辑冲突。

  1. 声明私有静态变量,类型与当前类保持一致,并将初始值赋为 null
  2. 设置构造函数的访问修饰符为 private彻底阻断外部代码通过 new 关键字创建新对象。
  3. 添加公共静态方法 getInstance(),在方法内部实现双重检查逻辑:先判断实例是否为空,若为空则进入同步块,再次判断并执行初始化。
  4. 使用 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 底层保证 生产环境推荐的标准写法
枚举式 启动即占满 绝对安全 需要防止反射与反序列化破坏单例

第二阶段:实现工厂模式

核心目标集中管理对象创建逻辑,隔离调用方与具体实现类的直接依赖。
通俗解释:工厂就像餐厅点餐系统。顾客只需告诉服务员要某道菜,厨房自动调用对应配方制作。顾客无需知道油温、刀工与调味细节,后续更换厨师或菜谱也不影响点餐流程。

  1. 抽取各产品共有的核心功能,定义标准接口或抽象基类。
  2. 编写多个具体实现类,实现接口中声明的所有业务方法。
  3. 创建静态工厂类,内部声明一个 Map 容器,建立标识字符串与对象构造函数的映射关系。
  4. 编写核心生产方法,接收类型参数作为键,从容器中提取对应的构造函数并执行实例化。
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();
    }
}

第三阶段:实现观察者模式

核心目标建立一对多的事件广播机制,实现核心模块与扩展模块的彻底解耦。
通俗解释:观察者就像气象局的监测终端。气象站(被观察者)更新气压数据时,会自动唤醒所有已绑定的终端(观察者),各终端根据新数据刷新屏幕显示或触发预警广播,气象站本身不干涉终端的具体处理逻辑。

  1. 定义观察者接口,声明唯一的数据更新回调方法 update(String message)
  2. 构建被观察者类,声明线程安全的列表容器用于存储已注册的观察者对象。
  3. 提供注册与注销方法,分别使用 List.addList.remove 管理监听关系。
  4. 触发业务变更时,调用内部广播方法,遍历观察者列表并逐一执行 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 关键字与硬编码逻辑迁移至对应结构内,即可快速完成架构解耦。

评论 (0)

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

扫一扫,手机查看

扫描上方二维码,在手机上查看本文