常见设计模式详解与实现
单例模式
单例模式的核心目标是保证某个类在整个应用生命周期内仅存在一个实例,并对外提供统一的获取入口。
核心要素
- 私有化的构造器,防止外部直接实例化
- 静态私有成员变量持有唯一实例
- 公开静态方法供全局访问
六种实现方式对比
1. 饿汉式(类加载即初始化)
public class AppConfig {
private static final AppConfig config = new AppConfig();
private AppConfig() {
// 初始化操作
}
public static AppConfig fetchConfig() {
return config;
}
}
特点:线程安全,但缺乏延迟加载能力,可能造成不必要的资源占用。
2. 基础懒汉式(存在并发隐患)
public class TaskScheduler {
private static TaskScheduler scheduler;
private TaskScheduler() {}
public static TaskScheduler fetchScheduler() {
if (scheduler == null) {
scheduler = new TaskScheduler();
}
return scheduler;
}
}
多线程场景下可能产生多个实例,不推荐生产环境使用。
3. 同步方法懒汉式
public class CacheManager {
private static CacheManager manager;
private CacheManager() {}
public static synchronized CacheManager fetchManager() {
if (manager == null) {
manager = new CacheManager();
}
return manager;
}
}
通过 synchronized 保证线程安全,但同步粒度大,高并发时性能较差。
4. 双重校验锁(DCL)
public class ConnectionPool {
private volatile static ConnectionPool pool;
private ConnectionPool() {}
public static ConnectionPool fetchPool() {
if (pool == null) {
synchronized (ConnectionPool.class) {
if (pool == null) {
pool = new ConnectionPool();
}
}
}
return pool;
}
}
采用 volatile 禁止指令重排序,两次校验减少同步开销,兼顾安全与性能。
5. 静态内部类模式
public class MessageQueue {
private MessageQueue() {}
private static class QueueHolder {
private static final MessageQueue queue = new MessageQueue();
}
public static MessageQueue fetchQueue() {
return QueueHolder.queue;
}
}
利用类加载机制保证线程安全,实现延迟加载且无需额外同步。
6. 枚举实现
public enum Logger {
LOGGER;
public void record(String msg) {
// 日志记录逻辑
}
}
最简洁的实现,天然防止反射攻击和序列化问题。
典型应用场景
- 数据库连接池、线程池等共享资源管理
- 全局配置信息的集中存储
- 系统日志记录器的统一调度
- 频繁创建销毁且构造代价高的对象复用
工厂模式
工厂模式将对象的创建过程封装起来,调用方只需关注接口而非具体实现,实现创建与使用的解耦。
优势
- 降低模块间耦合度
- 提升代码复用性
- 新增产品时无需改动既有代码,符合开闭原则
三种形态
| 类型 | 说明 |
|---|---|
| 简单工厂 | 单一工厂类负责所有产品创建 |
| 工厂方法 | 抽象工厂定义接口,子类决定实例化哪个类 |
| 抽象工厂 | 创建相关对象家族,无需依赖具体类 |
适用场景
- 运行时才能确定需要创建的具体类型
- 对象创建逻辑复杂,需要集中管理
- 希望将创建职责委托给多个子类之一
代理模式
为其他对象提供一种代理以控制对这个对象的访问,在不改变原对象的前提下增加额外功能。
角色划分
- 抽象接口:声明真实对象与代理的共同行为
- 真实对象:业务逻辑的实际执行者
- 代理对象:持有真实对象引用,负责访问控制与增强
常见变体
静态代理、动态代理(JDK动态代理、CGLIB字节码增强)
观察者模式
建立对象间的一对多依赖关系,当主体状态变更时,所有依赖的观察者自动收到通知并更新。
public interface Subscriber {
void onEvent(String eventType, Object data);
}
public class EventBus {
private List<Subscriber> subscribers = new ArrayList<>();
public void attach(Subscriber s) {
subscribers.add(s);
}
public void publish(String event, Object payload) {
for (Subscriber s : subscribers) {
s.onEvent(event, payload);
}
}
}
装饰器模式
动态地给对象添加额外职责,比继承更灵活。通过包装原有对象,在不改变其结构的情况下扩展功能。
适配器模式
将不兼容的接口转换为可协作的接口,使原本因接口不匹配而无法工作的类能够协同运作。
核心设计原则
| 原则 | 核心思想 |
|---|---|
| 单一职责 | 一个类只负责一项明确功能,降低复杂度 |
| 开闭原则 | 对扩展开放,对修改关闭 |
| 里氏替换 | 子类可替换父类且程序行为正确 |
| 接口隔离 | 避免强迫类实现不需要的方法 |
| 依赖倒置 | 依赖抽象而非具体实现 |
| 组合复用 | 优先使用组合(has-a)而非继承(is-a) |
| 迪米特法则 | 减少对象间的直接交互,降低耦合 |