吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 649|回复: 7
收起左侧

[Java 原创] 观帖有感,Java 策略设计模式

[复制链接]
公子语凉 发表于 2026-1-4 23:19
废话少说,上代码

定义注解:
[Java] 纯文本查看 复制代码
package com.jichangxiu.server.common.core.annotation;

import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;

import java.lang.annotation.*;

/**
* Handler:
*
* [url=home.php?mod=space&uid=686208]@AuThor[/url] Jcx
* [url=home.php?mod=space&uid=441028]@Since[/url] 2025-01-01 00:00:00
*/
@Component
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public [url=home.php?mod=space&uid=593715]@interface[/url] Handler {

    @AliasFor(annotation = Component.class)
    String value() default "";

}


业务枚举继承接口
[Java] 纯文本查看 复制代码
package com.jichangxiu.server.common.core.strategy;

/**
* Strategy:
*
* @author Jcx
* @since 2025-01-01 00:00:00
*/
public interface Strategy<PARAMETER, RESULT> {

}


业务执行器接口:
[Java] 纯文本查看 复制代码
package com.jichangxiu.server.common.core.strategy;

public interface Executor<PARAMETER, RESULT> {

    Strategy<PARAMETER, RESULT> strategy();

    RESULT execute(PARAMETER parameter);

}


工厂调度器:

[Java] 纯文本查看 复制代码
package com.jichangxiu.server.common.core.factory;

import com.jichangxiu.server.common.core.strategy.Strategy;
import com.jichangxiu.server.common.core.strategy.Executor;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
* StrategyFactory:
*
* @author Jcx
* @since 2025-01-01 00:00:00
*/
public class StrategyFactory {

    private static final Map<Strategy<?, ?>, Executor<?, ?>> STRATEGY_MAP = new ConcurrentHashMap<>();

    /**
     * 私有构造函数
     */
    private StrategyFactory() {
    }

    /**
     * 注册策略
     *
     * @Param strategy 策略码
     * @param executor 策略
     */
    public static void register(Strategy<?, ?> strategy, Executor<?, ?> executor) {
        Objects.requireNonNull(strategy, "Strategy 不能为空");
        Objects.requireNonNull(executor, "Executor 不能为空");
        STRATEGY_MAP.put(strategy, executor);
    }

    /**
     * 获取策略
     *
     * @param strategy 策略码
     * @Return 策略
     */
    public static <PARAMETER, RESULT> Executor<PARAMETER, RESULT> get(Strategy<PARAMETER, RESULT> strategy) {
        return (Executor<PARAMETER, RESULT>) STRATEGY_MAP.get(strategy);
    }

    /**
     * 判断策略是否存在
     *
     * @param strategy 策略码
     * @return 策略是否存在
     */
    public static boolean contains(Strategy<?, ?> strategy) {
        return STRATEGY_MAP.containsKey(strategy);
    }

    /**
     * 获取策略数量
     *
     * @return 策略数量
     */
    public static int size() {
        return STRATEGY_MAP.size();
    }

    /**
     * 移除策略
     *
     * @param strategy 策略码
     */
    public static void remove(Strategy<?, ?> strategy) {
        STRATEGY_MAP.remove(strategy);
    }

    /**
     * 清空策略
     */
    public static void clear() {
        STRATEGY_MAP.clear();
    }

    /**
     * 执行策略
     *
     * @param strategy  策略码
     * @param parameter 参数
     * @return 结果
     */
    @SuppressWarnings("unchecked")
    public static <PARAMETER, RESULT> RESULT doExecute(Strategy<PARAMETER, RESULT> strategy, PARAMETER parameter) {
        Executor<PARAMETER, RESULT> executor = (Executor<PARAMETER, RESULT>) STRATEGY_MAP.get(strategy);
        if (executor == null) {
            throw new IllegalStateException("未找到 Strategy 对应的 Executor: " + strategy);
        }
        return executor.execute(parameter);
    }

}


spring 启动扫描Handler注解
[Java] 纯文本查看 复制代码
package com.jichangxiu.server.starter.action.scanner;

import com.jichangxiu.server.common.aop.utils.AopUtils;
import com.jichangxiu.server.common.core.annotation.Handler;
import com.jichangxiu.server.common.core.factory.StrategyFactory;
import com.jichangxiu.server.common.core.strategy.Executor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotatedElementUtils;

import java.util.Map;

/**
* HandlerScanner:
*
* @author Jcx
* @since 2025-01-01 00:00:00
*/
@Slf4j
public class HandlerScanner {

    public HandlerScanner(ApplicationContext applicationContext) {
        Map<String, Object> beans = applicationContext.getBeansWithAnnotation(Handler.class);
        beans.values().forEach(bean -> {
            Class<?> targetClass = AopUtils.getTargetClass(bean);
            Handler handler = AnnotatedElementUtils.findMergedAnnotation(targetClass, Handler.class);
            if (handler == null) {
                return;
            }
            // 1&#65039;&#8419; 校验 Executor
            if (!(bean instanceof Executor<?, ?> executor)) {
                log.warn("&#9888;&#65039; Bean [{}] 标注了 @Handler 但未实现 Executor 接口", targetClass.getName());
                return;
            }
            // 2&#65039;&#8419; 注册
            StrategyFactory.register(executor.strategy(), executor);
            log.info("&#9989; 注册 Strategy: {} -> {}", executor.strategy(), targetClass.getSimpleName());
        });
        log.info("&#128640; StrategyFactory 初始化完成,共 {} 个策略", StrategyFactory.size());
    }

}


注册 Scanner 到 spring boot
[Java] 纯文本查看 复制代码
/**
* ActionConfig:
* Action 配置
*
* @author Jcx
* @since 2025-01-01 00:00:00
*/
@Slf4j
@AutoConfiguration
public class ActionConfig {

    /**
     * 策略注册 Bean
     *
     * @param applicationContext 应用上下文
     * @return 策略注册 Bean
     */
    @Bean
    public HandlerScanner handlerScanner(ApplicationContext applicationContext) {
        log.info("&#9989; 成功加载【HandlerScanner】");
        return new HandlerScanner(applicationContext);
    }
}




测试的类:
[Java] 纯文本查看 复制代码
package com.jichangxiu.server.application.boot.strategy.enums;

import com.jichangxiu.server.application.boot.strategy.parameter.CalcParameter;
import com.jichangxiu.server.common.core.strategy.Strategy;

import java.math.BigDecimal;

public enum CalcStrategy implements Strategy<CalcParameter, BigDecimal> {

    DIV,

    SUM;

}


package com.jichangxiu.server.application.boot.strategy.executor;

import com.jichangxiu.server.application.boot.strategy.enums.CalcStrategy;
import com.jichangxiu.server.application.boot.strategy.parameter.CalcParameter;
import com.jichangxiu.server.common.core.annotation.Handler;
import com.jichangxiu.server.common.core.strategy.Executor;
import com.jichangxiu.server.common.core.strategy.Strategy;

import java.math.BigDecimal;
import java.math.RoundingMode;

@Handler
public class DivExecutor implements Executor<CalcParameter, BigDecimal> {

    @Override
    public Strategy<CalcParameter, BigDecimal> strategy() {
        return CalcStrategy.DIV;
    }

    @Override
    public BigDecimal execute(CalcParameter calcParameter) {
        BigDecimal a = calcParameter.getA();
        BigDecimal b = calcParameter.getB();
        return a.divide(b, RoundingMode.HALF_UP);
    }

}


package com.jichangxiu.server.application.boot.strategy.executor;

import com.jichangxiu.server.application.boot.strategy.enums.CalcStrategy;
import com.jichangxiu.server.application.boot.strategy.parameter.CalcParameter;
import com.jichangxiu.server.common.core.annotation.Handler;
import com.jichangxiu.server.common.core.strategy.Strategy;
import com.jichangxiu.server.common.core.strategy.Executor;

import java.math.BigDecimal;

@Handler
public class SumExecutor implements Executor<CalcParameter, BigDecimal> {

    @Override
    public Strategy<CalcParameter, BigDecimal> strategy() {
        return CalcStrategy.SUM;
    }

    @Override
    public BigDecimal execute(CalcParameter calcParameter) {
        BigDecimal a = calcParameter.getA();
        BigDecimal b = calcParameter.getB();
        return a.add(b);
    }

}




package com.jichangxiu.server.application.boot.strategy.parameter;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class CalcParameter {

    private BigDecimal a;

    private BigDecimal b;

}


package com.jichangxiu.server.application.boot.action;

import com.jichangxiu.server.application.boot.strategy.enums.CalcStrategy;
import com.jichangxiu.server.application.boot.strategy.parameter.CalcParameter;
import com.jichangxiu.server.common.core.annotation.Everyone;
import com.jichangxiu.server.common.core.factory.StrategyFactory;
import com.jichangxiu.server.starter.action.annotation.Get;
import com.jichangxiu.server.starter.action.annotation.Rest;

import java.math.BigDecimal;

@Everyone
@Rest("/strategy")
public class StrategyAction {

    @Get("/test")
    public String test() {
        BigDecimal result = StrategyFactory.doExecute(
                CalcStrategy.SUM,
                new CalcParameter(
                        BigDecimal.valueOf(1),
                        BigDecimal.valueOf(2)
                )
        );
        return "执行策略:" + result;
    }

}

免费评分

参与人数 2吾爱币 +7 热心值 +2 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
yxzzz666 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 公子语凉 发表于 2026-1-4 23:20

原帖:https://www.52pojie.cn/forum.php?mod=viewthread&tid=2070688&extra=page%3D1%26filter%3Dtypeid%26typeid%3D388
 楼主| 公子语凉 发表于 2026-1-4 23:24
package com.jichangxiu.server.common.core.strategy;

/**
* Strategy:
*
* @author Jcx
* @since 2025-01-01 00:00:00
*/
public interface Strategy {

}


这个类可以不保留泛型,没必要,相应的泛型一起去掉
datangshizhewu 发表于 2026-1-5 08:49
Carinx 发表于 2026-1-5 12:05
这个[url=home.php?mod=space&uid=593715]是啥?
 楼主| 公子语凉 发表于 2026-1-5 19:18

论坛代码试图展示的 bug 我也不知道
brute 发表于 2026-1-6 09:41
搬好板凳学习~
WXZLBN 发表于 2026-1-7 14:08

搬好板凳学习~
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-1-8 19:20

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表