当前位置: 首页 > news >正文

《常见的设计模式——单例、代理与适配器》

目录

引言

一、单例模式(Singleton)

二、代理模式(Proxy)

三、适配器模式(Adapter)

四、三种模式对比

五、模式选择建议


引言

设计模式是解决特定问题的经典方案,本文将聚焦三种最常用的设计模式:单例模式、代理模式和适配器模式,通过实例代码和实际应用场景,帮助你深入理解它们的精髓。

一、单例模式(Singleton)

1. 模式定义

单例模式确保一个类只有一个实例,并提供一个全局访问点。这是所有设计模式中最简单但应用最广泛的一种。

2. 实现方式

(1) 饿汉式(线程安全)

public class EagerSingleton {private static final EagerSingleton instance = new EagerSingleton();private EagerSingleton() {}public static EagerSingleton getInstance() {return instance;}
}

特点:类加载时就初始化,线程安全但可能造成资源浪费

(2) 懒汉式(双重检查锁)

public class LazySingleton {private volatile static LazySingleton instance;private LazySingleton() {}public static LazySingleton getInstance() {if (instance == null) {synchronized (LazySingleton.class) {if (instance == null) {instance = new LazySingleton();}}}return instance;}
}

特点:延迟加载,线程安全且高效(推荐)

(3) 静态内部类实现

public class InnerClassSingleton {private InnerClassSingleton() {}private static class SingletonHolder {private static final InnerClassSingleton instance = new InnerClassSingleton();}public static InnerClassSingleton getInstance() {return SingletonHolder.instance;}
}

特点:兼顾延迟加载和线程安全,无需同步锁

3. 应用场景

配置管理类(如Spring的ApplicationContext)

数据库连接池

日志记录器

线程池

缓存系统

4. 注意事项

多线程环境必须保证线程安全

考虑序列化和反序列化破坏单例的问题

反射攻击防护(可在构造器中检查实例是否存在)

二、代理模式(Proxy)

1. 模式定义

代理模式为其他对象提供一种代理控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介作用。

2. 实现方式

(1) 静态代理

interface Subject {void request();
}class RealSubject implements Subject {@Overridepublic void request() {System.out.println("真实请求");}
}class Proxy implements Subject {private RealSubject realSubject;@Overridepublic void request() {if (realSubject == null) {realSubject = new RealSubject();}preRequest();realSubject.request();postRequest();}private void preRequest() {System.out.println("预处理");}private void postRequest() {System.out.println("后处理");}
}

(2) 动态代理(JDK实现)

interface DynamicSubject {void dynamicRequest();
}class RealDynamicSubject implements DynamicSubject {@Overridepublic void dynamicRequest() {System.out.println("真实动态请求");}
}class DynamicProxyHandler implements InvocationHandler {private Object target;public DynamicProxyHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("动态代理预处理");Object result = method.invoke(target, args);System.out.println("动态代理后处理");return result;}
}// 使用方式
DynamicSubject subject = (DynamicSubject) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[]{DynamicSubject.class},new DynamicProxyHandler(new RealDynamicSubject())
);
subject.dynamicRequest();

(3) CGLIB动态代理

class RealService {public void execute() {System.out.println("真实服务执行");}
}class CglibProxy implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("CGLIB预处理");Object result = proxy.invokeSuper(obj, args);System.out.println("CGLIB后处理");return result;}
}// 使用方式
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(RealService.class);
enhancer.setCallback(new CglibProxy());
RealService proxy = (RealService) enhancer.create();
proxy.execute();

3. 代理类型

代理类型

特点

远程代理

为不同地址空间的对象提供本地代表(如RMI)

虚拟代理

根据需要创建开销大的对象(如图片懒加载)

保护代理

控制对原始对象的访问权限

智能引用

在访问对象时执行额外操作(如引用计数、懒加载)

Spring AOP

基于动态代理实现的面向切面编程

4. 应用场景

权限控制

延迟加载

日志记录

事务管理

性能监控

RPC调用

三、适配器模式(Adapter)

1. 模式定义

适配器模式将一个类的接口转换成客户期望的另一个接口,使原本接口不兼容的类可以一起工作。

2. 实现方式

(1) 类适配器(继承方式)

class Adaptee {public void specificRequest() {System.out.println("特殊请求");}
}interface Target {void request();
}class Adapter extends Adaptee implements Target {@Overridepublic void request() {specificRequest();}
}

(2) 对象适配器(组合方式,推荐)

class Adaptee {public void specificRequest() {System.out.println("特殊请求");}
}interface Target {void request();
}class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee = adaptee;}@Overridepublic void request() {adaptee.specificRequest();}
}

(3) 接口适配器(缺省适配器)

interface ServiceInterface {void service1();void service2();void service3();
}abstract class AbstractAdapter implements ServiceInterface {@Overridepublic void service1() {}@Overridepublic void service2() {}@Overridepublic void service3() {}
}class ConcreteService extends AbstractAdapter {@Overridepublic void service1() {System.out.println("只实现需要的服务1");}
}

3. 应用场景

场景类型

示例

旧系统整合

将遗留系统接口适配到新系统

第三方库适配

统一不同库的接口规范

接口版本兼容

新老接口版本兼容处理

设备驱动适配

不同厂商设备驱动适配统一接口

数据格式转换

XML与JSON数据转换

4. 实际案例

JDBC驱动管理器:适配不同数据库的驱动

Spring MVC的HandlerAdapter:适配不同类型的控制器

Java I/O中的InputStreamReader:将字节流适配为字符流

四、三种模式对比

模式核心目的主要优点典型应用场景
单例模式控制实例数量全局访问、节省资源配置管理、连接池
代理模式控制对象访问职责清晰、扩展性强权限控制、AOP编程
适配器接口转换提高复用性、兼容性强系统整合、第三方库适配

五、模式选择建议

  1. 单例模式选择:

    • 需要严格控制实例数量时
    • 考虑线程安全性和性能(推荐双重检查锁或静态内部类实现)
  2. 代理模式选择:

    • 需要增强或控制对象功能时
    • 静态代理用于简单场景,动态代理用于复杂场景
    • Spring AOP优先于手动代理
  3. 适配器模式选择:

    • 接口不兼容需要转换时
    • 优先使用对象适配器(组合优于继承)
    • 考虑适配器的透明性(是否对客户端暴露适配细节)

记住:应根据实际需求合理选择,保持代码的简洁性和可维护性。


文章转载自:

http://tM8xwGJY.qczyz.cn
http://5EFFZfxk.qczyz.cn
http://phyptz5O.qczyz.cn
http://xk8stYkO.qczyz.cn
http://M76iDx7F.qczyz.cn
http://n5JBF0WR.qczyz.cn
http://cdkb85OA.qczyz.cn
http://NIB7DupV.qczyz.cn
http://fisyatYr.qczyz.cn
http://n2GKOXGs.qczyz.cn
http://GtWHqI6e.qczyz.cn
http://DD0oglmI.qczyz.cn
http://pYGhIe1f.qczyz.cn
http://JtQR4yde.qczyz.cn
http://8UP7Wh8i.qczyz.cn
http://oqCJzFB0.qczyz.cn
http://Bw5w6Y8m.qczyz.cn
http://NYAbsbz3.qczyz.cn
http://7j1YxPUQ.qczyz.cn
http://SDqbK6bk.qczyz.cn
http://9Dlfs5k7.qczyz.cn
http://mtaDYQ0B.qczyz.cn
http://4uH60QlX.qczyz.cn
http://Il5lxbQt.qczyz.cn
http://xRYRk6AV.qczyz.cn
http://tLmKzUoc.qczyz.cn
http://hEn4uRoM.qczyz.cn
http://uYrTMBcc.qczyz.cn
http://L6Iyw4Oc.qczyz.cn
http://i5gdeibf.qczyz.cn
http://www.dtcms.com/a/381120.html

相关文章:

  • 海龟交易策略
  • MySQL 事务
  • claude code使用小窍门
  • Recaptcha2 图像识别 API 对接说明
  • Spring中 @Value注解设置默认值
  • Linux / Windows 下连续发送多帧 8 字节指令,下位机只响应第一帧,第二帧“丢失”。
  • RStudio 教程:以抑郁量表测评数据分析为例
  • 驱动程序介绍及其安装说明
  • Day03 前缀和 | 1248. 统计「优美子数组」、53. 最大子数组和
  • 现代化心理中心场室建设与规划之道
  • 面向小白用户的多集群云原生应用管理平台设计
  • 怎么设计一个高效的任务调度器,避免任务饥饿
  • Linux运维核心知识体系总结:从安全加密到服务部署
  • 50期权日内交易技巧
  • 枚举算法和排序算法能力测试
  • 未来之窗昭和仙君 (四) 前端网页分页 — 东方仙盟筑基期
  • Class50 LSTM
  • Redis是什么?一篇讲透它的定位、特点与应用场景
  • [zlaq.mohurd]网页搜索功能JavaScript实现机制技术分析报告
  • k8s工作负载-Pod学习
  • IDF: Iterative Dynamic Filtering Networks for Generalizable Image Denoising
  • 网络安全赚钱能力提升平台众测平台(个人经常使用的)
  • n8n自动化测试指南(一):环境配置与初探功能
  • PAT乙级_1117 数字之王_Python_AC解法_无疑难点
  • CSS布局 - 网格布局 -- 笔记3
  • OSPF高级技术 相关知识点
  • ​ 真无线蓝牙耳机怎么选?舒适与实用如何兼得?
  • 4. 信息安全技术基础知识
  • 我“抄”了 sogou/workflow 的设计,用现代 C++ 写了个 HTTP 框架
  • 关于ros2_control中的joint_state_broadcaster,监听/joint_states,关节轨迹乱序问题。