设计模式-17策略模式 (Strategy Pattern) 源码实例大全

Java接口源码深度解析:从Function接口看Lambda实现与设计模式 在Java编程中,接口作为定义行为契约的核心机制,其设计原理深刻影响着代码架构。从概念层面看,接口通过抽象方法定义规范,而函数式接口则进一步支持Lambda表达式,这是Java函数式编程的基础。其实现原理涉及JVM的invokedynamic指令,该指令在运行时动态生成实现类,相比传统匿名内部类具有显著的性能优势,包括惰性加载和实例复用。这种技术价值在于提升了代码的简洁性和执行效率,同时为设计模式如策略模式、装饰器模式提供了优雅的实现方式。在应用场景上,接口广泛应用于Java标准库的Stream API、集 阅读详情

策略模式 (Strategy Pattern) 源码实例大全

模式定义

定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。

框架源码实例

1. Java Standard Library

Comparator Strategy Pattern
// Java比较器策略模式 - 策略接口
@FunctionalInterface
public interface Comparator<T> {
    
    // 比较两个对象
    int compare(T o1, T o2);
    
    // 默认方法 - 反转比较顺序
    default Comparator<T> reversed() {
        return Collections.reverseOrder(this);
    }
    
    // 默认方法 - 链式比较
    default Comparator<T> thenComparing(Comparator<? super T> other) {
        Objects.requireNonNull(other);
        return (Comparator<T> & Serializable) (c1, c2) -> {
            int res = compare(c1, c2);
            return (res != 0) ? res : other.compare(c1, c2);
        };
    }
}

// 具体策略 - 用户年龄比较器
public class UserAgeComparator implements Comparator<User> {
    
    @Override
    public int compare(User u1, User u2) {
        return Integer.compare(u1.getAge(), u2.getAge());
    }
}

// 具体策略 - 用户姓名比较器
public class UserNameComparator implements Comparator<User> {
    
    @Override
    public int compare(User u1, User u2) {
        return u1.getName().compareTo(u2.getName());
    }
}

// 具体策略 - 用户注册时间比较器
public class UserRegistrationDateComparator implements Comparator<User> {
    
    @Override
    public int compare(User u1, User u2) {
        return u1.getRegistrationDate().compareTo(u2.getRegistrationDate());
    }
}

// 具体策略 - 复合比较器
public class UserCompositeComparator implements Comparator<User> {
    
    private final List<Comparator<User>> comparators;
    
    public UserCompositeComparator(List<Comparator<User>> comparators) {
        this.comparators = comparators;
    }
    
    @Override
    public int compare(User u1, User u2) {
        for (Comparator<User> comparator : comparators) {
            int result = comparator.compare(u1, u2);
            if (result != 0) {
                return result;
            }
        }
        return 0;
    }
}

// 上下文 - 用户服务
public class UserService {
    
    private List<User> users = new ArrayList<>();
    private Comparator<User> currentComparator = new UserNameComparator();
    
    public void addUser(User user) {
        users.add(user);
    }
    
    public void setSortingStrategy(Comparator<User> comparator) {
        this.currentComparator = comparator;
    }
    
    public List<User> getSortedUsers() {
        List<User> sortedUsers = new ArrayList<>(users);
        sortedUsers.sort(currentComparator);
        return sortedUsers;
    }
    
    public List<User> getUsersSortedByAge() {
        List<User> sortedUsers = new ArrayList<>(users);
        sortedUsers.sort(new UserAgeComparator());
        return sortedUsers;
    }
    
    public List<User> getUsersSortedByRegistrationDate() {
        List<User> sortedUsers = new ArrayList<>(users);
        sortedUsers.sort(new UserRegistrationDateComparator());
        return sortedUsers;
    }
}
ThreadFactory Strategy Pattern
// Java线程工厂策略模式 - 策略接口
public interface ThreadFactory {
    
    // 创建新线程
    Thread newThread(Runnable r);
}

// 具体策略 - 默认线程工厂
public class DefaultThreadFactory implements ThreadFactory {
    
    private static final AtomicInteger poolNumber = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;
    
    public DefaultThreadFactory() {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
        namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-";
    }
    
    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
        if (t.isDaemon()) {
            t.setDaemon(false);
        }
        if (t.getPriority() != Thread.NORM_PRIORITY) {
            t.setPriority(Thread.NORM_PRIORITY);
        }
        return t;
    }
}

// 具体策略 - 守护线程工厂
public class DaemonThreadFactory implements ThreadFactory {
    
    private final String namePrefix;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    
    public DaemonThreadFactory(String namePrefix) {
        this.namePrefix = namePrefix;
    }
    
    @Override
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r, namePrefix + "-" + threadNumber.getAndIncrement());
        thread.setDaemon(true);
        return thread;
    }
}

// 具体策略 - 优先级线程工厂
public class PriorityThreadFactory implements ThreadFactory {
    
    private final int priority;
    private final String namePrefix;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    
    public PriorityThreadFactory(int priority, String namePrefix) {
        this.priority = priority;
        this.namePrefix = namePrefix;
    }
    
    @Override
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r, namePrefix + "-" + threadNumber.getAndIncrement());
        thread.setPriority(priority);
        return thread;
    }
}

// 具体策略 - 异常处理线程工厂
public class ExceptionHandlingThreadFactory implements ThreadFactory {
    
    private final ThreadFactory delegate;
    private final Thread.UncaughtExceptionHandler exceptionHandler;
    
    public ExceptionHandlingThreadFactory(ThreadFactory delegate, Thread.UncaughtExceptionHandler exceptionHandler) {
        this.delegate = delegate;
        this.exceptionHandler = exceptionHandler;
    }
    
    @Override
    public Thread newThread(Runnable r) {
        Thread thread = delegate.newThread(r);
        thread.setUncaughtExceptionHandler(exceptionHandler);
        return thread;
    }
}

// 上下文 - 线程池管理器
public class ThreadPoolManager {
    
    private final ThreadFactory threadFactory;
    private final ExecutorService executorService;
    
    public ThreadPoolManager(int poolSize, ThreadFactory threadFactory) {
        this.threadFactory = threadFactory;
        this.executorService = Executors.newFixedThreadPool(poolSize, threadFactory);
    }
    
    public void executeTask(Runnable task) {
        executorService.execute(task);
    }
    
    public Future<?> submitTask(Runnable task) {
        return executorService.submit(task);
    }
    
    public <T> Future<T> submitTask(Callable<T> task) {
        return executorService.submit(task);
    }
    
    public void shutdown() {
        executorService.shutdown();
    }
}

2. Apache Commons Codec

Encoding Strategy Pattern
// Apache Commons Codec编码策略模式 - 策略接口
public interface Encoder {
    
    // 编码对象
    Object encode(Object source) throws EncoderException;
}

// 具体策略 - Base64编码器
public class Base64Encoder implements Encoder {
    
    @Override
    public Object encode(Object source) throws EncoderException {
        if (!(source instanceof String)) {
            throw new EncoderException("Base64Encoder can only encode String objects");
        }
        return Base64.getEncoder().encodeToString(((String) source).getBytes(StandardCharsets.UTF_8));
    }
}

// 具体策略 - URL编码器
public class URLEncoder implements Encoder {
    
    @Override
    public Object encode(Object source) throws EncoderException {
        if (!(source instanceof String)) {
            throw new EncoderException("URLEncoder can only encode String objects");
        }
        try {
            return java.net.URLEncoder.encode((String) source, StandardCharsets.UTF_8.name());
        } catch (UnsupportedEncodingException e) {
            throw new EncoderException("URL encoding failed", e);
        }
    }
}

// 具体策略 - MD5编码器
public class MD5Encoder implements Encoder {
    
    @Override
    public Object encode(Object source) throws EncoderException {
        if (!(source instanceof String)) {
            throw new EncoderException("MD5Encoder can only encode String objects");
        }
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(((String) source).getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new EncoderException("MD5 algorithm not available", e);
        }
    }
}

// 具体策略 - SHA256编码器
public class SHA256Encoder implements Encoder {
    
    @Override
    public Object encode(Object source) throws EncoderException {
        if (!(source instanceof String)) {
            throw new EncoderException("SHA256Encoder can only encode String objects");
        }
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] digest = md.digest(((String) source).getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            throw new EncoderException("SHA-256 algorithm not available", e);
        }
    }
}

// 上下文 - 编码服务
public class EncodingService {
    
    private Encoder currentEncoder = new Base64Encoder();
    
    public void setEncodingStrategy(Encoder encoder) {
        this.currentEncoder = encoder;
    }
    
    public String encode(String input) throws EncoderException {
        return (String) currentEncoder.encode(input);
    }
    
    public Map<String, String> encodeWithAllStrategies(String input) throws EncoderException {
        Map<String, String> results = new HashMap<>();
        
        results.put("Base64", (String) new Base64Encoder().encode(input));
        results.put("URL", (String) new URLEncoder().encode(input));
        results.put("MD5", (String) new MD5Encoder().encode(input));
        results.put("SHA256", (String) new SHA256Encoder().encode(input));
        
        return results;
    }
}

3. Google Guava

Cache Strategy Pattern
// Google Guava缓存策略模式 - 策略接口
public interface CacheLoader<K, V> {
    
    // 加载缓存项
    V load(K key) throws Exception;
    
    // 批量加载缓存项
    Map<K, V> loadAll(Iterable<? extends K> keys) throws Exception;
}

// 具体策略 - 用户缓存加载器
public class UserCacheLoader extends CacheLoader<Long, User> {
    
    private final UserRepository userRepository;
    private final Logger logger = LoggerFactory.getLogger(UserCacheLoader.class);
    
    public UserCacheLoader(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    @Override
    public User load(Long userId) throws Exception {
        logger.debug("Loading user from database: {}", userId);
        User user = userRepository.findById(userId);
        if (user == null) {
            throw new Exception("User not found: " + userId);
        }
        return user;
    }
    
    @Override
    public Map<Long, User> loadAll(Iterable<? extends Long> userIds) throws Exception {
        logger.debug("Loading multiple users from database: {}", userIds);
        Map<Long, User> users = new HashMap<>();
        for (Long userId : userIds) {
            users.put(userId, load(userId));
        }
        return users;
    }
}

// 具体策略 - 产品缓存加载器
public class ProductCacheLoader extends CacheLoader<String, Product> {
    
    private final ProductRepository productRepository;
    private final Logger logger = LoggerFactory.getLogger(ProductCacheLoader.class);
    
    public ProductCacheLoader(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }
    
    @Override
    public Product load(String productCode) throws Exception {
        logger.debug("Loading product from database: {}", productCode);
        Product product = productRepository.findByCode(productCode);
        if (product == null) {
            throw new Exception("Product not found: " + productCode);
        }
        return product;
    }
    
    @Override
    public Map<String, Product> loadAll(Iterable<? extends String> productCodes) throws Exception {
        logger.debug("Loading multiple products from database: {}", productCodes);
        Map<String, Product> products = new HashMap<>();
        for (String productCode : productCodes) {
            products.put(productCode, load(productCode));
        }
        return products;
    }
}

// 具体策略 - 配置缓存加载器
public class ConfigurationCacheLoader extends CacheLoader<String, String> {
    
    private final ConfigurationRepository configurationRepository;
    private final Logger logger = LoggerFactory.getLogger(ConfigurationCacheLoader.class);
    
    public ConfigurationCacheLoader(ConfigurationRepository configurationRepository) {
        this.configurationRepository = configurationRepository;
    }
    
    @Override
    public String load(String configKey) throws Exception {
        logger.debug("Loading configuration from database: {}", configKey);
        String value = configurationRepository.getValue(configKey);
        if (value == null) {
            throw new Exception("Configuration not found: " + configKey);
        }
        return value;
    }
    
    @Override
    public Map<String, String> loadAll(Iterable<? extends String> configKeys) throws Exception {
        logger.debug("Loading multiple configurations from database: {}", configKeys);
        Map<String, String> configs = new HashMap<>();
        for (String configKey : configKeys) {
            configs.put(configKey, load(configKey));
        }
        return configs;
    }
}

// 上下文 - 缓存管理器
public class CacheManager<K, V> {
    
    private final Cache<K, V> cache;
    private final CacheLoader<K, V> cacheLoader;
    
    public CacheManager(CacheLoader<K, V> cacheLoader, long maximumSize, long expireAfterWrite, TimeUnit timeUnit) {
        this.cacheLoader = cacheLoader;
        this.cache = CacheBuilder.newBuilder()
                .maximumSize(maximumSize)
                .expireAfterWrite(expireAfterWrite, timeUnit)
                .build(cacheLoader);
    }
    
    public V get(K key) throws ExecutionException {
        return cache.get(key);
    }
    
    public Map<K, V> getAll(Iterable<? extends K> keys) throws ExecutionException {
        return cache.getAll(keys);
    }
    
    public void put(K key, V value) {
        cache.put(key, value);
    }
    
    public void invalidate(K key) {
        cache.invalidate(key);
    }
    
    public void invalidateAll() {
        cache.invalidateAll();
    }
    
    public long size() {
        return cache.size();
    }
    
    public CacheStats stats() {
        return cache.stats();
    }
}
Rate Limiting Strategy Pattern
// Google Guava限流策略模式 - 策略接口
public interface RateLimiter {
    
    // 获取许可
    boolean tryAcquire();
    
    // 获取指定数量的许可
    boolean tryAcquire(int permits);
    
    // 阻塞获取许可
    void acquire();
    
    // 获取当前速率
    double getRate();
}

// 具体策略 - 平滑突发限流器
public class SmoothBurstyRateLimiter implements RateLimiter {
    
    private final com.google.common.util.concurrent.RateLimiter guavaRateLimiter;
    private final Logger logger = LoggerFactory.getLogger(SmoothBurstyRateLimiter.class);
    
    public SmoothBurstyRateLimiter(double permitsPerSecond) {
        this.guavaRateLimiter = com.google.common.util.concurrent.RateLimiter.create(permitsPerSecond);
        logger.info("Created SmoothBurstyRateLimiter with rate: {} permits/second", permitsPerSecond);
    }
    
    @Override
    public boolean tryAcquire() {
        boolean acquired = guavaRateLimiter.tryAcquire();
        logger.debug("Try acquire permit: {}", acquired);
        return acquired;
    }
    
    @Override
    public boolean tryAcquire(int permits) {
        boolean acquired = guavaRateLimiter.tryAcquire(permits);
        logger.debug("Try acquire {} permits: {}", permits, acquired);
        return acquired;
    }
    
    @Override
    public void acquire() {
        logger.debug("Blocking acquire permit");
        guavaRateLimiter.acquire();
    }
    
    @Override
    public double getRate() {
        return guavaRateLimiter.getRate();
    }
}

// 具体策略 - 平滑预热限流器
public class SmoothWarmingUpRateLimiter implements RateLimiter {
    
    private final com.google.common.util.concurrent.RateLimiter guavaRateLimiter;
    private final Logger logger = LoggerFactory.getLogger(SmoothWarmingUpRateLimiter.class);
    
    public SmoothWarmingUpRateLimiter(double permitsPerSecond, long warmupPeriod, TimeUnit unit) {
        this.guavaRateLimiter = com.google.common.util.concurrent.RateLimiter.create(permitsPerSecond, warmupPeriod, unit);
        logger.info("Created SmoothWarmingUpRateLimiter with rate: {} permits/second, warmup: {} {}", 
                   permitsPerSecond, warmupPeriod, unit);
    }
    
    @Override
    public boolean tryAcquire() {
        boolean acquired = guavaRateLimiter.tryAcquire();
        logger.debug("Try acquire permit: {}", acquired);
        return acquired;
    }
    
    @Override
    public boolean tryAcquire(int permits) {
        boolean acquired = guavaRateLimiter.tryAcquire(permits);
        logger.debug("Try acquire {} permits: {}", permits, acquired);
        return acquired;
    }
    
    @Override
    public void acquire() {
        logger.debug("Blocking acquire permit");
        guavaRateLimiter.acquire();
    }
    
    @Override
    public double getRate() {
        return guavaRateLimiter.getRate();
    }
}

// 具体策略 - 令牌桶限流器
public class TokenBucketRateLimiter implements RateLimiter {
    
    private final AtomicInteger tokens;
    private final int capacity;
    private final double refillRate;
    private final ScheduledExecutorService scheduler;
    private final Logger logger = LoggerFactory.getLogger(TokenBucketRateLimiter.class);
    
    public TokenBucketRateLimiter(int capacity, double refillRatePerSecond) {
        this.capacity = capacity;
        this.tokens = new AtomicInteger(capacity);
        this.refillRate = refillRatePerSecond;
        this.scheduler = Executors.newSingleThreadScheduledExecutor();
        
        // 定期补充令牌
        long refillInterval = (long) (1000 / refillRatePerSecond);
        scheduler.scheduleAtFixedRate(this::refillTokens, refillInterval, refillInterval, TimeUnit.MILLISECONDS);
        
        logger.info("Created TokenBucketRateLimiter with capacity: {}, refill rate: {} tokens/second", 
                   capacity, refillRatePerSecond);
    }
    
    private void refillTokens() {
        int currentTokens = tokens.get();
        int newTokens = Math.min(capacity, currentTokens + 1);
        if (tokens.compareAndSet(currentTokens, newTokens)) {
            logger.debug("Refilled token, current tokens: {}", newTokens);
        }
    }
    
    @Override
    public boolean tryAcquire() {
        return tryAcquire(1);
    }
    
    @Override
    public boolean tryAcquire(int permits) {
        while (true) {
            int current = tokens.get();
            if (current < permits) {
                logger.debug("Not enough tokens, current: {}, requested: {}", current, permits);
                return false;
            }
            if (tokens.compareAndSet(current, current - permits)) {
                logger.debug("Acquired {} tokens, remaining: {}", permits, current - permits);
                return true;
            }
        }
    }
    
    @Override
    public void acquire() {
        while (!tryAcquire()) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException("Interrupted while waiting for tokens", e);
            }
        }
    }
    
    @Override
    public double getRate() {
        return refillRate;
    }
    
    public void shutdown() {
        scheduler.shutdown();
    }
}

// 上下文 - API限流器
public class ApiRateLimiter {
    
    private final Map<String, RateLimiter> endpointLimiters = new ConcurrentHashMap<>();
    private final RateLimiter defaultLimiter;
    
    public ApiRateLimiter(double defaultRate) {
        this.defaultLimiter = new SmoothBurstyRateLimiter(defaultRate);
    }
    
    public void addEndpointLimiter(String endpoint, RateLimiter limiter) {
        endpointLimiters.put(endpoint, limiter);
    }
    
    public boolean tryAcquire(String endpoint) {
        RateLimiter limiter = endpointLimiters.getOrDefault(endpoint, defaultLimiter);
        return limiter.tryAcquire();
    }
    
    public boolean tryAcquire(String endpoint, int permits) {
        RateLimiter limiter = endpointLimiters.getOrDefault(endpoint, defaultLimiter);
        return limiter.tryAcquire(permits);
    }
    
    public void acquire(String endpoint) {
        RateLimiter limiter = endpointLimiters.getOrDefault(endpoint, defaultLimiter);
        limiter.acquire();
    }
    
    public double getRate(String endpoint) {
        RateLimiter limiter = endpointLimiters.getOrDefault(endpoint, defaultLimiter);
        return limiter.getRate();
    }
}

4. Apache HttpClient

Redirect Strategy Pattern
// Apache HttpClient重定向策略模式 - 策略接口
public interface RedirectStrategy {
    
    // 判断是否自动重定向
    boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException;
    
    // 获取重定向位置
    HttpUriRequest getRedirect(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException;
}

// 具体策略 - 默认重定向策略
public class DefaultRedirectStrategy implements RedirectStrategy {
    
    private final Logger logger = LoggerFactory.getLogger(DefaultRedirectStrategy.class);
    
    @Override
    public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException {
        Args.notNull(request, "HTTP request");
        Args.notNull(response, "HTTP response");
        
        int statusCode = response.getStatusLine().getStatusCode();
        String method = request.getRequestLine().getMethod();
        Header locationHeader = response.getFirstHeader("location");
        
        switch (statusCode) {
            case HttpStatus.SC_MOVED_TEMPORARILY:
            case HttpStatus.SC_MOVED_PERMANENTLY:
            case HttpStatus.SC_TEMPORARY_REDIRECT:
                return isRedirectable(method) && locationHeader != null;
            case HttpStatus.SC_SEE_OTHER:
                return locationHeader != null;
            default:
                return false;
        }
    }
    
    @Override
    public HttpUriRequest getRedirect(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException {
        URI location = createLocationURI(response.getFirstHeader("location").getValue());
        String method = request.getRequestLine().getMethod();
        
        if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
            return new HttpHead(location);
        } else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
            return new HttpGet(location);
        } else {
            int status = response.getStatusLine().getStatusCode();
            if (status == HttpStatus.SC_TEMPORARY_REDIRECT || status == HttpStatus.SC_SEE_OTHER) {
                return new HttpGet(location);
            } else {
                return RequestBuilder.copy(request).setUri(location).build();
            }
        }
    }
    
    protected boolean isRedirectable(String method) {
        return Arrays.binarySearch(new String[]{
                HttpGet.METHOD_NAME,
                HttpHead.METHOD_NAME,
                HttpPost.METHOD_NAME,
                HttpPut.METHOD_NAME,
                HttpDelete.METHOD_NAME
        }, method) >= 0;
    }
    
    protected URI createLocationURI(String location) throws ProtocolException {
        try {
            return new URI(location);
        } catch (URISyntaxException ex) {
            throw new ProtocolException("Invalid redirect URI: " + location, ex);
        }
    }
}

// 具体策略 - 宽松重定向策略
public class LaxRedirectStrategy extends DefaultRedirectStrategy {
    
    private final Logger logger = LoggerFactory.getLogger(LaxRedirectStrategy.class);
    
    @Override
    protected boolean isRedirectable(String method) {
        return true; // 允许所有HTTP方法重定向
    }
    
    @Override
    public HttpUriRequest getRedirect(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException {
        logger.info("Using lax redirect strategy");
        return super.getRedirect(request, response, context);
    }
}

// 具体策略 - 严格重定向策略
public class StrictRedirectStrategy implements RedirectStrategy {
    
    private final Logger logger = LoggerFactory.getLogger(StrictRedirectStrategy.class);
    
    @Override
    public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException {
        Args.notNull(request, "HTTP request");
        Args.notNull(response, "HTTP response");
        
        int statusCode = response.getStatusLine().getStatusCode();
        String method = request.getRequestLine().getMethod();
        Header locationHeader = response.getFirstHeader("location");
        
        // 只允许GET和HEAD方法重定向
        boolean isGetOrHead = HttpGet.METHOD_NAME.equalsIgnoreCase(method) || HttpHead.METHOD_NAME.equalsIgnoreCase(method);
        
        switch (statusCode) {
            case HttpStatus.SC_MOVED_TEMPORARILY:
            case HttpStatus.SC_MOVED_PERMANENTLY:
            case HttpStatus.SC_TEMPORARY_REDIRECT:
            case HttpStatus.SC_SEE_OTHER:
                return isGetOrHead && locationHeader != null;
            default:
                return false;
        }
    }
    
    @Override
    public HttpUriRequest getRedirect(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException {
        logger.info("Using strict redirect strategy");
        URI location = createLocationURI(response.getFirstHeader("location").getValue());
        String method = request.getRequestLine().getMethod();
        
        if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
            return new HttpHead(location);
        } else {
            return new HttpGet(location);
        }
    }
    
    protected URI createLocationURI(String location) throws ProtocolException {
        try {
            return new URI(location);
        } catch (URISyntaxException ex) {
            throw new ProtocolException("Invalid redirect URI: " + location, ex);
        }
    }
}

// 具体策略 - 自定义重定向策略
public class CustomRedirectStrategy implements RedirectStrategy {
    
    private final int maxRedirects;
    private final Set<Integer> allowedStatusCodes;
    private final Logger logger = LoggerFactory.getLogger(CustomRedirectStrategy.class);
    
    public CustomRedirectStrategy(int maxRedirects, Set<Integer> allowedStatusCodes) {
        this.maxRedirects = maxRedirects;
        this.allowedStatusCodes = allowedStatusCodes;
    }
    
    @Override
    public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException {
        int statusCode = response.getStatusLine().getStatusCode();
        Header locationHeader = response.getFirstHeader("location");
        
        // 检查重定向次数
        RedirectLocations redirectLocations = (RedirectLocations) context.getAttribute(HttpClientContext.REDIRECT_LOCATIONS);
        if (redirectLocations != null && redirectLocations.size() >= maxRedirects) {
            logger.warn("Maximum redirects reached: {}", maxRedirects);
            return false;
        }
        
        boolean isAllowedStatus = allowedStatusCodes.contains(statusCode);
        boolean hasLocation = locationHeader != null;
        
        logger.debug("Redirect check - status: {}, allowed: {}, hasLocation: {}", 
                    statusCode, isAllowedStatus, hasLocation);
        
        return isAllowedStatus && hasLocation;
    }
    
    @Override
    public HttpUriRequest getRedirect(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException {
        logger.info("Getting redirect for custom strategy");
        URI location = createLocationURI(response.getFirstHeader("location").getValue());
        return new HttpGet(location);
    }
    
    protected URI createLocationURI(String location) throws ProtocolException {
        try {
            return new URI(location);
        } catch (URISyntaxException ex) {
            throw new ProtocolException("Invalid redirect URI: " + location, ex);
        }
    }
}

// 上下文 - HTTP客户端
public class HttpClientWithRedirect {
    
    private final CloseableHttpClient httpClient;
    private RedirectStrategy redirectStrategy;
    
    public HttpClientWithRedirect(RedirectStrategy redirectStrategy) {
        this.redirectStrategy = redirectStrategy;
        this.httpClient = HttpClients.custom()
                .setRedirectStrategy(redirectStrategy)
                .build();
    }
    
    public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
        this.redirectStrategy = redirectStrategy;
        // 重新创建HTTP客户端
        try {
            httpClient.close();
        } catch (IOException e) {
            // 记录日志
        }
        // 重新创建HTTP客户端的逻辑
    }
    
    public CloseableHttpResponse execute(HttpUriRequest request) throws IOException {
        return httpClient.execute(request);
    }
    
    public String getRedirectStrategyName() {
        return redirectStrategy.getClass().getSimpleName();
    }
}

5. Netflix Ribbon

Load Balancing Strategy Pattern
// Netflix Ribbon负载均衡策略模式 - 策略接口
public interface IRule {
    
    // 选择服务器
    Server choose(Object key);
    
    // 设置负载均衡器
    void setLoadBalancer(ILoadBalancer lb);
    
    // 获取负载均衡器
    ILoadBalancer getLoadBalancer();
}

// 具体策略 - 轮询策略
public class RoundRobinRule extends AbstractLoadBalancerRule {
    
    private final AtomicInteger nextServerCyclicCounter;
    private final Logger logger = LoggerFactory.getLogger(RoundRobinRule.class);
    
    public RoundRobinRule() {
        nextServerCyclicCounter = new AtomicInteger(0);
    }
    
    @Override
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            logger.warn("no load balancer");
            return null;
        }
        
        Server server = null;
        int count = 0;
        while (server == null && count++ < 10) {
            List<Server> reachableServers = lb.getReachableServers();
            List<Server> allServers = lb.getAllServers();
            int upCount = reachableServers.size();
            int serverCount = allServers.size();
            
            if ((upCount == 0) || (serverCount == 0)) {
                logger.warn("No up servers available from load balancer: " + lb);
                return null;
            }
            
            int nextServerIndex = incrementAndGetModulo(serverCount);
            server = allServers.get(nextServerIndex);
            
            if (server == null) {
                Thread.yield();
                continue;
            }
            
            if (server.isAlive() && (server.isReadyToServe())) {
                return server;
            }
            
            server = null;
        }
        
        if (count >= 10) {
            logger.warn("No available alive servers after 10 tries from load balancer: " + lb);
        }
        return server;
    }
    
    private int incrementAndGetModulo(int modulo) {
        for (;;) {
            int current = nextServerCyclicCounter.get();
            int next = (current + 1) % modulo;
            if (nextServerCyclicCounter.compareAndSet(current, next)) {
                return next;
            }
        }
    }
}

// 具体策略 - 随机策略
public class RandomRule extends AbstractLoadBalancerRule {
    
    private final Random rand;
    private final Logger logger = LoggerFactory.getLogger(RandomRule.class);
    
    public RandomRule() {
        rand = new Random();
    }
    
    @Override
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        Server server = null;
        
        while (server == null) {
            if (Thread.interrupted()) {
                return null;
            }
            List<Server> upList = lb.getReachableServers();
            List<Server> allList = lb.getAllServers();
            
            int serverCount = allList.size();
            if (serverCount == 0) {
                return null;
            }
            
            int index = rand.nextInt(serverCount);
            server = allList.get(index);
            
            if (server == null) {
                Thread.yield();
                continue;
            }
            
            if (server.isAlive()) {
                return server;
            }
            
            server = null;
            Thread.yield();
        }
        return server;
    }
}

// 具体策略 - 加权响应时间策略
public class WeightedResponseTimeRule extends RoundRobinRule {
    
    public static final IClientConfigKey<Integer> WEIGHT_TASK_TIMER_INTERVAL_CONFIG_KEY = new IClientConfigKey<Integer>() {
        @Override
        public String key() {
            return "WeightedResponseTimeRuleTimerInterval";
        }
        
        @Override
        public String toString() {
            return key();
        }
        
        @Override
        public Class<Integer> type() {
            return Integer.class;
        }
    };
    
    public static final int DEFAULT_TIMER_INTERVAL = 30 * 1000;
    
    private int serverWeightTaskTimerInterval = DEFAULT_TIMER_INTERVAL;
    
    private static final double DEFAULT_WEIGHT = 1.0D;
    
    private volatile List<Double> accumulatedWeights = new ArrayList<Double>();
    
    private final Random random = new Random();
    
    protected Timer serverWeightTimer = null;
    
    protected AtomicBoolean serverWeightAssignmentInProgress = new AtomicBoolean(false);
    
    private final Logger logger = LoggerFactory.getLogger(WeightedResponseTimeRule.class);
    
    @Override
    public void setLoadBalancer(ILoadBalancer lb) {
        super.setLoadBalancer(lb);
        if (lb instanceof BaseLoadBalancer) {
            name = ((BaseLoadBalancer) lb).getName();
        }
        initialize(lb);
    }
    
    void initialize(ILoadBalancer lb) {
        if (serverWeightTimer != null) {
            serverWeightTimer.cancel();
        }
        serverWeightTimer = new Timer("NFLoadBalancer-serverWeightTimer-" + name, true);
        serverWeightTimer.schedule(new DynamicServerWeightTask(), 0, serverWeightTaskTimerInterval);
        
        ServerWeight sw = new ServerWeight();
        sw.maintainWeights();
        
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            public void run() {
                logger.info("Stopping NFLoadBalancer-serverWeightTimer-" + name);
                serverWeightTimer.cancel();
            }
        }));
    }
    
    @Override
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            return null;
        }
        Server server = null;
        
        while (server == null) {
            List<Double> currentWeights = accumulatedWeights;
            if (Thread.interrupted()) {
                return null;
            }
            List<Server> allList = lb.getAllServers();
            
            int serverCount = allList.size();
            
            if (serverCount == 0) {
                return null;
            }
            
            int serverIndex = 0;
            
            List<Server> reachableServers = lb.getReachableServers();
            if (currentWeights != null && currentWeights.size() == serverCount) {
                serverIndex = randomWithWeight(currentWeights);
                server = allList.get(serverIndex);
            } else {
                server = super.choose(lb, key);
            }
            
            if (server == null) {
                Thread.yield();
                continue;
            }
            
            if (server.isAlive() && (server.isReadyToServe())) {
                return server;
            }
            
            server = null;
        }
        return server;
    }
    
    private int randomWithWeight(List<Double> currentWeights) {
        double randomWeight = random.nextDouble();
        int serverIndex = 0;
        for (Double weight : currentWeights) {
            if (randomWeight < weight) {
                return serverIndex;
            }
            serverIndex++;
        }
        return serverIndex - 1;
    }
}

// 具体策略 - 可用性过滤策略
public class AvailabilityFilteringRule extends ClientConfigEnabledRoundRobinRule {
    
    private AbstractServerPredicate predicate;
    
    public AvailabilityFilteringRule() {
        super();
        predicate = CompositePredicate.withPredicate(new AvailabilityPredicate(this, null))
                .addFallbackPredicate(AbstractServerPredicate.alwaysTrue())
                .build();
    }
    
    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
        predicate = CompositePredicate.withPredicate(new AvailabilityPredicate(this, clientConfig))
                .addFallbackPredicate(AbstractServerPredicate.alwaysTrue())
                .build();
    }
    
    @Override
    public Server choose(Object key) {
        int count = 0;
        Server server = roundRobinRule.choose(key);
        while (count++ <= 10) {
            if (predicate.apply(new PredicateKey(server))) {
                return server;
            }
            server = roundRobinRule.choose(key);
        }
        return super.choose(key);
    }
}

// 上下文 - 负载均衡器
public class LoadBalancer {
    
    private final ILoadBalancer loadBalancer;
    private IRule loadBalancingRule;
    
    public LoadBalancer(List<Server> servers, IRule loadBalancingRule) {
        this.loadBalancingRule = loadBalancingRule;
        this.loadBalancer = new BaseLoadBalancer();
        
        for (Server server : servers) {
            loadBalancer.addServer(server);
        }
        
        loadBalancingRule.setLoadBalancer(loadBalancer);
    }
    
    public void setLoadBalancingRule(IRule loadBalancingRule) {
        this.loadBalancingRule = loadBalancingRule;
        this.loadBalancingRule.setLoadBalancer(loadBalancer);
    }
    
    public Server chooseServer(Object key) {
        return loadBalancingRule.choose(key);
    }
    
    public String getCurrentStrategyName() {
        return loadBalancingRule.getClass().getSimpleName();
    }
    
    public List<Server> getAllServers() {
        return loadBalancer.getAllServers();
    }
    
    public List<Server> getReachableServers() {
        return loadBalancer.getReachableServers();
    }
}

6. Apache Log4j

Appender Strategy Pattern
// Apache Log4j附加器策略模式 - 策略接口
public interface Appender {
    
    // 追加日志事件
    void append(LogEvent event);
    
    // 获取附加器名称
    String getName();
    
    // 设置附加器名称
    void setName(String name);
    
    // 忽略异常
    boolean ignoreExceptions();
    
    // 获取错误处理器
    ErrorHandler getHandler();
    
    // 设置错误处理器
    void setHandler(ErrorHandler handler);
    
    // 获取布局
    Layout<? extends Serializable> getLayout();
    
    // 设置布局
    void setLayout(Layout<? extends Serializable> layout);
}

// 具体策略 - 控制台附加器
public class ConsoleAppender extends AbstractOutputStreamAppender<ConsoleManager> {
    
    private static final Logger LOGGER = StatusLogger.getLogger();
    
    public static class Builder<B extends Builder<B>> extends AbstractOutputStreamAppender.Builder<B>
            implements org.apache.logging.log4j.core.util.Builder<ConsoleAppender> {
        
        @Override
        public ConsoleAppender build() {
            final Layout<? extends Serializable> layout = getLayout();
            if (layout == null) {
                AbstractLifeCycle.LOGGER.error("No layout provided for ConsoleAppender");
                return null;
            }
            
            final ConsoleManager manager = ConsoleManager.getManager(getName(), getTarget(), getFollow(), layout);
            if (manager == null) {
                return null;
            }
            
            return new ConsoleAppender(getName(), layout, getFilter(), manager, isIgnoreExceptions(), getPropertyArray());
        }
    }
    
    public enum Target {
        SYSTEM_OUT,
        SYSTEM_ERR
    }
    
    private ConsoleAppender(String name, Layout<? extends Serializable> layout, Filter filter, ConsoleManager manager, boolean ignoreExceptions, Property[] properties) {
        super(name, layout, filter, ignoreExceptions, true, manager, properties);
    }
    
    @Override
    public void append(LogEvent event) {
        getManager().write(event);
    }
}

// 具体策略 - 文件附加器
public class FileAppender extends AbstractOutputStreamAppender<FileManager> {
    
    private static final long serialVersionUID = 1L;
    
    public static class Builder<B extends Builder<B>> extends AbstractOutputStreamAppender.Builder<B>
            implements org.apache.logging.log4j.core.util.Builder<FileAppender> {
        
        @PluginBuilderAttribute
        @Required(message = "No file name provided")
        private String fileName;
        
        @PluginBuilderAttribute
        private boolean append = true;
        
        @PluginBuilderAttribute
        private boolean locking;
        
        @PluginBuilderAttribute
        private boolean advertise;
        
        @PluginBuilderAttribute
        private String advertiseUri;
        
        @PluginBuilderAttribute
        private boolean createOnDemand;
        
        @Override
        public FileAppender build() {
            final Layout<? extends Serializable> layout = getLayout();
            final String name = getName();
            
            final FileManager manager = FileManager.getFileManager(fileName, append, locking, advertiseUri, layout, bufferSize, isImmediateFlush(), createOnDemand, getConfiguration());
            if (manager == null) {
                return null;
            }
            
            return new FileAppender(name, layout, getFilter(), manager, fileName, isIgnoreExceptions(), isImmediateFlush(), advertise ? getConfiguration().getAdvertiser() : null, getPropertyArray());
        }
    }
    
    private FileAppender(String name, Layout<? extends Serializable> layout, Filter filter, FileManager manager, String fileName, boolean ignoreExceptions, boolean immediateFlush, Advertiser advertiser, Property[] properties) {
        super(name, layout, filter, ignoreExceptions, immediateFlush, manager, properties);
    }
    
    @Override
    public void append(LogEvent event) {
        getManager().write(event);
    }
}

// 具体策略 - 数据库附加器
public class JdbcAppender extends AbstractDatabaseAppender<JdbcDatabaseManager> {
    
    private final String description = "JdbcAppender";
    
    public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
            implements org.apache.logging.log4j.core.util.Builder<JdbcAppender> {
        
        @PluginBuilderAttribute
        @Required(message = "No connection source provided")
        private ConnectionSource connectionSource;
        
        @PluginBuilderAttribute
        @Required(message = "No SQL statement provided")
        private String sqlStatement;
        
        @Override
        public JdbcAppender build() {
            final String name = getName();
            final JdbcDatabaseManager manager = JdbcDatabaseManager.getJdbcDatabaseManager(name, getBufferSize(), connectionSource, sqlStatement, isImmediateFail());
            
            return new JdbcAppender(name, getFilter(), getLayout(), isIgnoreExceptions(), manager);
        }
    }
    
    private JdbcAppender(String name, Filter filter, Layout<? extends Serializable> layout, boolean ignoreExceptions, JdbcDatabaseManager manager) {
        super(name, filter, layout, ignoreExceptions, manager);
    }
    
    @Override
    public void append(LogEvent event) {
        getManager().writeEvent(event, this);
    }
}

// 具体策略 - 网络附加器
public class SocketAppender extends AbstractOutputStreamAppender<SocketManager> {
    
    public static class Builder<B extends Builder<B>> extends AbstractOutputStreamAppender.Builder<B>
            implements org.apache.logging.log4j.core.util.Builder<SocketAppender> {
        
        @PluginBuilderAttribute
        private boolean immediateFail = true;
        
        @PluginBuilderAttribute
        @Required(message = "No host name provided")
        private String host;
        
        @PluginBuilderAttribute
        @Required(message = "No port number provided")
        private int port;
        
        @PluginBuilderAttribute
        private int connectTimeoutMillis = 0;
        
        @PluginBuilderAttribute
        private int reconnectionDelayMillis = 0;
        
        @Override
        public SocketAppender build() {
            final Layout<? extends Serializable> layout = getLayout();
            if (layout == null) {
                AbstractLifeCycle.LOGGER.error("No layout provided for SocketAppender");
                return null;
            }
            
            final SocketManager manager = SocketManager.getSocketManager(getName(), layout, host, port, connectTimeoutMillis, reconnectionDelayMillis, immediateFail, getPropertyArray());
            if (manager == null) {
                return null;
            }
            
            return new SocketAppender(getName(), layout, getFilter(), manager, isIgnoreExceptions(), getPropertyArray());
        }
    }
    
    private SocketAppender(String name, Layout<? extends Serializable> layout, Filter filter, SocketManager manager, boolean ignoreExceptions, Property[] properties) {
        super(name, layout, filter, ignoreExceptions, true, manager, properties);
    }
    
    @Override
    public void append(LogEvent event) {
        getManager().write(event);
    }
}

// 上下文 - 日志管理器
public class LoggingManager {
    
    private final Map<String, Appender> appenders = new HashMap<>();
    private Appender currentAppender;
    
    public LoggingManager() {
        // 初始化默认附加器
        ConsoleAppender consoleAppender = ConsoleAppender.newBuilder()
                .setName("Console")
                .setLayout(PatternLayout.newBuilder().withPattern("%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n").build())
                .build();
        
        appenders.put("console", consoleAppender);
        currentAppender = consoleAppender;
    }
    
    public void addAppender(String name, Appender appender) {
        appenders.put(name, appender);
    }
    
    public void setAppender(String name) {
        Appender appender = appenders.get(name);
        if (appender != null) {
            currentAppender = appender;
        }
    }
    
    public void log(LogEvent event) {
        currentAppender.append(event);
    }
    
    public void log(String level, String message) {
        LogEvent event = Log4jLogEvent.newBuilder()
                .setLevel(Level.getLevel(level))
                .setMessage(new SimpleMessage(message))
                .setTimeMillis(System.currentTimeMillis())
                .build();
        log(event);
    }
    
    public String getCurrentAppenderName() {
        return currentAppender.getName();
    }
    
    public Set<String> getAvailableAppenders() {
        return appenders.keySet();
    }
}

7. Spring Framework

Spring Validation Strategy Pattern
// Spring验证策略模式 - 验证策略接口
public interface Validator {
    
    // 验证对象
    boolean supports(Class<?> clazz);
    
    // 执行验证
    void validate(Object target, Errors errors);
}

// 具体策略 - 用户验证器
public class UserValidator implements Validator {
    
    private final Logger logger = LoggerFactory.getLogger(UserValidator.class);
    
    @Override
    public boolean supports(Class<?> clazz) {
        return User.class.equals(clazz);
    }
    
    @Override
    public void validate(Object target, Errors errors) {
        logger.info("Validating user object");
        User user = (User) target;
        
        // 验证用户名
        if (user.getUsername() == null || user.getUsername().trim().isEmpty()) {
            errors.rejectValue("username", "username.empty", "Username is required");
        } else if (user.getUsername().length() < 3) {
            errors.rejectValue("username", "username.short", "Username must be at least 3 characters");
        } else if (user.getUsername().length() > 20) {
            errors.rejectValue("username", "username.long", "Username must be less than 20 characters");
        }
        
        // 验证邮箱
        if (user.getEmail() == null || user.getEmail().trim().isEmpty()) {
            errors.rejectValue("email", "email.empty", "Email is required");
        } else if (!isValidEmail(user.getEmail())) {
            errors.rejectValue("email", "email.invalid", "Email format is invalid");
        }
        
        // 验证年龄
        if (user.getAge() == null) {
            errors.rejectValue("age", "age.empty", "Age is required");
        } else if (user.getAge() < 18) {
            errors.rejectValue("age", "age.min", "Age must be at least 18");
        } else if (user.getAge() > 120) {
            errors.rejectValue("age", "age.max", "Age must be less than 120");
        }
        
        logger.info("User validation completed, errors: {}", errors.getErrorCount());
    }
    
    private boolean isValidEmail(String email) {
        String emailRegex = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$";
        return email.matches(emailRegex);
    }
}

// 具体策略 - 产品验证器
public class ProductValidator implements Validator {
    
    private final Logger logger = LoggerFactory.getLogger(ProductValidator.class);
    
    @Override
    public boolean supports(Class<?> clazz) {
        return Product.class.equals(clazz);
    }
    
    @Override
    public void validate(Object target, Errors errors) {
        logger.info("Validating product object");
        Product product = (Product) target;
        
        // 验证产品名称
        if (product.getName() == null || product.getName().trim().isEmpty()) {
            errors.rejectValue("name", "name.empty", "Product name is required");
        } else if (product.getName().length() < 2) {
            errors.rejectValue("name", "name.short", "Product name must be at least 2 characters");
        }
        
        // 验证价格
        if (product.getPrice() == null) {
            errors.rejectValue("price", "price.empty", "Price is required");
        } else if (product.getPrice().compareTo(BigDecimal.ZERO) <= 0) {
            errors.rejectValue("price", "price.negative", "Price must be greater than zero");
        } else if (product.getPrice().compareTo(new BigDecimal("10000")) > 0) {
            errors.rejectValue("price", "price.max", "Price must be less than 10000");
        }
        
        // 验证库存
        if (product.getStock() == null) {
            errors.rejectValue("stock", "stock.empty", "Stock is required");
        } else if (product.getStock() < 0) {
            errors.rejectValue("stock", "stock.negative", "Stock cannot be negative");
        }
        
        logger.info("Product validation completed, errors: {}", errors.getErrorCount());
    }
}

// 具体策略 - 订单验证器
public class OrderValidator implements Validator {
    
    private final Logger logger = LoggerFactory.getLogger(OrderValidator.class);
    
    @Override
    public boolean supports(Class<?> clazz) {
        return Order.class.equals(clazz);
    }
    
    @Override
    public void validate(Object target, Errors errors) {
        logger.info("Validating order object");
        Order order = (Order) target;
        
        // 验证订单项
        if (order.getItems() == null || order.getItems().isEmpty()) {
            errors.rejectValue("items", "items.empty", "Order must contain at least one item");
        } else {
            for (int i = 0; i < order.getItems().size(); i++) {
                OrderItem item = order.getItems().get(i);
                if (item.getQuantity() <= 0) {
                    errors.rejectValue("items[" + i + "].quantity", "quantity.invalid", "Quantity must be greater than zero");
                }
            }
        }
        
        // 验证总金额
        if (order.getTotalAmount() == null) {
            errors.rejectValue("totalAmount", "totalAmount.empty", "Total amount is required");
        } else if (order.getTotalAmount().compareTo(BigDecimal.ZERO) <= 0) {
            errors.rejectValue("totalAmount", "totalAmount.invalid", "Total amount must be greater than zero");
        }
        
        // 验证客户信息
        if (order.getCustomerId() == null) {
            errors.rejectValue("customerId", "customerId.empty", "Customer ID is required");
        }
        
        logger.info("Order validation completed, errors: {}", errors.getErrorCount());
    }
}

// 上下文 - 验证服务
public class ValidationService {
    
    private final Map<Class<?>, Validator> validators = new HashMap<>();
    private final Logger logger = LoggerFactory.getLogger(ValidationService.class);
    
    public ValidationService() {
        // 注册验证器
        validators.put(User.class, new UserValidator());
        validators.put(Product.class, new ProductValidator());
        validators.put(Order.class, new OrderValidator());
    }
    
    public void addValidator(Class<?> clazz, Validator validator) {
        validators.put(clazz, validator);
    }
    
    public <T> ValidationResult validate(T object) {
        logger.info("Starting validation for object: {}", object.getClass().getSimpleName());
        
        Validator validator = validators.get(object.getClass());
        if (validator == null) {
            logger.warn("No validator found for class: {}", object.getClass().getName());
            return new ValidationResult(false, "No validator found for this object type");
        }
        
        if (!validator.supports(object.getClass())) {
            logger.warn("Validator does not support class: {}", object.getClass().getName());
            return new ValidationResult(false, "Validator does not support this object type");
        }
        
        BeanPropertyBindingResult errors = new BeanPropertyBindingResult(object, object.getClass().getSimpleName());
        validator.validate(object, errors);
        
        if (errors.hasErrors()) {
            List<String> errorMessages = new ArrayList<>();
            for (ObjectError error : errors.getAllErrors()) {
                errorMessages.add(error.getDefaultMessage());
            }
            logger.warn("Validation failed with {} errors", errorMessages.size());
            return new ValidationResult(false, String.join("; ", errorMessages));
        }
        
        logger.info("Validation completed successfully");
        return new ValidationResult(true, "Validation passed");
    }
    
    public <T> ValidationResult validateWithStrategy(Class<? extends Validator> validatorClass, T object) {
        try {
            Validator validator = validatorClass.getDeclaredConstructor().newInstance();
            if (validator.supports(object.getClass())) {
                BeanPropertyBindingResult errors = new BeanPropertyBindingResult(object, object.getClass().getSimpleName());
                validator.validate(object, errors);
                
                if (errors.hasErrors()) {
                    List<String> errorMessages = new ArrayList<>();
                    for (ObjectError error : errors.getAllErrors()) {
                        errorMessages.add(error.getDefaultMessage());
                    }
                    return new ValidationResult(false, String.join("; ", errorMessages));
                }
                return new ValidationResult(true, "Validation passed");
            }
        } catch (Exception e) {
            logger.error("Error creating validator", e);
        }
        return new ValidationResult(false, "Validator creation failed");
    }
}
Spring MessageConverter Strategy Pattern
// Spring消息转换策略模式 - 消息转换策略接口
public interface MessageConverter {
    
    // 转换消息
    Object fromMessage(Message message) throws MessageConversionException;
    
    // 转换对象到消息
    Message toMessage(Object object, Session session) throws JMSException, MessageConversionException;
}

// 具体策略 - JSON消息转换器
public class JsonMessageConverter implements MessageConverter {
    
    private final ObjectMapper objectMapper = new ObjectMapper();
    private final Logger logger = LoggerFactory.getLogger(JsonMessageConverter.class);
    
    @Override
    public Object fromMessage(Message message) throws MessageConversionException {
        try {
            if (message instanceof TextMessage) {
                String json = ((TextMessage) message).getText();
                logger.debug("Converting JSON message: {}", json);
                return objectMapper.readValue(json, Map.class);
            } else {
                throw new MessageConversionException("Message must be TextMessage for JSON conversion");
            }
        } catch (Exception e) {
            logger.error("Error converting from JSON message", e);
            throw new MessageConversionException("Failed to convert JSON message", e);
        }
    }
    
    @Override
    public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
        try {
            logger.debug("Converting object to JSON message: {}", object);
            String json = objectMapper.writeValueAsString(object);
            TextMessage message = session.createTextMessage(json);
            logger.info("Object converted to JSON message successfully");
            return message;
        } catch (Exception e) {
            logger.error("Error converting object to JSON message", e);
            throw new MessageConversionException("Failed to convert object to JSON message", e);
        }
    }
}

// 具体策略 - XML消息转换器
public class XmlMessageConverter implements MessageConverter {
    
    private final JAXBContext jaxbContext;
    private final Logger logger = LoggerFactory.getLogger(XmlMessageConverter.class);
    
    public XmlMessageConverter(Class<?>... classesToBeBound) throws JAXBException {
        this.jaxbContext = JAXBContext.newInstance(classesToBeBound);
    }
    
    @Override
    public Object fromMessage(Message message) throws MessageConversionException {
        try {
            if (message instanceof TextMessage) {
                String xml = ((TextMessage) message).getText();
                logger.debug("Converting XML message: {}", xml);
                Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
                return unmarshaller.unmarshal(new StringReader(xml));
            } else {
                throw new MessageConversionException("Message must be TextMessage for XML conversion");
            }
        } catch (Exception e) {
            logger.error("Error converting from XML message", e);
            throw new MessageConversionException("Failed to convert XML message", e);
        }
    }
    
    @Override
    public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
        try {
            logger.debug("Converting object to XML message: {}", object);
            Marshaller marshaller = jaxbContext.createMarshaller();
            StringWriter writer = new StringWriter();
            marshaller.marshal(object, writer);
            TextMessage message = session.createTextMessage(writer.toString());
            logger.info("Object converted to XML message successfully");
            return message;
        } catch (Exception e) {
            logger.error("Error converting object to XML message", e);
            throw new MessageConversionException("Failed to convert object to XML message", e);
        }
    }
}

// 具体策略 - 字节数组消息转换器
public class BytesMessageConverter implements MessageConverter {
    
    private final Logger logger = LoggerFactory.getLogger(BytesMessageConverter.class);
    
    @Override
    public Object fromMessage(Message message) throws MessageConversionException {
        try {
            if (message instanceof BytesMessage) {
                BytesMessage bytesMessage = (BytesMessage) message;
                byte[] bytes = new byte[(int) bytesMessage.getBodyLength()];
                bytesMessage.readBytes(bytes);
                logger.debug("Converting bytes message, length: {}", bytes.length);
                return bytes;
            } else {
                throw new MessageConversionException("Message must be BytesMessage for byte array conversion");
            }
        } catch (Exception e) {
            logger.error("Error converting from bytes message", e);
            throw new MessageConversionException("Failed to convert bytes message", e);
        }
    }
    
    @Override
    public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
        try {
            if (object instanceof byte[]) {
                byte[] bytes = (byte[]) object;
                logger.debug("Converting byte array to message, length: {}", bytes.length);
                BytesMessage message = session.createBytesMessage();
                message.writeBytes(bytes);
                logger.info("Byte array converted to message successfully");
                return message;
            } else {
                throw new MessageConversionException("Object must be byte array for BytesMessage conversion");
            }
        } catch (Exception e) {
            logger.error("Error converting byte array to message", e);
            throw new MessageConversionException("Failed to convert byte array to message", e);
        }
    }
}

// 具体策略 - 对象序列化消息转换器
public class SerializableMessageConverter implements MessageConverter {
    
    private final Logger logger = LoggerFactory.getLogger(SerializableMessageConverter.class);
    
    @Override
    public Object fromMessage(Message message) throws MessageConversionException {
        try {
            if (message instanceof ObjectMessage) {
                ObjectMessage objectMessage = (ObjectMessage) message;
                Serializable object = objectMessage.getObject();
                logger.debug("Converting object message: {}", object);
                return object;
            } else {
                throw new MessageConversionException("Message must be ObjectMessage for Serializable conversion");
            }
        } catch (Exception e) {
            logger.error("Error converting from object message", e);
            throw new MessageConversionException("Failed to convert object message", e);
        }
    }
    
    @Override
    public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
        try {
            if (object instanceof Serializable) {
                logger.debug("Converting Serializable object to message: {}", object);
                ObjectMessage message = session.createObjectMessage((Serializable) object);
                logger.info("Serializable object converted to message successfully");
                return message;
            } else {
                throw new MessageConversionException("Object must implement Serializable");
            }
        } catch (Exception e) {
            logger.error("Error converting Serializable object to message", e);
            throw new MessageConversionException("Failed to convert Serializable object to message", e);
        }
    }
}

// 上下文 - 消息转换服务
public class MessageConversionService {
    
    private final Map<String, MessageConverter> converters = new HashMap<>();
    private MessageConverter defaultConverter;
    private final Logger logger = LoggerFactory.getLogger(MessageConversionService.class);
    
    public MessageConversionService() {
        // 注册默认转换器
        try {
            converters.put("json", new JsonMessageConverter());
            converters.put("xml", new XmlMessageConverter(User.class, Product.class, Order.class));
            converters.put("bytes", new BytesMessageConverter());
            converters.put("serializable", new SerializableMessageConverter());
            defaultConverter = converters.get("json");
        } catch (Exception e) {
            logger.error("Error initializing default converters", e);
        }
    }
    
    public void addConverter(String name, MessageConverter converter) {
        converters.put(name, converter);
    }
    
    public void setDefaultConverter(String name) {
        MessageConverter converter = converters.get(name);
        if (converter != null) {
            defaultConverter = converter;
        }
    }
    
    public Message toMessage(Object object, Session session) throws JMSException {
        return toMessage(object, session, null);
    }
    
    public Message toMessage(Object object, Session session, String converterName) throws JMSException {
        MessageConverter converter = converterName != null ? converters.get(converterName) : defaultConverter;
        if (converter == null) {
            throw new JMSException("No converter found for name: " + converterName);
        }
        
        logger.info("Converting object to message using converter: {}", converter.getClass().getSimpleName());
        return converter.toMessage(object, session);
    }
    
    public Object fromMessage(Message message) throws JMSException {
        return fromMessage(message, null);
    }
    
    public Object fromMessage(Message message, String converterName) throws JMSException {
        MessageConverter converter = converterName != null ? converters.get(converterName) : defaultConverter;
        if (converter == null) {
            throw new JMSException("No converter found for name: " + converterName);
        }
        
        logger.info("Converting message to object using converter: {}", converter.getClass().getSimpleName());
        return converter.fromMessage(message);
    }
    
    public List<String> getAvailableConverters() {
        return new ArrayList<>(converters.keySet());
    }
}

8. Apache Kafka

Kafka Serialization Strategy Pattern
// Kafka序列化策略模式 - 序列化策略接口
public interface Serializer<T> {
    
    // 配置序列化器
    void configure(Map<String, ?> configs, boolean isKey);
    
    // 序列化对象
    byte[] serialize(String topic, T data);
    
    // 关闭序列化器
    void close();
}

// 具体策略 - JSON序列化器
public class JsonSerializer<T> implements Serializer<T> {
    
    private final ObjectMapper objectMapper = new ObjectMapper();
    private final Logger logger = LoggerFactory.getLogger(JsonSerializer.class);
    
    @Override
    public void configure(Map<String, ?> configs, boolean isKey) {
        logger.info("Configuring JSON serializer, isKey: {}", isKey);
        // 可以在这里配置ObjectMapper
    }
    
    @Override
    public byte[] serialize(String topic, T data) {
        if (data == null) {
            return null;
        }
        
        try {
            logger.debug("Serializing object to JSON for topic: {}", topic);
            String json = objectMapper.writeValueAsString(data);
            byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
            logger.debug("Object serialized to JSON successfully, length: {}", bytes.length);
            return bytes;
        } catch (Exception e) {
            logger.error("Error serializing object to JSON", e);
            throw new SerializationException("Failed to serialize object to JSON", e);
        }
    }
    
    @Override
    public void close() {
        logger.info("Closing JSON serializer");
    }
}

// 具体策略 - Avro序列化器
public class AvroSerializer<T> implements Serializer<T> {
    
    private final Schema schema;
    private final DatumWriter<T> datumWriter;
    private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    private final BinaryEncoder encoder;
    private final Logger logger = LoggerFactory.getLogger(AvroSerializer.class);
    
    public AvroSerializer(Schema schema) {
        this.schema = schema;
        this.datumWriter = new ReflectDatumWriter<>(schema);
        this.encoder = EncoderFactory.get().binaryEncoder(outputStream, null);
    }
    
    @Override
    public void configure(Map<String, ?> configs, boolean isKey) {
        logger.info("Configuring Avro serializer, isKey: {}", isKey);
    }
    
    @Override
    public byte[] serialize(String topic, T data) {
        if (data == null) {
            return null;
        }
        
        try {
            logger.debug("Serializing object to Avro for topic: {}", topic);
            outputStream.reset();
            datumWriter.write(data, encoder);
            encoder.flush();
            byte[] bytes = outputStream.toByteArray();
            logger.debug("Object serialized to Avro successfully, length: {}", bytes.length);
            return bytes;
        } catch (Exception e) {
            logger.error("Error serializing object to Avro", e);
            throw new SerializationException("Failed to serialize object to Avro", e);
        }
    }
    
    @Override
    public void close() {
        logger.info("Closing Avro serializer");
        try {
            outputStream.close();
        } catch (IOException e) {
            logger.error("Error closing output stream", e);
        }
    }
}

// 具体策略 - Protobuf序列化器
public class ProtobufSerializer<T extends Message> implements Serializer<T> {
    
    private final Logger logger = LoggerFactory.getLogger(ProtobufSerializer.class);
    
    @Override
    public void configure(Map<String, ?> configs, boolean isKey) {
        logger.info("Configuring Protobuf serializer, isKey: {}", isKey);
    }
    
    @Override
    public byte[] serialize(String topic, T data) {
        if (data == null) {
            return null;
        }
        
        try {
            logger.debug("Serializing object to Protobuf for topic: {}", topic);
            byte[] bytes = data.toByteArray();
            logger.debug("Object serialized to Protobuf successfully, length: {}", bytes.length);
            return bytes;
        } catch (Exception e) {
            logger.error("Error serializing object to Protobuf", e);
            throw new SerializationException("Failed to serialize object to Protobuf", e);
        }
    }
    
    @Override
    public void close() {
        logger.info("Closing Protobuf serializer");
    }
}

// 具体策略 - Kryo序列化器
public class KryoSerializer<T> implements Serializer<T> {
    
    private final ThreadLocal<Kryo> kryoThreadLocal = ThreadLocal.withInitial(() -> {
        Kryo kryo = new Kryo();
        kryo.setRegistrationRequired(false);
        return kryo;
    });
    
    private final ThreadLocal<Output> outputThreadLocal = ThreadLocal.withInitial(() -> new Output(1024, -1));
    private final Logger logger = LoggerFactory.getLogger(KryoSerializer.class);
    
    @Override
    public void configure(Map<String, ?> configs, boolean isKey) {
        logger.info("Configuring Kryo serializer, isKey: {}", isKey);
    }
    
    @Override
    public byte[] serialize(String topic, T data) {
        if (data == null) {
            return null;
        }
        
        try {
            logger.debug("Serializing object to Kryo for topic: {}", topic);
            Kryo kryo = kryoThreadLocal.get();
            Output output = outputThreadLocal.get();
            output.clear();
            
            kryo.writeClassAndObject(output, data);
            byte[] bytes = output.toBytes();
            logger.debug("Object serialized to Kryo successfully, length: {}", bytes.length);
            return bytes;
        } catch (Exception e) {
            logger.error("Error serializing object to Kryo", e);
            throw new SerializationException("Failed to serialize object to Kryo", e);
        }
    }
    
    @Override
    public void close() {
        logger.info("Closing Kryo serializer");
        kryoThreadLocal.remove();
        outputThreadLocal.remove();
    }
}

// 具体策略 - 字符串序列化器
public class StringSerializer implements Serializer<String> {
    
    private final String encoding;
    private final Logger logger = LoggerFactory.getLogger(StringSerializer.class);
    
    public StringSerializer() {
        this("UTF-8");
    }
    
    public StringSerializer(String encoding) {
        this.encoding = encoding;
    }
    
    @Override
    public void configure(Map<String, ?> configs, boolean isKey) {
        logger.info("Configuring String serializer, encoding: {}, isKey: {}", encoding, isKey);
    }
    
    @Override
    public byte[] serialize(String topic, String data) {
        if (data == null) {
            return null;
        }
        
        try {
            logger.debug("Serializing string for topic: {}", topic);
            byte[] bytes = data.getBytes(encoding);
            logger.debug("String serialized successfully, length: {}", bytes.length);
            return bytes;
        } catch (Exception e) {
            logger.error("Error serializing string", e);
            throw new SerializationException("Failed to serialize string", e);
        }
    }
    
    @Override
    public void close() {
        logger.info("Closing String serializer");
    }
}

// 具体策略 - 长整型序列化器
public class LongSerializer implements Serializer<Long> {
    
    private final Logger logger = LoggerFactory.getLogger(LongSerializer.class);
    
    @Override
    public void configure(Map<String, ?> configs, boolean isKey) {
        logger.info("Configuring Long serializer, isKey: {}", isKey);
    }
    
    @Override
    public byte[] serialize(String topic, Long data) {
        if (data == null) {
            return null;
        }
        
        try {
            logger.debug("Serializing long for topic: {}", topic);
            ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
            buffer.putLong(data);
            byte[] bytes = buffer.array();
            logger.debug("Long serialized successfully, length: {}", bytes.length);
            return bytes;
        } catch (Exception e) {
            logger.error("Error serializing long", e);
            throw new SerializationException("Failed to serialize long", e);
        }
    }
    
    @Override
    public void close() {
        logger.info("Closing Long serializer");
    }
}

// 上下文 - 序列化策略管理器
public class SerializationStrategyManager {
    
    private final Map<String, Serializer<?>> serializers = new HashMap<>();
    private Serializer<?> defaultSerializer;
    private final Logger logger = LoggerFactory.getLogger(SerializationStrategyManager.class);
    
    public SerializationStrategyManager() {
        // 注册默认序列化器
        serializers.put("string", new StringSerializer());
        serializers.put("long", new LongSerializer());
        serializers.put("json", new JsonSerializer<>());
        serializers.put("kryo", new KryoSerializer<>());
        defaultSerializer = serializers.get("json");
    }
    
    public void registerSerializer(String name, Serializer<?> serializer) {
        serializers.put(name, serializer);
        logger.info("Registered serializer: {}", name);
    }
    
    public void setDefaultSerializer(String name) {
        Serializer<?> serializer = serializers.get(name);
        if (serializer != null) {
            defaultSerializer = serializer;
            logger.info("Set default serializer to: {}", name);
        }
    }
    
    @SuppressWarnings("unchecked")
    public <T> Serializer<T> getSerializer(String name) {
        return (Serializer<T>) serializers.get(name);
    }
    
    @SuppressWarnings("unchecked")
    public <T> Serializer<T> getDefaultSerializer() {
        return (Serializer<T>) defaultSerializer;
    }
    
    public List<String> getAvailableSerializers() {
        return new ArrayList<>(serializers.keySet());
    }
}
Kafka Partition Assignment Strategy Pattern
// Kafka分区分配策略模式 - 分区分配策略接口
public interface PartitionAssignor {
    
    // 分配分区
    Map<String, Assignment> assign(Cluster metadata, Map<String, Subscription> subscriptions);
    
    // 获取分配器名称
    String name();
    
    // 订阅信息
    Subscription subscription(Set<String> topics);
    
    // 分配信息
    Assignment assignment(List<TopicPartition> partitions);
}

// 具体策略 - 范围分配策略
public class RangeAssignor implements PartitionAssignor {
    
    private final Logger logger = LoggerFactory.getLogger(RangeAssignor.class);
    
    @Override
    public Map<String, Assignment> assign(Cluster metadata, Map<String, Subscription> subscriptions) {
        logger.info("Performing range partition assignment");
        Map<String, Assignment> assignments = new HashMap<>();
        
        for (Map.Entry<String, Subscription> entry : subscriptions.entrySet()) {
            String consumerId = entry.getKey();
            Subscription subscription = entry.getValue();
            
            List<TopicPartition> assignedPartitions = new ArrayList<>();
            for (String topic : subscription.topics()) {
                List<PartitionInfo> partitions = metadata.partitionsForTopic(topic);
                if (partitions != null && !partitions.isEmpty()) {
                    // 范围分配逻辑
                    int partitionCount = partitions.size();
                    int consumerIndex = getConsumerIndex(consumerId, subscriptions.keySet());
                    int partitionsPerConsumer = partitionCount / subscriptions.size();
                    int start = consumerIndex * partitionsPerConsumer;
                    int end = (consumerIndex == subscriptions.size() - 1) ? 
                             partitionCount : start + partitionsPerConsumer;
                    
                    for (int i = start; i < end; i++) {
                        assignedPartitions.add(new TopicPartition(topic, i));
                    }
                }
            }
            
            assignments.put(consumerId, new Assignment(assignedPartitions));
            logger.info("Assigned {} partitions to consumer: {}", assignedPartitions.size(), consumerId);
        }
        
        return assignments;
    }
    
    @Override
    public String name() {
        return "range";
    }
    
    @Override
    public Subscription subscription(Set<String> topics) {
        return new Subscription(new ArrayList<>(topics));
    }
    
    @Override
    public Assignment assignment(List<TopicPartition> partitions) {
        return new Assignment(partitions);
    }
    
    private int getConsumerIndex(String consumerId, Set<String> consumerIds) {
        List<String> sortedConsumers = new ArrayList<>(consumerIds);
        Collections.sort(sortedConsumers);
        return sortedConsumers.indexOf(consumerId);
    }
}

// 具体策略 - 轮询分配策略
public class RoundRobinAssignor implements PartitionAssignor {
    
    private final Logger logger = LoggerFactory.getLogger(RoundRobinAssignor.class);
    
    @Override
    public Map<String, Assignment> assign(Cluster metadata, Map<String, Subscription> subscriptions) {
        logger.info("Performing round-robin partition assignment");
        Map<String, Assignment> assignments = new HashMap<>();
        
        // 收集所有分区
        List<TopicPartition> allPartitions = new ArrayList<>();
        for (Subscription subscription : subscriptions.values()) {
            for (String topic : subscription.topics()) {
                List<PartitionInfo> partitions = metadata.partitionsForTopic(topic);
                if (partitions != null) {
                    for (PartitionInfo partition : partitions) {
                        allPartitions.add(new TopicPartition(topic, partition.partition()));
                    }
                }
            }
        }
        
        // 轮询分配
        List<String> consumers = new ArrayList<>(subscriptions.keySet());
        Collections.sort(consumers);
        
        for (int i = 0; i < allPartitions.size(); i++) {
            TopicPartition partition = allPartitions.get(i);
            String consumerId = consumers.get(i % consumers.size());
            
            Assignment assignment = assignments.computeIfAbsent(consumerId, 
                k -> new Assignment(new ArrayList<>()));
            assignment.partitions().add(partition);
        }
        
        logger.info("Round-robin assignment completed for {} partitions across {} consumers", 
                   allPartitions.size(), consumers.size());
        return assignments;
    }
    
    @Override
    public String name() {
        return "roundrobin";
    }
    
    @Override
    public Subscription subscription(Set<String> topics) {
        return new Subscription(new ArrayList<>(topics));
    }
    
    @Override
    public Assignment assignment(List<TopicPartition> partitions) {
        return new Assignment(partitions);
    }
}

// 具体策略 - 粘性分配策略
public class StickyAssignor implements PartitionAssignor {
    
    private final Logger logger = LoggerFactory.getLogger(StickyAssignor.class);
    
    @Override
    public Map<String, Assignment> assign(Cluster metadata, Map<String, Subscription> subscriptions) {
        logger.info("Performing sticky partition assignment");
        Map<String, Assignment> assignments = new HashMap<>();
        
        // 获取之前的分配信息
        Map<String, List<TopicPartition>> previousAssignment = getPreviousAssignment(subscriptions);
        
        // 尽量保持之前的分配
        Set<TopicPartition> assignedPartitions = new HashSet<>();
        
        for (Map.Entry<String, Subscription> entry : subscriptions.entrySet()) {
            String consumerId = entry.getKey();
            List<TopicPartition> previousPartitions = previousAssignment.get(consumerId);
            List<TopicPartition> newPartitions = new ArrayList<>();
            
            if (previousPartitions != null) {
                // 保留之前分配的分区
                for (TopicPartition partition : previousPartitions) {
                    if (isPartitionAvailable(partition, metadata, entry.getValue().topics())) {
                        newPartitions.add(partition);
                        assignedPartitions.add(partition);
                    }
                }
            }
            
            // 分配剩余的分区
            List<TopicPartition> remainingPartitions = getRemainingPartitions(metadata, 
                entry.getValue().topics(), assignedPartitions);
            newPartitions.addAll(remainingPartitions);
            
            assignments.put(consumerId, new Assignment(newPartitions));
            logger.info("Sticky assigned {} partitions to consumer: {}", newPartitions.size(), consumerId);
        }
        
        return assignments;
    }
    
    @Override
    public String name() {
        return "sticky";
    }
    
    @Override
    public Subscription subscription(Set<String> topics) {
        return new Subscription(new ArrayList<>(topics));
    }
    
    @Override
    public Assignment assignment(List<TopicPartition> partitions) {
        return new Assignment(partitions);
    }
    
    private Map<String, List<TopicPartition>> getPreviousAssignment(Map<String, Subscription> subscriptions) {
        // 从订阅信息中获取之前的分配
        Map<String, List<TopicPartition>> previousAssignment = new HashMap<>();
        for (Map.Entry<String, Subscription> entry : subscriptions.entrySet()) {
            // 这里简化处理,实际应该从订阅信息中提取
            previousAssignment.put(entry.getKey(), new ArrayList<>());
        }
        return previousAssignment;
    }
    
    private boolean isPartitionAvailable(TopicPartition partition, Cluster metadata, List<String> subscribedTopics) {
        return subscribedTopics.contains(partition.topic()) && 
               metadata.partition(partition) != null;
    }
    
    private List<TopicPartition> getRemainingPartitions(Cluster metadata, List<String> topics, 
                                                       Set<TopicPartition> assignedPartitions) {
        List<TopicPartition> remaining = new ArrayList<>();
        for (String topic : topics) {
            List<PartitionInfo> partitions = metadata.partitionsForTopic(topic);
            if (partitions != null) {
                for (PartitionInfo partition : partitions) {
                    TopicPartition tp = new TopicPartition(topic, partition.partition());
                    if (!assignedPartitions.contains(tp)) {
                        remaining.add(tp);
                    }
                }
            }
        }
        return remaining;
    }
}

// 具体策略 - 协作粘性分配策略
public class CooperativeStickyAssignor implements PartitionAssignor {
    
    private final StickyAssignor stickyAssignor = new StickyAssignor();
    private final Logger logger = LoggerFactory.getLogger(CooperativeStickyAssignor.class);
    
    @Override
    public Map<String, Assignment> assign(Cluster metadata, Map<String, Subscription> subscriptions) {
        logger.info("Performing cooperative sticky partition assignment");
        
        // 首先使用粘性分配
        Map<String, Assignment> assignments = stickyAssignor.assign(metadata, subscriptions);
        
        // 协作处理:尽量减少分区重新分配
        for (Map.Entry<String, Assignment> entry : assignments.entrySet()) {
            Assignment assignment = entry.getValue();
            // 这里可以添加协作逻辑,如逐步重新分配
            logger.debug("Cooperative assignment for consumer {}: {} partitions", 
                        entry.getKey(), assignment.partitions().size());
        }
        
        return assignments;
    }
    
    @Override
    public String name() {
        return "cooperative-sticky";
    }
    
    @Override
    public Subscription subscription(Set<String> topics) {
        return stickyAssignor.subscription(topics);
    }
    
    @Override
    public Assignment assignment(List<TopicPartition> partitions) {
        return stickyAssignor.assignment(partitions);
    }
}

// 上下文 - 分区分配策略管理器
public class PartitionAssignmentStrategyManager {
    
    private final Map<String, PartitionAssignor> assignors = new HashMap<>();
    private PartitionAssignor defaultAssignor;
    private final Logger logger = LoggerFactory.getLogger(PartitionAssignmentStrategyManager.class);
    
    public PartitionAssignmentStrategyManager() {
        // 注册默认分配策略
        assignors.put("range", new RangeAssignor());
        assignors.put("roundrobin", new RoundRobinAssignor());
        assignors.put("sticky", new StickyAssignor());
        assignors.put("cooperative-sticky", new CooperativeStickyAssignor());
        defaultAssignor = assignors.get("range");
    }
    
    public void registerAssignor(String name, PartitionAssignor assignor) {
        assignors.put(name, assignor);
        logger.info("Registered partition assignor: {}", name);
    }
    
    public void setDefaultAssignor(String name) {
        PartitionAssignor assignor = assignors.get(name);
        if (assignor != null) {
            defaultAssignor = assignor;
            logger.info("Set default partition assignor to: {}", name);
        }
    }
    
    public PartitionAssignor getAssignor(String name) {
        return assignors.get(name);
    }
    
    public PartitionAssignor getDefaultAssignor() {
        return defaultAssignor;
    }
    
    public List<String> getAvailableAssignors() {
        return new ArrayList<>(assignors.keySet());
    }
}

9. Redis

Redis Data Structure Strategy Pattern
// Redis数据结构策略模式 - 数据结构策略接口
public interface RedisDataStructureStrategy<T> {
    
    // 存储数据
    void set(String key, T value);
    
    // 获取数据
    T get(String key);
    
    // 删除数据
    void delete(String key);
    
    // 检查是否存在
    boolean exists(String key);
    
    // 获取策略类型
    String getStrategyType();
}

// 具体策略 - 字符串数据结构
public class RedisStringStrategy implements RedisDataStructureStrategy<String> {
    
    private final Jedis jedis;
    private final Logger logger = LoggerFactory.getLogger(RedisStringStrategy.class);
    
    public RedisStringStrategy(Jedis jedis) {
        this.jedis = jedis;
    }
    
    @Override
    public void set(String key, String value) {
        logger.debug("Setting string value for key: {}", key);
        jedis.set(key, value);
        logger.info("String value set successfully for key: {}", key);
    }
    
    @Override
    public String get(String key) {
        logger.debug("Getting string value for key: {}", key);
        String value = jedis.get(key);
        logger.info("String value retrieved for key: {}, exists: {}", key, value != null);
        return value;
    }
    
    @Override
    public void delete(String key) {
        logger.debug("Deleting string value for key: {}", key);
        jedis.del(key);
        logger.info("String value deleted for key: {}", key);
    }
    
    @Override
    public boolean exists(String key) {
        boolean exists = jedis.exists(key);
        logger.debug("Checking existence for key: {}, exists: {}", key, exists);
        return exists;
    }
    
    @Override
    public String getStrategyType() {
        return "STRING";
    }
}

// 具体策略 - 列表数据结构
public class RedisListStrategy implements RedisDataStructureStrategy<List<String>> {
    
    private final Jedis jedis;
    private final Logger logger = LoggerFactory.getLogger(RedisListStrategy.class);
    
    public RedisListStrategy(Jedis jedis) {
        this.jedis = jedis;
    }
    
    @Override
    public void set(String key, List<String> value) {
        logger.debug("Setting list value for key: {}, size: {}", key, value.size());
        jedis.del(key); // 先删除旧数据
        for (String item : value) {
            jedis.rpush(key, item);
        }
        logger.info("List value set successfully for key: {}", key);
    }
    
    @Override
    public List<String> get(String key) {
        logger.debug("Getting list value for key: {}", key);
        List<String> value = jedis.lrange(key, 0, -1);
        logger.info("List value retrieved for key: {}, size: {}", key, value.size());
        return value;
    }
    
    @Override
    public void delete(String key) {
        logger.debug("Deleting list value for key: {}", key);
        jedis.del(key);
        logger.info("List value deleted for key: {}", key);
    }
    
    @Override
    public boolean exists(String key) {
        boolean exists = jedis.exists(key);
        logger.debug("Checking existence for key: {}, exists: {}", key, exists);
        return exists;
    }
    
    @Override
    public String getStrategyType() {
        return "LIST";
    }
}

// 具体策略 - 集合数据结构
public class RedisSetStrategy implements RedisDataStructureStrategy<Set<String>> {
    
    private final Jedis jedis;
    private final Logger logger = LoggerFactory.getLogger(RedisSetStrategy.class);
    
    public RedisSetStrategy(Jedis jedis) {
        this.jedis = jedis;
    }
    
    @Override
    public void set(String key, Set<String> value) {
        logger.debug("Setting set value for key: {}, size: {}", key, value.size());
        jedis.del(key); // 先删除旧数据
        for (String item : value) {
            jedis.sadd(key, item);
        }
        logger.info("Set value set successfully for key: {}", key);
    }
    
    @Override
    public Set<String> get(String key) {
        logger.debug("Getting set value for key: {}", key);
        Set<String> value = jedis.smembers(key);
        logger.info("Set value retrieved for key: {}, size: {}", key, value.size());
        return value;
    }
    
    @Override
    public void delete(String key) {
        logger.debug("Deleting set value for key: {}", key);
        jedis.del(key);
        logger.info("Set value deleted for key: {}", key);
    }
    
    @Override
    public boolean exists(String key) {
        boolean exists = jedis.exists(key);
        logger.debug("Checking existence for key: {}, exists: {}", key, exists);
        return exists;
    }
    
    @Override
    public String getStrategyType() {
        return "SET";
    }
}

// 具体策略 - 哈希数据结构
public class RedisHashStrategy implements RedisDataStructureStrategy<Map<String, String>> {
    
    private final Jedis jedis;
    private final Logger logger = LoggerFactory.getLogger(RedisHashStrategy.class);
    
    public RedisHashStrategy(Jedis jedis) {
        this.jedis = jedis;
    }
    
    @Override
    public void set(String key, Map<String, String> value) {
        logger.debug("Setting hash value for key: {}, fields: {}", key, value.size());
        jedis.del(key); // 先删除旧数据
        jedis.hmset(key, value);
        logger.info("Hash value set successfully for key: {}", key);
    }
    
    @Override
    public Map<String, String> get(String key) {
        logger.debug("Getting hash value for key: {}", key);
        Map<String, String> value = jedis.hgetAll(key);
        logger.info("Hash value retrieved for key: {}, fields: {}", key, value.size());
        return value;
    }
    
    @Override
    public void delete(String key) {
        logger.debug("Deleting hash value for key: {}", key);
        jedis.del(key);
        logger.info("Hash value deleted for key: {}", key);
    }
    
    @Override
    public boolean exists(String key) {
        boolean exists = jedis.exists(key);
        logger.debug("Checking existence for key: {}, exists: {}", key, exists);
        return exists;
    }
    
    @Override
    public String getStrategyType() {
        return "HASH";
    }
}

// 具体策略 - 有序集合数据结构
public class RedisZSetStrategy implements RedisDataStructureStrategy<Map<String, Double>> {
    
    private final Jedis jedis;
    private final Logger logger = LoggerFactory.getLogger(RedisZSetStrategy.class);
    
    public RedisZSetStrategy(Jedis jedis) {
        this.jedis = jedis;
    }
    
    @Override
    public void set(String key, Map<String, Double> value) {
        logger.debug("Setting sorted set value for key: {}, members: {}", key, value.size());
        jedis.del(key); // 先删除旧数据
        for (Map.Entry<String, Double> entry : value.entrySet()) {
            jedis.zadd(key, entry.getValue(), entry.getKey());
        }
        logger.info("Sorted set value set successfully for key: {}", key);
    }
    
    @Override
    public Map<String, Double> get(String key) {
        logger.debug("Getting sorted set value for key: {}", key);
        Set<Tuple> tuples = jedis.zrangeWithScores(key, 0, -1);
        Map<String, Double> value = new LinkedHashMap<>();
        for (Tuple tuple : tuples) {
            value.put(tuple.getElement(), tuple.getScore());
        }
        logger.info("Sorted set value retrieved for key: {}, members: {}", key, value.size());
        return value;
    }
    
    @Override
    public void delete(String key) {
        logger.debug("Deleting sorted set value for key: {}", key);
        jedis.del(key);
        logger.info("Sorted set value deleted for key: {}", key);
    }
    
    @Override
    public boolean exists(String key) {
        boolean exists = jedis.exists(key);
        logger.debug("Checking existence for key: {}, exists: {}", key, exists);
        return exists;
    }
    
    @Override
    public String getStrategyType() {
        return "ZSET";
    }
}

// 上下文 - Redis数据结构管理器
public class RedisDataStructureManager {
    
    private final Jedis jedis;
    private final Map<String, RedisDataStructureStrategy<?>> strategies = new HashMap<>();
    private final Logger logger = LoggerFactory.getLogger(RedisDataStructureManager.class);
    
    public RedisDataStructureManager(Jedis jedis) {
        this.jedis = jedis;
        // 注册默认策略
        strategies.put("string", new RedisStringStrategy(jedis));
        strategies.put("list", new RedisListStrategy(jedis));
        strategies.put("set", new RedisSetStrategy(jedis));
        strategies.put("hash", new RedisHashStrategy(jedis));
        strategies.put("zset", new RedisZSetStrategy(jedis));
    }
    
    public void registerStrategy(String name, RedisDataStructureStrategy<?> strategy) {
        strategies.put(name, strategy);
        logger.info("Registered Redis data structure strategy: {}", name);
    }
    
    @SuppressWarnings("unchecked")
    public <T> RedisDataStructureStrategy<T> getStrategy(String name) {
        return (RedisDataStructureStrategy<T>) strategies.get(name);
    }
    
    public <T> void setData(String structureType, String key, T value) {
        RedisDataStructureStrategy<T> strategy = getStrategy(structureType);
        if (strategy != null) {
            logger.info("Setting data using strategy: {}, key: {}", structureType, key);
            strategy.set(key, value);
        } else {
            throw new IllegalArgumentException("Unknown strategy type: " + structureType);
        }
    }
    
    @SuppressWarnings("unchecked")
    public <T> T getData(String structureType, String key) {
        RedisDataStructureStrategy<T> strategy = getStrategy(structureType);
        if (strategy != null) {
            logger.info("Getting data using strategy: {}, key: {}", structureType, key);
            return strategy.get(key);
        } else {
            throw new IllegalArgumentException("Unknown strategy type: " + structureType);
        }
    }
    
    public void deleteData(String structureType, String key) {
        RedisDataStructureStrategy<?> strategy = getStrategy(structureType);
        if (strategy != null) {
            logger.info("Deleting data using strategy: {}, key: {}", structureType, key);
            strategy.delete(key);
        } else {
            throw new IllegalArgumentException("Unknown strategy type: " + structureType);
        }
    }
    
    public boolean exists(String structureType, String key) {
        RedisDataStructureStrategy<?> strategy = getStrategy(structureType);
        if (strategy != null) {
            return strategy.exists(key);
        } else {
            throw new IllegalArgumentException("Unknown strategy type: " + structureType);
        }
    }
    
    public List<String> getAvailableStrategies() {
        return new ArrayList<>(strategies.keySet());
    }
}

10. Elasticsearch

Elasticsearch Query Strategy Pattern
// Elasticsearch查询策略模式 - 查询策略接口
public interface ElasticsearchQueryStrategy<T> {
    
    // 执行查询
    SearchResponse executeQuery(String index, T queryParams) throws IOException;
    
    // 构建查询
    QueryBuilder buildQuery(T queryParams);
    
    // 获取策略类型
    String getStrategyType();
}

// 具体策略 - 匹配查询
public class MatchQueryStrategy implements ElasticsearchQueryStrategy<Map<String, Object>> {
    
    private final RestHighLevelClient client;
    private final Logger logger = LoggerFactory.getLogger(MatchQueryStrategy.class);
    
    public MatchQueryStrategy(RestHighLevelClient client) {
        this.client = client;
    }
    
    @Override
    public SearchResponse executeQuery(String index, Map<String, Object> queryParams) throws IOException {
        logger.info("Executing match query on index: {}, params: {}", index, queryParams);
        
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        
        // 构建匹配查询
        String field = (String) queryParams.get("field");
        String value = (String) queryParams.get("value");
        Float boost = (Float) queryParams.getOrDefault("boost", 1.0f);
        
        MatchQueryBuilder matchQuery = QueryBuilders.matchQuery(field, value).boost(boost);
        sourceBuilder.query(matchQuery);
        
        // 设置分页
        Integer from = (Integer) queryParams.getOrDefault("from", 0);
        Integer size = (Integer) queryParams.getOrDefault("size", 10);
        sourceBuilder.from(from).size(size);
        
        searchRequest.source(sourceBuilder);
        
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        logger.info("Match query completed, hits: {}", response.getHits().getTotalHits());
        return response;
    }
    
    @Override
    public QueryBuilder buildQuery(Map<String, Object> queryParams) {
        String field = (String) queryParams.get("field");
        String value = (String) queryParams.get("value");
        Float boost = (Float) queryParams.getOrDefault("boost", 1.0f);
        return QueryBuilders.matchQuery(field, value).boost(boost);
    }
    
    @Override
    public String getStrategyType() {
        return "MATCH_QUERY";
    }
}

// 具体策略 - 范围查询
public class RangeQueryStrategy implements ElasticsearchQueryStrategy<Map<String, Object>> {
    
    private final RestHighLevelClient client;
    private final Logger logger = LoggerFactory.getLogger(RangeQueryStrategy.class);
    
    public RangeQueryStrategy(RestHighLevelClient client) {
        this.client = client;
    }
    
    @Override
    public SearchResponse executeQuery(String index, Map<String, Object> queryParams) throws IOException {
        logger.info("Executing range query on index: {}, params: {}", index, queryParams);
        
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        
        // 构建范围查询
        String field = (String) queryParams.get("field");
        Object from = queryParams.get("from");
        Object to = queryParams.get("to");
        Boolean includeLower = (Boolean) queryParams.getOrDefault("include_lower", true);
        Boolean includeUpper = (Boolean) queryParams.getOrDefault("include_upper", true);
        
        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery(field);
        if (from != null) rangeQuery.from(from).includeLower(includeLower);
        if (to != null) rangeQuery.to(to).includeUpper(includeUpper);
        
        sourceBuilder.query(rangeQuery);
        
        // 设置排序
        String sortField = (String) queryParams.get("sort_field");
        String sortOrder = (String) queryParams.getOrDefault("sort_order", "asc");
        if (sortField != null) {
            sourceBuilder.sort(sortField, SortOrder.fromString(sortOrder));
        }
        
        searchRequest.source(sourceBuilder);
        
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        logger.info("Range query completed, hits: {}", response.getHits().getTotalHits());
        return response;
    }
    
    @Override
    public QueryBuilder buildQuery(Map<String, Object> queryParams) {
        String field = (String) queryParams.get("field");
        Object from = queryParams.get("from");
        Object to = queryParams.get("to");
        Boolean includeLower = (Boolean) queryParams.getOrDefault("include_lower", true);
        Boolean includeUpper = (Boolean) queryParams.getOrDefault("include_upper", true);
        
        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery(field);
        if (from != null) rangeQuery.from(from).includeLower(includeLower);
        if (to != null) rangeQuery.to(to).includeUpper(includeUpper);
        return rangeQuery;
    }
    
    @Override
    public String getStrategyType() {
        return "RANGE_QUERY";
    }
}

// 具体策略 - 布尔查询
public class BoolQueryStrategy implements ElasticsearchQueryStrategy<Map<String, Object>> {
    
    private final RestHighLevelClient client;
    private final Logger logger = LoggerFactory.getLogger(BoolQueryStrategy.class);
    
    public BoolQueryStrategy(RestHighLevelClient client) {
        this.client = client;
    }
    
    @Override
    public SearchResponse executeQuery(String index, Map<String, Object> queryParams) throws IOException {
        logger.info("Executing bool query on index: {}, params: {}", index, queryParams);
        
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        
        // 构建布尔查询
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        
        // 添加must条件
        List<Map<String, Object>> mustConditions = (List<Map<String, Object>>) queryParams.get("must");
        if (mustConditions != null) {
            for (Map<String, Object> condition : mustConditions) {
                boolQuery.must(buildConditionQuery(condition));
            }
        }
        
        // 添加should条件
        List<Map<String, Object>> shouldConditions = (List<Map<String, Object>>) queryParams.get("should");
        if (shouldConditions != null) {
            for (Map<String, Object> condition : shouldConditions) {
                boolQuery.should(buildConditionQuery(condition));
            }
            Integer minimumShouldMatch = (Integer) queryParams.get("minimum_should_match");
            if (minimumShouldMatch != null) {
                boolQuery.minimumShouldMatch(minimumShouldMatch);
            }
        }
        
        // 添加must_not条件
        List<Map<String, Object>> mustNotConditions = (List<Map<String, Object>>) queryParams.get("must_not");
        if (mustNotConditions != null) {
            for (Map<String, Object> condition : mustNotConditions) {
                boolQuery.mustNot(buildConditionQuery(condition));
            }
        }
        
        // 添加filter条件
        List<Map<String, Object>> filterConditions = (List<Map<String, Object>>) queryParams.get("filter");
        if (filterConditions != null) {
            for (Map<String, Object> condition : filterConditions) {
                boolQuery.filter(buildConditionQuery(condition));
            }
        }
        
        sourceBuilder.query(boolQuery);
        
        // 设置高亮
        Boolean highlight = (Boolean) queryParams.get("highlight");
        if (highlight != null && highlight) {
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            List<String> highlightFields = (List<String>) queryParams.get("highlight_fields");
            if (highlightFields != null) {
                for (String field : highlightFields) {
                    highlightBuilder.field(field);
                }
            }
            sourceBuilder.highlighter(highlightBuilder);
        }
        
        searchRequest.source(sourceBuilder);
        
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        logger.info("Bool query completed, hits: {}", response.getHits().getTotalHits());
        return response;
    }
    
    private QueryBuilder buildConditionQuery(Map<String, Object> condition) {
        String type = (String) condition.get("type");
        switch (type) {
            case "match":
                return QueryBuilders.matchQuery((String) condition.get("field"), condition.get("value"));
            case "term":
                return QueryBuilders.termQuery((String) condition.get("field"), condition.get("value"));
            case "range":
                return QueryBuilders.rangeQuery((String) condition.get("field"))
                    .from(condition.get("from"))
                    .to(condition.get("to"));
            default:
                throw new IllegalArgumentException("Unknown condition type: " + type);
        }
    }
    
    @Override
    public QueryBuilder buildQuery(Map<String, Object> queryParams) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        
        // 这里简化处理,实际应该构建完整的布尔查询
        List<Map<String, Object>> mustConditions = (List<Map<String, Object>>) queryParams.get("must");
        if (mustConditions != null) {
            for (Map<String, Object> condition : mustConditions) {
                boolQuery.must(buildConditionQuery(condition));
            }
        }
        
        return boolQuery;
    }
    
    @Override
    public String getStrategyType() {
        return "BOOL_QUERY";
    }
}

// 具体策略 - 聚合查询
public class AggregationQueryStrategy implements ElasticsearchQueryStrategy<Map<String, Object>> {
    
    private final RestHighLevelClient client;
    private final Logger logger = LoggerFactory.getLogger(AggregationQueryStrategy.class);
    
    public AggregationQueryStrategy(RestHighLevelClient client) {
        this.client = client;
    }
    
    @Override
    public SearchResponse executeQuery(String index, Map<String, Object> queryParams) throws IOException {
        logger.info("Executing aggregation query on index: {}, params: {}", index, queryParams);
        
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        
        // 构建聚合查询
        Map<String, Object> aggregations = (Map<String, Object>) queryParams.get("aggregations");
        if (aggregations != null) {
            for (Map.Entry<String, Object> entry : aggregations.entrySet()) {
                String aggName = entry.getKey();
                Map<String, Object> aggConfig = (Map<String, Object>) entry.getValue();
                AggregationBuilder aggregationBuilder = buildAggregation(aggName, aggConfig);
                sourceBuilder.aggregation(aggregationBuilder);
            }
        }
        
        // 设置查询条件(可选)
        Map<String, Object> query = (Map<String, Object>) queryParams.get("query");
        if (query != null) {
            sourceBuilder.query(buildQuery(query));
        }
        
        // 设置size为0,只返回聚合结果
        sourceBuilder.size(0);
        
        searchRequest.source(sourceBuilder);
        
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        logger.info("Aggregation query completed, aggregations: {}", response.getAggregations().getAsMap().size());
        return response;
    }
    
    private AggregationBuilder buildAggregation(String name, Map<String, Object> config) {
        String type = (String) config.get("type");
        String field = (String) config.get("field");
        
        switch (type) {
            case "terms":
                return AggregationBuilders.terms(name).field(field);
            case "avg":
                return AggregationBuilders.avg(name).field(field);
            case "sum":
                return AggregationBuilders.sum(name).field(field);
            case "max":
                return AggregationBuilders.max(name).field(field);
            case "min":
                return AggregationBuilders.min(name).field(field);
            case "date_histogram":
                String interval = (String) config.get("interval");
                return AggregationBuilders.dateHistogram(name).field(field).calendarInterval(
                    DateHistogramInterval.valueOf(interval));
            default:
                throw new IllegalArgumentException("Unknown aggregation type: " + type);
        }
    }
    
    private QueryBuilder buildQuery(Map<String, Object> queryParams) {
        // 简化处理,实际应该构建完整的查询
        return QueryBuilders.matchAllQuery();
    }
    
    @Override
    public QueryBuilder buildQuery(Map<String, Object> queryParams) {
        return QueryBuilders.matchAllQuery(); // 聚合查询通常使用match_all
    }
    
    @Override
    public String getStrategyType() {
        return "AGGREGATION_QUERY";
    }
}

// 上下文 - Elasticsearch查询策略管理器
public class ElasticsearchQueryStrategyManager {
    
    private final Map<String, ElasticsearchQueryStrategy<?>> strategies = new HashMap<>();
    private final RestHighLevelClient client;
    private final Logger logger = LoggerFactory.getLogger(ElasticsearchQueryStrategyManager.class);
    
    public ElasticsearchQueryStrategyManager(RestHighLevelClient client) {
        this.client = client;
        // 注册默认策略
        strategies.put("match", new MatchQueryStrategy(client));
        strategies.put("range", new RangeQueryStrategy(client));
        strategies.put("bool", new BoolQueryStrategy(client));
        strategies.put("aggregation", new AggregationQueryStrategy(client));
    }
    
    public void registerStrategy(String name, ElasticsearchQueryStrategy<?> strategy) {
        strategies.put(name, strategy);
        logger.info("Registered Elasticsearch query strategy: {}", name);
    }
    
    @SuppressWarnings("unchecked")
    public <T> ElasticsearchQueryStrategy<T> getStrategy(String name) {
        return (ElasticsearchQueryStrategy<T>) strategies.get(name);
    }
    
    public <T> SearchResponse executeQuery(String strategyName, String index, T queryParams) throws IOException {
        ElasticsearchQueryStrategy<T> strategy = getStrategy(strategyName);
        if (strategy != null) {
            logger.info("Executing query using strategy: {}, index: {}", strategyName, index);
            return strategy.executeQuery(index, queryParams);
        } else {
            throw new IllegalArgumentException("Unknown query strategy: " + strategyName);
        }
    }
    
    public <T> QueryBuilder buildQuery(String strategyName, T queryParams) {
        ElasticsearchQueryStrategy<T> strategy = getStrategy(strategyName);
        if (strategy != null) {
            return strategy.buildQuery(queryParams);
        } else {
            throw new IllegalArgumentException("Unknown query strategy: " + strategyName);
        }
    }
    
    public List<String> getAvailableStrategies() {
        return new ArrayList<>(strategies.keySet());
    }
}

总结

这些实例展示了策略模式在现代分布式系统、消息队列、缓存系统和搜索引擎中的广泛应用,每个实例都包含了完整的策略接口、具体策略实现和上下文管理,提供了灵活的配置和扩展机制。

策略模式在开源框架中应用广泛,主要场景包括:

  1. 算法选择:提供不同的算法实现,允许运行时选择
  2. 排序和比较:提供不同的排序和比较策略
  3. 缓存策略:提供不同的缓存加载和过期策略
  4. 限流策略:提供不同的限流算法实现
  5. 负载均衡:提供不同的负载均衡算法
  6. 日志记录:提供不同的日志输出目标
  7. 编码和加密:提供不同的编码和加密算法
  8. 重定向处理:提供不同的HTTP重定向处理策略

策略模式的优点:

  • 算法可以自由切换,易于扩展
  • 避免使用多重条件判断
  • 扩展性良好,增加策略很简单
  • 策略类可以复用,减少重复代码

策略模式的缺点:

  • 策略类会增多,增加系统复杂度
  • 所有策略类都需要对外暴露,客户端必须知道有哪些策略
  • 客户端需要理解所有策略的区别,才能选择合适的策略
Java装饰器模式实战:从IO源码到Spring事务的动态能力叠加 装饰器模式是一种通过组合而非继承来动态扩展对象功能的设计思想,其核心在于统一接口、持有委托、责任分离。它解决了多维度功能自由组合时的类爆炸问题,天然契合开闭原则与单一职责原则。在Java生态中,该模式广泛应用于标准IO(如BufferedReader)、Spring AOP(@Transactional代理链)、HTTP客户端增强(日志、计时、熔断)等场景,是理解框架底层机制与构建高可维护性系统的关键范式。掌握装饰器模式,意味着能精准识别何时‘叠加能力’优于‘修改逻辑’,从而写出更清晰、更易测试、更易演进的 阅读详情

相关推荐

07-Hugging Face Transformers 分词器系统深度分析

本文深入分析了Hugging Face Transformers的分词器系统架构。系统采用多后端设计,包括PythonBackend慢分词器、SentencePieceBackend、TokenizersBackend快速分词器和MistralCommonBackend。核心基类PreTrainedTokenizerBase定义了统一接口,支持特殊Token管理和多种分词策略。文章详细剖析了各后端实现原理、BatchEncoding数据结构以及V5版本的重要改进,如慢快分词器转换、聊天模板系统和结构化输出解

ld326的专栏 582

空对象模式(Null Object Pattern)精讲 —— CS-Notes 行为型设计模式解析

空对象模式(Null Object)是行为型设计模式之一,其核心思想是**用一个"什么都不做"的空对象来代替 `null` 返回值**,从而让调用方不再需要层层判空。本文以 CS-Notes 仓库 notes/设计模式 - 空对象.md 为骨架,结合完整代码示例,系统讲解该模式的意图、类图结构、实现要点、适用场景与取舍,帮助你在阅读源码与面试表达时快速抓住关键。 [![空对象模式 UML 类图:

gitblog_00688的博客 400

C++康复训练系统:设计模式、实时控制与Qt界面的工程实践

在嵌入式与实时系统开发中,C++因其高性能和硬件直接操作能力成为核心选择。其原理在于通过精细的内存管理、低延迟响应和高效的编译优化,满足对时序有严格要求的应用场景。这一技术价值体现在工业控制、机器人、医疗设备等需要高可靠性与实时性的领域。设计模式作为构建可维护、可扩展软件架构的关键,通过策略模式、状态模式等解耦模块,提升代码复用性。应用场景广泛,从自动化产线到康复医疗设备均依赖于此。本文聚焦于康复训练系统的实现,详细阐述了如何运用C++、设计模式及Qt框架,构建一个模块化、实时的上下肢康复训练系统,并提供了

weixin_33860528的博客 379

大白话说Java设计模式-26-策略模式(业务实战篇)

本文结合大白商城支付渠道多算法切换业务场景,详解策略模式的核心设计思想与实战实现,对比if-else堆叠、继承等反面方案的痛点,拆解抽象策略、具体策略、上下文三大核心角色,提供Spring自动注入方式的生产级可运行完整代码实现,对比策略与工厂方法、状态模式的本质差异与适用场景,深入解读Spring ResourceLoader的策略实现原理,给出工程决策Checklist与6大常见坑解决方案,帮助开发者掌握如何运用策略模式实现加新算法不动老代码,解决多分支代码臃肿、耦合度高的问题,提升代码可扩展性与可维护性

Java后端 | AI智能体应用实战派 | 电脑技能行家 206

软件设计模式在仓库管理系统中的工程化实践

软件设计模式是面向对象编程中解耦、复用与可维护的核心方法论。其原理在于通过抽象接口、封装变化点和定义协作契约,将业务逻辑与实现细节分离,从而提升系统扩展性与测试性。在实际工程中,设计模式的价值体现在应对需求演进——如从单仓到多仓、从本地到对接第三方服务时,避免大规模重构。典型应用场景包括库存管理中的策略切换、事件通知解耦、对象创建隔离等。本文以小型仓库管理系统为载体,深入剖析工厂模式、策略模式与观察者模式的协同落地,聚焦如何用模式驱动代码从CRUD堆砌走向高内聚低耦合的架构实践。

weixin_29879257的博客 169

ubuntu安装FSL

1.下载fslinstaller.py 官网下载地址:https://fsl.fmrib.ox.ac.uk/fsldownloads_registration 或者去我的百度网盘取: 链接:https://pan.baidu.com/s/1d5eHm48oamFdYdKm84nifw 提取码:6ff9 2.将base环境改成python2.0版本 本来想在服务器安装,服务器没有sudo权限,网上很多教程都装不了,于是就自己安装虚拟机再装了一个ubuntu,然后安装了python2环境,再开始装fsl,fsl

qq_36421001的博客 4098

大白话说Java设计模式-01-开篇总览(附50篇学习路线图)

本文是大白话说Java设计模式系列的开篇总览,系统梳理23种经典设计模式的分类、核心思想与适用场景,提供完整的50篇学习路线图,讲解设计模式的学习方法、落地原则与避坑指南,帮助开发者建立设计模式的全局知识体系,掌握如何在业务实战中灵活运用设计模式提升代码质量。

Java后端 | AI智能体应用实战派 | 电脑技能行家 599

【Pandas总结】第二节 Pandas 的数据读取_pd.read_csv()的使用详解(非常全面,推荐收藏)

pandas对纯文本的读取提供了非常强力的支持,参数有四五十个。这些参数中,有的很容易被忽略,但是在实际工作中却用处很大。

weixin_47139649的博客 11万+

《JAVA面经实录》- SpringBoot 电商项目23种设计模式(三)

最终版·生产级 SpringBoot 电商项目: 已补全所有漏洞 + 23 种设计模式真实串联 + Spring 生态融合 + 可简历可面试可上线

专注 Java 后端开发,分享基础语法、JVM、并发、Spring 全家桶、微服务、分布式、性能优化等实战干货。坚持输出高质量技术笔记,用简单语言讲清复杂原理,助力每一位 Java 开发者稳步进阶。 556

Ubuntu20.04安全重启后WiFi图标消失?MT7922网卡驱动修复全攻略

本文详细解析了Ubuntu20.04安全重启后WiFi图标消失的问题,特别是针对MT7922网卡驱动失效的情况。通过诊断命令和分步解决方案,包括禁用PCIe ASPM、更新无线固件和升级HWE内核,帮助用户快速恢复网络连接。文章还提供了进阶排查技巧和系统优化建议,确保WiFi稳定运行。

weixin_29202687的博客 368

Linux 使用rm -rf /*命令后,恢复系统方法

Linux 使用rm -rf /*命令后,恢复系统方法 个人学习记录 这里实验环境采用的是radhel7.1的版本: 个人认为核心就是缺失什么组件,就从别的地方复制什么组件过来,先把系统拉起来,再慢慢恢复配置 进入救援模式 1、将/dev/sda两个分区分别挂载看看,里面的内容,有内容的就是根存在的分区 2、ifconfig eno16777777 192.168.8.2 3、从另外一台一样系统的根 。用 tar打包,一个个文件夹拷贝过来 4、到坏系统,scp另外一个系统的etc.tar.gz 5

weixin_43603476的博客 1万+

Java 23 种设计模式

/ 产品族:Button + TextField 是一套// Windows 风格} }} }// Mac 风格} }} }// 抽象工厂 — 创建产品族一句话:普通工厂一个方法一种产品,抽象工厂一个方法多个关联产品。// 计算 "1 + 2 - 3"right = r;// 使用// 3一句话:很少用,JDK 的就是。创建型 — 怎么 new单例(一个)→ 工厂(子类决定)→ 抽象工厂(产品族)→ 建造者(分步构造)→ 原型(克隆)结构型 — 类/对象怎么组合。

鲜衣怒马少年时,不负韶华行且知。 从第一个Hello World起,便踏上这条后端修行路。趟过分布式事务的浑水,翻过性能瓶颈的高山,方知代码如剑,需千锤百炼方显锋芒。 博客所记,皆为修行路上的顿悟与磕绊,愿与同道人共勉,稳步江湖。 316

IMU、INS、GNSS与组合导航:从原理到工程实践全解析

在自动驾驶、无人机和机器人等智能系统的定位方案中,IMU、INS、GNSS和组合导航常被混为一谈,但它们在硬件层级、数据特性和误差机制上截然不同。IMU作为惯性测量单元,以百赫兹以上频率输出加速度和角速度;INS基于IMU完成姿态、速度与位置的递推解算,却因积分累积误差而随时间漂移;GNSS提供绝对位置,但易受遮挡和干扰。组合导航通过卡尔曼滤波将两者融合,实现短期不飘、长期不偏的连续定位,这正是高精度导航系统的技术底座。工程落地时,从IMU标定、Allan方差分析到相机/LiDAR与IMU外参标定,再到松耦

weixin_29193259的博客 378

从GoF到现代C++:设计模式在C++语言演进中的变迁与创新 [特殊字符]

在软件开发领域,设计模式一直是构建高质量代码的**终极指南**。从经典的GoF设计模式到现代C++的演变,设计模式在C++语言中经历了怎样的变迁?如何利用C++11、C++14、C++17等现代特性重新诠释这些经典模式?本文将为您揭示**设计模式在现代C++中的完整实现方法**,帮助您掌握面向对象编程的精髓。 ## 📊 设计模式:从经典到现代的演变历程 设计模式最初由Erich Gamma等

gitblog_00910的博客 399

Unity游戏Mono注入实战:从反编译到功能扩展

本文详细介绍了Unity游戏Mono注入的完整实战流程,从使用dnSpy反编译游戏核心逻辑,到编写自定义C#功能DLL,再到利用SharpMonoInjector进行动态注入。文章深入讲解了如何通过Harmony库拦截修改游戏方法,并介绍了使用MelonLoader框架和UnityExplorer进行高级模组开发与调试,最终通过一个游戏对象透视(ESP)案例演示了功能扩展的实现。

weixin_29018335的博客 458

杰理SDK入门教程(二):USB升级程序

开发板升级操作指南 摘要:本文介绍了开发板程序升级的两种方式(常规升级和串口升级),重点说明了常规升级的操作步骤: 拨码设置:提供4种拨码方式(不拨/1档/2档/3档),对应不同指示灯状态和按键要求 硬件连接:强制升级工具需正确连接电脑和开发板(注意USB接口方向) 升级流程:根据拨码状态操作按键,观察指示灯变化(红灯常亮绿灯灭表示进入升级模式) 执行升级:运行SDK中的download.bat完成升级 文中还包含拨码开关说明、指示灯状态对照表以及升级原理说明,帮助用户理解升级过程。升级成功后在设备管理器可

qq_42014563的博客 1115

23个设计模式一文搞懂

本笔记涵盖 23 种经典设计模式,按创建型、结构型、行为型三大类整理。每个模式配有生活类比、核心思想、结构图解、实现要点、真实应用案例、适用场景、优缺点分析及常见面试题。

weixin_72753562的博客 802

基于共识的捆绑算法CBBA在多无人机多任务调度中的实现

在捆绑过程中,每个无人机根据自己的任务清单和其他无人机的任务清单,确定一个被称为“束”的集合。通过合理的任务分配和无人机协作,CBBA算法能够实现最优的任务调度,提高了多无人机系统的效率和执行能力。在每一轮迭代中,无人机根据自己的当前任务和位置信息将任务清单发送给其他无人机,并接收其他无人机发送过来的任务清单。通过比较其他无人机的任务清单和自身的任务清单,每个无人机可以更新自己的任务分配情况。在这一步中,每个无人机根据自己选择的新任务,更新自身的任务清单,并将更新后的清单发送给其他无人机。

持续更新 1154

C++多态机制深度解析:从虚函数表到设计模式实战

多态是面向对象编程的核心概念之一,它允许通过统一的接口处理不同的数据类型,是实现代码复用和扩展性的关键技术。其原理基于虚函数和虚函数表,通过运行时动态绑定,使得程序能够根据对象的实际类型调用相应的方法。这一机制极大地提升了软件设计的灵活性,降低了模块间的耦合度,是构建可维护大型系统的基础。在工程实践中,多态广泛应用于图形系统、插件架构、策略模式等场景,是实现开闭原则的关键。本文以C++为例,深入剖析了虚函数表的工作原理,并结合对象切片、虚析构函数等常见陷阱,以及现代C++中的override与final关键

weixin_34262482的博客 347

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【NVIDIA】NVIDIA Container Toolkit v1.19.1 源码架构总览之一

NVIDIA Container Toolkit(以下简称 NVCTK)是 NVIDIA 官方开源的容器 GPU 支持工具集,其核心使命是让 GPU 加速容器变得透明且易于使用。在没有 NVCTK 之前,要在容器中使用 GPU,用户需要手动挂载设备节点、拷贝用户态驱动库、配置环境变量——这是一件极其繁琐且容易出错的工作。NVCTK 将这一切自动化了。NVCTK 的前身是 项目(2016 年发布),后来演化为 和 两个层级的工具。到 v1.19.1 时,项目已经经历了多次重大架构演进,从最初的简单 ho

zhonglinzhang 412

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Java instanceof操作符:类型检查与模式匹配实战

类型检查是面向对象编程的核心机制,Java通过instanceof操作符实现运行时类型识别。其原理是通过JVM层面的Klass指针遍历继承链,相比getClass()方法具有更好的多态支持。在工程实践中,instanceof既能防止ClassCastException确保类型安全,又能在框架开发中处理动态代理和泛型擦除问题。随着Java16+的模式匹配特性引入,instanceof进一步升级为支持变量绑定的智能类型检查工具,广泛应用于策略模式、访问者模式等设计场景。合理使用这一基础操作符,能显著提升代码的健

weixin_34121304的博客 372

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C++模板编程:从基础语法到STL实战的泛型编程指南

泛型编程是一种编程范式,其核心思想是编写独立于数据类型的代码。在C++中,这一理念主要通过模板技术实现,它允许开发者定义可处理多种数据类型的函数或类,而无需为每种类型重复编写代码。其原理是编译器在编译期间根据具体使用的类型生成特化版本,从而实现类型安全且无运行时开销的抽象。这种技术价值在于提升代码复用性、减少冗余,并能在编译期完成类型检查和优化,生成与手写代码同等高效的机器码。应用场景广泛,从简单的通用算法(如排序、查找)到复杂的数据结构(如容器、智能指针)都依赖模板实现。本文聚焦C++模板编程,深入解析函

weixin_34183910的博客 487

Uni-Mol Tools CLI 架构设计:基于 CLI-Anything 的分子性质预测命令行工具全解析

Uni-Mol Tools CLI 是基于 CLI-Anything 框架构建的命令行工具(harness),它为分子性质预测提供了一套完整、可交互的终端工作流:从项目初始化、数据集配置、Uni-Mol 模型训练与推理,到模型排行、存储分析与安全清理。本文以 [架构设计文档](https://link.gitcode.com/i/236b074c7adb6e12620dea78a802f512)

gitblog_00981的博客 808

大白话说Java设计模式-04-工厂方法模式(业务实战篇)

本文结合支付渠道对接的业务场景详解工厂方法模式的核心实现与实战应用,讲解工厂方法模式的四大核心角色(抽象产品、具体产品、抽象工厂、具体工厂)的设计思路,对比简单工厂、工厂方法、抽象工厂三种模式的适用场景差异,分析工厂方法模式在Spring、MyBatis等框架中的应用案例,帮助开发者掌握如何在业务中灵活运用工厂方法模式解耦对象创建逻辑。

Java后端 | AI智能体应用实战派 | 电脑技能行家 371

如何把B站视频变成5分钟能读完的笔记:BiliTools AI总结实操指南

BiliTools 是一个开源的哔哩哔哩工具箱,其中对学习最实用的能力之一是 AI 总结:粘贴一个视频链接,就能生成一份带标题、核心摘要和时间戳大纲的 Markdown 笔记。本文先展示这份文件长什么样,再讲清开关在哪里勾选、文件存在哪、拿到之后怎么用。 ## 📄 BiliTools 的 AI 总结 Markdown 长什么样 一份文件对应一个视频,内容固定为三段: 1. **标题行**:

gitblog_00958的博客 1003

大白话说Java设计模式-16-装饰器模式(业务实战篇)

本文结合订单价格计算叠加优惠、接口响应数据加密等业务场景详解装饰器模式的核心实现与实战应用,讲解装饰器模式的核心角色与透明装饰、半透明装饰两种实现方式,对比装饰器模式与继承、代理模式的适用场景差异,分析装饰器模式在功能动态扩展、能力灵活组合等场景的设计优势,帮助开发者掌握如何在业务中运用装饰器模式实现功能灵活插拔,提升代码可扩展性。

Java后端 | AI智能体应用实战派 | 电脑技能行家 323
上一篇: 设计模式-16状态模式 (State Pattern) 源码实例大全
下一篇: 设计模式-18责任链模式 (Chain of Responsibility Pattern) 源码实例大全
d3y1
博客等级 码龄12年 1438粉丝 2772原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值