Spring + 设计模式 (二十四) 扩展 - 其他设计模式

47 阅读7分钟

扩展设计模式

Gang of Four(GoF)的23种设计模式为软件设计提供了经典解决方案,但现代软件开发中,特定领域(如企业应用、并发、微服务、反应式编程)催生了更多扩展模式。本文深入分析这些扩展设计模式,涵盖创建型、结构型、行为型、企业级、并发型及其他领域特定模式。

1. 创建型模式补充

1.1 对象池模式

用途:通过对象复用降低资源开销,常见于数据库连接池、线程池。

Java源码分析:Java的ThreadPoolExecutorjava.util.concurrent包)是对象池模式的典型实现。

其核心逻辑在execute方法中,通过Worker对象池复用线程:

// java.util.concurrent.ThreadPoolExecutor (简化版)
public class ThreadPoolExecutor extends AbstractExecutorService {
    private final BlockingQueue<Runnable> workQueue;
    private final HashSet<Worker> workers;

    public void execute(Runnable command) {
        if (command == null) throw new NullPointerException();
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true)) return;
        }
        if (isRunning(c) && workQueue.offer(command)) {
            // 将任务放入队列,复用现有Worker
        } else {
            // 拒绝策略
        }
    }

    private boolean addWorker(Runnable firstTask, boolean core) {
        // 创建新Worker并加入workers集合
        Worker w = new Worker(firstTask);
        workers.add(w);
        w.thread.start();
        return true;
    }
}

Spring源码分析:Spring集成HikariCP(com.zaxxer.hikari)作为数据库连接池。

HikariCP的HikariPool通过ConcurrentBag管理连接对象:

// com.zaxxer.hikari.pool.HikariPool
public class HikariPool extends PoolBase {
    private final ConcurrentBag<PoolEntry> sharedList;

    public Connection getConnection() throws SQLException {
        PoolEntry entry = sharedList.borrow(1000, TimeUnit.MILLISECONDS);
        if (entry == null) {
            // 创建新连接
            entry = createPoolEntry();
        }
        return entry.connection;
    }
}

代码示例:

import com.zaxxer.hikari.HikariDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DataSourceConfig {
    @Bean
    public HikariDataSource dataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl("jdbc:mysql://localhost:3306/test");
        ds.setUsername("root");
        ds.setPassword("password");
        ds.setMaximumPoolSize(10);
        return ds;
    }
}

分析:HikariCP通过ConcurrentBag实现高效的连接借用和归还,ThreadPoolExecutor通过BlockingQueueWorker管理任务与线程复用,减少创建/销毁开销。

1.2 静态工厂模式

用途:通过静态方法封装对象创建逻辑,提供灵活性。

Java源码分析:Collections类的emptyList()方法是静态工厂模式的经典实现:

// java.util.Collections
public class Collections {
    private static final List EMPTY_LIST = new EmptyList<>();
    
    @SuppressWarnings("unchecked")
    public static <T> List<T> emptyList() {
        return (List<T>) EMPTY_LIST;
    }

    private static class EmptyList<E> extends AbstractList<E> {
        public int size() { return 0; }
        public boolean isEmpty() { return true; }
        public E get(int index) { throw new IndexOutOfBoundsException(); }
    }
}

代码示例:

import java.util.Collections;
import java.util.List;

public class StaticFactoryExample {
    public static <T> List<T> createEmptyList() {
        return Collections.emptyList();
    }

    public static void main(String[] args) {
        List<String> emptyList = createEmptyList();
        System.out.println("Empty list size: " + emptyList.size());
    }
}

分析:Collections.emptyList()通过返回单例EmptyList避免重复创建,体现了静态工厂模式的封装性

2. 结构型模式补充

2.1 装饰器链(Decorator Chain)

用途:动态扩展功能,常用于I/O流或过滤器链。

Java源码分析:Java的I/O流(如BufferedInputStream)通过装饰器模式实现功能叠加:

// java.io.BufferedInputStream
public class BufferedInputStream extends FilterInputStream {
    protected byte[] buf;

    public BufferedInputStream(InputStream in) {
        super(in);
        buf = new byte[8192];
    }

    public synchronized int read() throws IOException {
        if (pos >= count) {
            fill();
        }
        return buf[pos++] & 0xff;
    }

    private void fill() throws IOException {
        // 从底层InputStream读取数据到缓冲区
        count = in.read(buf, 0, buf.length);
        pos = 0;
    }
}

Spring源码分析:Spring Security的FilterChain通过SecurityFilterChain实现请求的层层处理:

// org.springframework.security.web.FilterChainProxy (简化版)
public class FilterChainProxy implements Filter {
    private List<SecurityFilterChain> filterChains;

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        VirtualFilterChain vfc = new VirtualFilterChain(request, chain, filterChains);
        vfc.doFilter(request, response);
    }

    private static class VirtualFilterChain implements FilterChain {
        private final List<Filter> additionalFilters;
        private int currentPosition = 0;

        public void doFilter(ServletRequest request, ServletResponse response) {
            if (currentPosition == additionalFilters.size()) {
                chain.doFilter(request, response);
            } else {
                Filter nextFilter = additionalFilters.get(currentPosition++);
                nextFilter.doFilter(request, response, this);
            }
        }
    }
}

代码示例:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/public/").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin().and()
            .httpBasic();
    }
}

分析:

  • BufferedInputStream通过缓冲区装饰InputStream,减少底层I/O调用;
  • Spring Security的FilterChain通过动态链式调用实现请求的权限验证、日志等功能,体现了装饰器链的扩展性。

2.2 插件模式

用途:支持动态扩展功能。

Spring示例:Spring Boot的Starter通过SPI加载模块。

代码示例(简化的SPI实现):

// Service接口
public interface Plugin {
    void execute();
}

// 插件实现
public class PluginA implements Plugin {
    @Override
    public void execute() {
        System.out.println("Plugin A executed");
    }
}

// SPI加载
import java.util.ServiceLoader;

public class PluginLoader {
    public static void main(String[] args) {
        ServiceLoader<Plugin> plugins = ServiceLoader.load(Plugin.class);
        for (Plugin plugin : plugins) {
            plugin.execute();
        }
    }
}

3. 行为型模式补充

3.1 依赖注入(Dependency Injection)

用途:解耦组件依赖,Spring的核心机制。

Spring源码分析:Spring的ApplicationContext通过DefaultListableBeanFactory实现依赖注入:

// org.springframework.beans.factory.support.DefaultListableBeanFactory (简化版)
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory {
    
    public Object resolveDependency(DependencyDescriptor descriptor, String beanName) {
        // 解析@Autowired注解的依赖
        Class<?> type = descriptor.getDependencyType();
        Object value = findAutowireCandidate(beanName, type);
        if (value == null) {
            throw new NoSuchBeanDefinitionException(type);
        }
        return value;
    }

    private Object findAutowireCandidate(String beanName, Class<?> requiredType) {
        // 从BeanDefinition中查找匹配的Bean
        String[] candidateNames = getBeanNamesForType(requiredType);
        return getBean(candidateNames[0]);
    }
}

代码示例:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Component
class UserRepository {
    public String findUser() {
        return "User found";
    }
}

@Service
class UserService {
    private final UserRepository repository;

    @Autowired
    public UserService(UserRepository repository) {
        this.repository = repository;
    }

    public String getUser() {
        return repository.findUser();
    }
}

分析:Spring通过DefaultListableBeanFactory解析@Autowired注解,动态注入依赖,解耦了组件间的直接引用,体现了依赖注入的高内聚低耦合特性。

3.2 拦截过滤器模式(Intercepting Filter)

用途:对请求进行预处理,如日志、权限检查。

Spring源码分析:Spring MVC的HandlerInterceptor通过HandlerExecutionChain实现拦截:

// org.springframework.web.servlet.HandlerExecutionChain (简化版)
public class HandlerExecutionChain {
    private final Object handler;
    private final HandlerInterceptor[] interceptors;

    public HandlerExecutionChain(Object handler, HandlerInterceptor[] interceptors) {
        this.handler = handler;
        this.interceptors = interceptors;
    }

    public boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) {
        for (HandlerInterceptor interceptor : interceptors) {
            if (!interceptor.preHandle(request, response, handler)) {
                return false;
            }
        }
        return true;
    }
}

代码示例:

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class LoggingInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        System.out.println("Request URL: " + request.getRequestURL());
        return true;
    }
}

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

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

分析:HandlerExecutionChain通过链式调用HandlerInterceptor,实现请求的预处理(如日志、权限验证),体现了拦截过滤器的模块化设计。

4. 企业级/J2EE模式

企业级模式针对分布式系统,以下深入分析。

4.1 MVC模式

用途:分离模型、视图和控制器。

Spring源码分析:Spring MVC的DispatcherServlet是MVC模式的核心,分发请求到控制器:

// org.springframework.web.servlet.DispatcherServlet (简化版)
public class DispatcherServlet extends FrameworkServlet {
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HandlerMapping handlerMapping = getHandlerMapping();
        HandlerAdapter ha = getHandlerAdapter(handler);
        ModelAndView mv = ha.handle(request, response, handler);
        render(mv, request, response);
    }

    protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) {
        // 渲染视图(如Thymeleaf)
        View view = mv.getView();
        view.render(mv.getModel(), request, response);
    }
}

代码示例:

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {
    @GetMapping("/")
    public String home(Model model) {
        model.addAttribute("message", "Welcome to Spring MVC!");
        return "home";
    }
}

home.html(Thymeleaf):

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Home</title>
</head>
<body>
    <h1 th:text="${message}"></h1>
</body>
</html>

分析:DispatcherServlet通过HandlerMappingHandlerAdapter解耦控制器与视图,Thymeleaf处理动态渲染,体现了MVC的分离关注点。

4.2 数据访问对象模式(DAO)

用途:抽象数据库操作。

Spring Data JPA示例:

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
    User findByUsername(String username);
}

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    private Long id;
    private String username;

    // Getters and setters
}

5. 并发型模式

5.1 生产者-消费者模式

用途:通过缓冲区协调线程。

Java源码分析:BlockingQueue(如LinkedBlockingQueue)是生产者-消费者模式的核心:

// java.util.concurrent.LinkedBlockingQueue (简化版)
public class LinkedBlockingQueue<E> extends AbstractQueue<E> {
    private final LinkedList<E> items;

    public void put(E e) throws InterruptedException {
        lock.lockInterruptibly();
        try {
            items.addLast(e);
            notEmpty.signal();
        } finally {
            lock.unlock();
        }
    }

    public E take() throws InterruptedException {
        lock.lockInterruptibly();
        try {
            while (items.isEmpty()) notEmpty.await();
            return items.removeFirst();
        } finally {
            lock.unlock();
        }
    }
}

代码示例:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class ProducerConsumerExample {
    public static void main(String[] args) {
        BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(5);
        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    queue.put(i);
                    System.out.println("Produced: " + i);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();

        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    System.out.println("Consumed: " + queue.take());
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
    }
}

分析:LinkedBlockingQueue通过锁和条件变量(notEmpty)实现线程安全的生产者-消费者通信,Spring的TaskExecutor也常用于类似场景。

5.2 读写锁模式

用途:优化读写并发。

Java示例:

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockExample {
    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    private String data = "Initial data";

    public String read() {
        lock.readLock().lock();
        try {
            return data;
        } finally {
            lock.readLock().unlock();
        }
    }

    public void write(String newData) {
        lock.writeLock().lock();
        try {
            this.data = newData;
        } finally {
            lock.writeLock().unlock();
        }
    }
}

6. 其他领域特定模式

6.1 反应式模式

用途:支持事件驱动的非阻塞编程。

Spring源码分析:Spring WebFlux的Mono基于Reactor实现反应式流:

// reactor.core.publisher.Mono (简化版)
public abstract class Mono<T> implements Publisher<T> {
    public static <T> Mono<T> just(T data) {
        return new MonoJust<>(data);
    }

    public Mono<T> map(Function<? super T, ? extends R> mapper) {
        return new MonoMap<>(this, mapper);
    }
}

代码示例:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@RestController
public class ReactiveController {
    @GetMapping("/reactive")
    public Mono<String> getData() {
        return Mono.just("Hello from WebFlux!")
                   .map(s -> s.toUpperCase());
    }
}

分析:Mono通过链式操作(如map)实现非阻塞数据流,Spring WebFlux将其应用于高并发场景,体现了反应式模式的异步特性。

6.2 微服务模式:断路器模式

用途:防止服务雪崩。

Spring Cloud Resilience4j示例:

import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import org.springframework.stereotype.Service;

@Service
public class CircuitBreakerService {
    @CircuitBreaker(name = "backendService", fallbackMethod = "fallback")
    public String callExternalService() {
        // 模拟外部服务调用
        throw new RuntimeException("Service unavailable");
    }

    public String fallback(Throwable t) {
        return "Fallback response: " + t.getMessage();
    }
}

总结

扩展设计模式是GoF 23种经典模式的“进阶装备”,专为现代软件开发的硬核挑战打造,覆盖微服务、高并发、反应式编程和企业级应用等场景。它们通过对象池(像HikariCP复用数据库连接)、依赖注入(Spring IoC解耦组件)、断路器(Resilience4j防服务雪崩)等“骚操作”,大幅提升代码的模块化、性能和稳定性。这些模式不仅优化资源利用,还让系统更抗压、易扩展,完美适配分布式系统和云原生开发的节奏。在Spring框架的源码里,这些模式无处不在——BeanFactory的静态工厂封装创建逻辑、FilterChain的装饰器链动态扩展功能、Mono的反应式流应对异步场景,堪称开发者的“效率倍增器”。通过这些模式,开发者能少踩坑、多省心,写出既能“跑得快”又好维护的代码,轻松应对从单机到云端的各种复杂需求,让系统真正“硬核”且“未来可期”!

(对您有帮助 && 觉得我总结的还行) -> 受累点个免费的赞👍,谢谢