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

五种高频设计模式及其在 Spring 中的应用揭秘

五种高频设计模式及其在 Spring 中的应用揭秘

1. 适配器模式(Adapter Pattern)

模式简介

适配器模式是一种结构型设计模式,通过将一个接口转换为客户端期望的另一个接口,使得原本不兼容的接口可以协同工作。它的核心作用在于兼容性适配,解决“老接口”和“新需求”的冲突。

模式结构
  • 目标接口:客户端期望使用的接口。
  • 适配器类:实现目标接口,并持有被适配者的引用,将被适配者的方法转换为目标接口的方法。
  • 被适配者:需要适配的类,其接口与目标接口不兼容。
使用场景
  • 将旧系统的接口适配到新系统中。
  • 为现有类提供新接口。
  • 统一多种接口,提供通用方法。
Java 示例代码

需求描述:将一种老式日志格式适配为新式格式。

// 目标接口:新日志格式
public interface NewLogger {
    void log(String message);
}

// 被适配者:老式日志格式
public class OldLogger {
    public void writeLog(String msg) {
        System.out.println("Old Logger: " + msg);
    }
}

// 适配器类:适配老式日志为新格式
public class LoggerAdapter implements NewLogger {
    private final OldLogger oldLogger;

    public LoggerAdapter(OldLogger oldLogger) {
        this.oldLogger = oldLogger;
    }

    @Override
    public void log(String message) {
        oldLogger.writeLog(message);  // 调用老式日志的实现
    }
}
在 Spring 框架中的应用

Spring 的 HandlerAdapter 是适配器模式的经典实现,用于适配不同类型的控制器到统一的处理逻辑。例如:

  • SimpleControllerHandlerAdapter:适配实现了 Controller 接口的控制器。
  • RequestMappingHandlerAdapter:适配标注了 @RequestMapping 的控制器方法。

核心代码:

public interface HandlerAdapter {
    boolean supports(Object handler);  // 检查适配器是否支持某个处理器
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}

通过适配器,Spring 能够支持多种控制器类型,提升框架的灵活性和扩展性。


2. 装饰器模式(Decorator Pattern)

模式简介

装饰器模式通过为对象动态地添加职责,而不是通过继承来扩展功能。它允许我们按照需求组合功能,从而实现高效的功能扩展。

模式结构
  • 组件接口:定义核心功能。
  • 具体组件:核心功能的实现类。
  • 装饰器类:实现组件接口,并包含对核心组件的引用,用于动态扩展功能。
  • 具体装饰器:实现特定扩展功能。
使用场景
  • 动态为对象添加功能(如 I/O 流)。
  • 需要在不改变原始类的前提下扩展功能。
Java 示例代码

需求描述:在发送通知前后添加日志功能。

// 抽象组件
public interface Notifier {
    void send(String message);
}

// 具体组件:基本通知实现
public class EmailNotifier implements Notifier {
    @Override
    public void send(String message) {
        System.out.println("发送邮件通知: " + message);
    }
}

// 装饰器基类
public abstract class NotifierDecorator implements Notifier {
    protected final Notifier notifier;

    public NotifierDecorator(Notifier notifier) {
        this.notifier = notifier;
    }
}

// 具体装饰器:添加日志功能
public class LoggingNotifierDecorator extends NotifierDecorator {
    public LoggingNotifierDecorator(Notifier notifier) {
        super(notifier);
    }

    @Override
    public void send(String message) {
        System.out.println("日志:开始发送通知...");
        notifier.send(message);  // 调用被装饰对象的方法
        System.out.println("日志:通知发送完毕!");
    }
}
在 Spring 框架中的应用

Spring 中的 BeanPostProcessorSpring Security 的过滤器链体现了装饰器模式:

  • BeanPostProcessor:在 Bean 初始化前后动态添加行为。

    示例代码:

    public class LoggingBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("初始化前日志:" + beanName);
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("初始化后日志:" + beanName);
            return bean;
        }
    }
    

3. 观察者模式(Observer Pattern)

模式简介

观察者模式定义了一种一对多的依赖关系,当被观察对象的状态发生变化时,所有观察者会自动收到通知。它是事件驱动模型的基础。

模式结构
  • 主题(Subject):被观察的对象,维护观察者列表。
  • 观察者(Observer):需要被通知的对象。
  • 具体主题和具体观察者:实现主题和观察者接口的类。
使用场景
  • GUI 事件监听。
  • 数据变化通知机制。
  • 发布/订阅系统。
Java 示例代码

需求描述:实现一个简单的事件通知机制。

// 主题接口
public interface Subject {
    void attach(Observer observer);
    void detach(Observer observer);
    void notifyObservers(String message);
}

// 观察者接口
public interface Observer {
    void update(String message);
}

// 具体主题
public class NewsPublisher implements Subject {
    private final List<Observer> observers = new ArrayList<>();

    @Override
    public void attach(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void detach(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

// 具体观察者
public class Subscriber implements Observer {
    private final String name;

    public Subscriber(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " 收到消息: " + message);
    }
}
在 Spring 框架中的应用

Spring 的事件驱动模型基于观察者模式:

  • ApplicationEvent:事件基类。
  • ApplicationListener:监听器接口。
  • ApplicationEventPublisher:事件发布器。

示例:

@Component
public class MyEventListener implements ApplicationListener<MyEvent> {
    @Override
    public void onApplicationEvent(MyEvent event) {
        System.out.println("监听到事件: " + event.getMessage());
    }
}

public class MyEvent extends ApplicationEvent {
    private final String message;

    public MyEvent(Object source, String message) {
        super(source);
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

4. 构建者模式(Builder Pattern)

模式简介

构建者模式通过分步构建复杂对象,将对象创建过程与其表示分离,特别适用于构建复杂对象。

模式结构
  • 产品(Product):要构建的复杂对象。
  • 构建者(Builder):定义构建产品的方法。
  • 具体构建者(ConcreteBuilder):实现构建过程。
  • 指导者(Director):指导构建者构建产品。
Java 示例代码
// 产品类
public class Computer {
    private String cpu;
    private String gpu;

    public static class Builder {
        private String cpu;
        private String gpu;

        public Builder cpu(String cpu) {
            this.cpu = cpu;
            return this;
        }

        public Builder gpu(String gpu) {
            this.gpu = gpu;
            return this;
        }

        public Computer build() {
            Computer computer = new Computer();
            computer.cpu = this.cpu;
            computer.gpu = this.gpu;
            return computer;
        }
    }
}
在 Spring 框架中的应用

Spring 中的 BeanDefinitionBuilder 是构建者模式的典型应用,用于动态定义 Bean:

BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MyBean.class);
builder.addPropertyValue("name", "Spring");
builder.addPropertyValue("version", "5.x");

5. 责任链模式(Chain of Responsibility Pattern)

模式结构
  • 处理者接口(Handler):定义处理请求的方法。
  • 具体处理者(ConcreteHandler):实现处理逻辑,并决定是否将请求传递给下一个处理者。
  • 责任链:由多个处理者组成,按照顺序处理请求。
使用场景
  • 当多个对象都有可能处理同一请求时,将这些对象连成一条链,按顺序处理请求。
  • 需要动态组合处理逻辑,但又不希望硬编码逻辑的顺序。
Java 示例代码

需求描述:一个日志处理系统,根据日志的级别分别由不同的处理者处理。

// 处理者接口
public abstract class LogHandler {
    protected LogHandler nextHandler;  // 下一个处理者

    public void setNextHandler(LogHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    public abstract void handle(String message, String level);
}

// 具体处理者:Debug日志处理
public class DebugLogHandler extends LogHandler {
    @Override
    public void handle(String message, String level) {
        if ("DEBUG".equalsIgnoreCase(level)) {
            System.out.println("DEBUG日志处理: " + message);
        } else if (nextHandler != null) {
            nextHandler.handle(message, level);
        }
    }
}

// 具体处理者:Error日志处理
public class ErrorLogHandler extends LogHandler {
    @Override
    public void handle(String message, String level) {
        if ("ERROR".equalsIgnoreCase(level)) {
            System.out.println("ERROR日志处理: " + message);
        } else if (nextHandler != null) {
            nextHandler.handle(message, level);
        }
    }
}

// 测试
public class LogHandlerTest {
    public static void main(String[] args) {
        // 创建处理链
        LogHandler debugHandler = new DebugLogHandler();
        LogHandler errorHandler = new ErrorLogHandler();
        debugHandler.setNextHandler(errorHandler);

        // 测试责任链
        debugHandler.handle("系统调试信息", "DEBUG");
        debugHandler.handle("系统错误信息", "ERROR");
        debugHandler.handle("未知级别日志", "INFO");  // 无处理者
    }
}

输出结果:

DEBUG日志处理: 系统调试信息
ERROR日志处理: 系统错误信息
在 Spring 框架中的应用

Spring 中责任链模式的应用非常广泛,以下是两个经典场景:

  1. Spring Security 的过滤器链

    • 在 Spring Security 中,FilterChainProxy 管理着一系列的安全过滤器。每个过滤器完成特定的职责,例如认证、授权或日志记录。
    • 这些过滤器按顺序组成责任链,当请求进入时,依次通过这些过滤器进行处理,直到过滤器链末端。

    配置示例:

    <http>
        <custom-filter position="FORM_LOGIN_FILTER" ref="myCustomFilter"/>
    </http>
    

    代码实现:

    public class MyCustomFilter extends GenericFilterBean {
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            // 在此处处理请求逻辑
            System.out.println("自定义过滤器处理请求...");
            chain.doFilter(request, response);  // 传递给下一个过滤器
        }
    }
    
  2. Spring MVC 的拦截器链

    • Spring MVC 的 HandlerInterceptor 提供了一个类似责任链模式的机制,用于在请求处理的不同阶段添加逻辑,例如请求前的权限校验或请求后的日志记录。

    示例代码:

    public class MyInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("前置处理逻辑...");
            return true;  // 返回 false 则中断请求链
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("后置处理逻辑...");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("完成处理逻辑...");
        }
    }
    

    注册拦截器:

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new MyInterceptor());
        }
    }
    

总结

通过本文,我们详细解读了五种常见设计模式在 Spring 框架中的应用:

  1. 适配器模式:用于将不同接口适配到统一接口(如 Spring 的 HandlerAdapter)。
  2. 装饰器模式:动态扩展对象功能(如 BeanPostProcessor)。
  3. 观察者模式:实现事件驱动机制(如 ApplicationListener)。
  4. 构建者模式:构建复杂对象(如 BeanDefinitionBuilder)。
  5. 责任链模式:组织多步骤处理(如 Spring Security 的过滤器链、Spring MVC 的拦截器链)。

设计模式在 Spring 中无处不在,理解并灵活运用这些模式,能够帮助开发者更深入地理解框架设计思想,并提升代码质量和系统的可维护性。建议在实际开发中多多关注框架源码中的设计模式应用,实践中不断提升自己的设计能力。


http://www.kler.cn/a/516078.html

相关文章:

  • 如何实现各种类型的进度条
  • Qt Creator 15.0.0如何更换主题和字体
  • SQL-leetcode—1141. 查询近30天活跃用户数
  • 【若依】添加数据字典
  • 麒麟监控工具rpm下载
  • 3.1 Go函数调用过程
  • Git克隆 提示证书验证失败解决
  • Python OrderedDict 实现 Least Recently used(LRU)缓存
  • 【易康eCognition实验教程】002:创建工作空间、工程
  • 分布式光纤应变监测是一种高精度、分布式的监测技术
  • element tbas增加下拉框
  • Windows Server 虚拟化环境中SR-IOV网络I/O增强功能
  • HTML5 常用事件详解
  • JavaScript图像处理,常用图像边缘检测算法简单介绍说明
  • 51 单片机矩阵键盘密码锁:原理、实现与应用
  • 微信小程序中实现进入页面时数字跳动效果(自定义animate-numbers组件)
  • 前后端交互过程
  • mysql my.ini 配置参数结束
  • 高性能队列 Disruptor 在 IM 系统中的实战
  • Linux进程间通信(补充)
  • 用 Java 发送 HTML 内容并带附件的电子邮件
  • Unity3D基于Unity整合BEPUphysicsint物理引擎实战详解
  • 系统相关类——java.lang.Math (三)(案例详细拆解小白友好)
  • 开发思维到业务思维的转变
  • go学习杂记
  • proxysql读写分离的部署