策略模式 (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重定向处理策略

策略模式的优点:

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

策略模式的缺点:

  • 策略类会增多,增加系统复杂度
  • 所有策略类都需要对外暴露,客户端必须知道有哪些策略
  • 客户端需要理解所有策略的区别,才能选择合适的策略
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐