当前位置:首页 > 技术 > 正文内容

常见设计模式详解与实现

访客 技术 2026年6月12日 1

单例模式

单例模式的核心目标是保证某个类在整个应用生命周期内仅存在一个实例,并对外提供统一的获取入口。

核心要素

  • 私有化的构造器,防止外部直接实例化
  • 静态私有成员变量持有唯一实例
  • 公开静态方法供全局访问

六种实现方式对比

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)
迪米特法则减少对象间的直接交互,降低耦合

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。