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

常见设计模式解析:单例、工厂、适配器与代理

访客 技术 2026年6月9日 1

软件开发中常用的设计模式解析

在软件架构设计中,设计模式是解决常见问题的标准化方案,能有效提升代码质量与可维护性。本文将深入讲解四种经典设计模式——单例、工厂、适配器和代理,涵盖其原理、实现方式及实际应用。

一、单例模式

基本概念

单例模式确保某个类在整个系统中仅存在一个实例对象,通过统一接口提供访问点。该模式适用于需要全局唯一资源管理的场景,如数据库连接池或配置管理器。

关键技术点

  • 避免重复实例化消耗资源的对象
  • 保证全局状态一致性
  • 控制共享资源访问

实现方案对比

  1. 立即加载型:类加载时初始化实例,天然线程安全但可能提前占用资源
public class EagerInstance {
    private static final EagerInstance INSTANCE = new EagerInstance();
    
    private EagerInstance() {}
    
    public static EagerInstance getInstanceMethod() {
        return INSTANCE;
    }
}
  1. 延迟加载型:使用双重校验锁机制实现线程安全的延迟初始化
public class LazyInstance {
    private static volatile LazyInstance INSTANCE;
    
    private LazyInstance() {}
    
    public static LazyInstance getInstanceMethod() {
        if (INSTANCE == null) {
            synchronized (LazyInstance.class) {
                if (INSTANCE == null) {
                    INSTANCE = new LazyInstance();
                }
            }
        }
        return INSTANCE;
    }
}

应用场景

  • 系统配置管理
  • 日志记录器
  • 连接池组件

二、工厂模式

工厂模式通过封装对象创建逻辑,实现对象使用与构造的解耦。根据复杂度可分为简单工厂、工厂方法和抽象工厂三种形式。

1. 简单工厂模式

通过单一工厂类根据参数创建不同产品实例,适合产品种类较少的场景

// 产品接口
public interface Vehicle {
    void start();
}

// 具体产品
public class Car implements Vehicle {
    @Override
    public void start() {
        System.out.println("Car started");
    }
}

// 工厂类
public class VehicleFactory {
    public static Vehicle createVehicle(String type) {
        if ("car".equals(type)) {
            return new Car();
        }
        throw new IllegalArgumentException();
    }
}

2. 工厂方法模式

为每个产品定义独立工厂,符合开闭原则

// 产品接口
public interface Logger {
    void log(String msg);
}

// 具体产品
public class FileLogger implements Logger {
    @Override
    public void log(String msg) {
        System.out.println("File log: " + msg);
    }
}

// 工厂接口
public interface LoggerFactory {
    Logger createLogger();
}

// 具体工厂
public class FileLoggerFactory implements LoggerFactory {
    @Override
    public Logger createLogger() {
        return new FileLogger();
    }
}

3. 抽象工厂模式

用于创建相关产品族,如不同平台的UI组件

三、适配器模式

适配器模式通过转换接口使不兼容的类能够协同工作,常见于系统集成场景。

核心价值

  • 整合遗留系统
  • 适配第三方库
  • 隔离接口变化

实现方式

  1. 类适配器(继承实现)
  2. 对象适配器(组合实现)
// 目标接口
public interface MediaPlayer {
    void play(String filename);
}

// 适配者类
public class Mp3Player {
    public void playMp3(String filename) {
        System.out.println("Playing MP3: " + filename);
    }
}

// 适配器类
public class MediaAdapter implements MediaPlayer {
    private Mp3Player player;
    
    public MediaAdapter(Mp3Player player) {
        this.player = player;
    }
    
    @Override
    public void play(String filename) {
        player.playMp3(filename);
    }
}

四、代理模式

代理模式通过中间层控制对目标对象的访问,常用于增强功能或控制访问权限。

典型场景

  • 远程调用
  • 权限控制
  • 延迟加载

实现示例

// 接口定义
public interface ImageLoader {
    void display();
}

// 真实对象
public class HighResImage implements ImageLoader {
    private String path;
    
    public HighResImage(String path) {
        this.path = path;
        loadFromDisk();
    }
    
    private void loadFromDisk() {
        System.out.println("Loading image from disk: " + path);
    }
    
    @Override
    public void display() {
        System.out.println("Displaying image: " + path);
    }
}

// 代理对象
public class ImageProxy implements ImageLoader {
    private HighResImage image;
    private String path;
    
    public ImageProxy(String path) {
        this.path = path;
    }
    
    @Override
    public void display() {
        if (image == null) {
            image = new HighResImage(path);
        }
        image.display();
    }
}

模式应用策略

不同设计模式各有适用场景:

  • 单例:全局资源管理
  • 工厂:对象创建解耦
  • 适配器:接口兼容处理
  • 代理:功能增强与访问控制

实际开发中常组合使用,例如工厂创建的对象可通过代理添加日志功能,适配器处理的接口可由单例模式统一管理。需根据具体需求选择合适的模式组合,避免过度设计。

相关文章

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...

发表评论

访客

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