Java实现策略模式


前言

策略模式是很常用的设计模式,可以解耦大量的 if…else… 堆积,下面使用设计模式实现常用的审核功能。

代码

1. 枚举

public enum ExpReviewStatus {
    UNKNOWN(0, "未知"),
    WAITING(1, "待审核"),
    APPROVE(2, "审核通过"),
    REFUSE(3, "审核拒绝"),
    END(10, "流程终结"),
    ;

    private final int status;
    private final String desc;

    ExpReviewStatus(int status, String desc) {
        this.status = status;
        this.desc = desc;
    }

    public int status() {
        return status;
    }

    public String desc() {
        return desc;
    }

    public static ExpReviewStatus of(int status) {
        for (ExpReviewStatus reviewStatus : ExpReviewStatus.values()) {
            if (reviewStatus.status == status) {
                return reviewStatus;
            }
        }
        return UNKNOWN;
    }

    public static boolean isValid(int status) {
        for (ExpReviewStatus reviewStatus : ExpReviewStatus.values()) {
            if (reviewStatus.status == status) {
                return true;
            }
        }
        return false;
    }
}

注意:这里使用枚举来管理服务

/**
 * 策略模式的服务管理者
 */
public enum ExpReviewServiceManager {
    UNKNOWN(ExpReviewStatus.UNKNOWN.status(), null),
    WAITING(ExpReviewStatus.WAITING.status(), ExpReviewWaitingService.class),
    APPROVE(ExpReviewStatus.APPROVE.status(), ExpReviewApproveService.class),
    REFUSE(ExpReviewStatus.REFUSE.status(), ExpReviewRefuseService.class),
    END(ExpReviewStatus.END.status(), ExpReviewEndService.class),
    ;

    private final int status;
    private final Class<? extends ExpReviewServiceInterface> aClass;

    ExpReviewServiceManager(int status, Class<? extends ExpReviewServiceInterface> aClass) {
        this.status = status;
        this.aClass = aClass;
    }

    public int status() {
        return status;
    }

    public static ExpReviewServiceManager of(int status) {
        for (ExpReviewServiceManager reviewMsg : ExpReviewServiceManager.values()) {
            if (reviewMsg.status == status) {
                return reviewMsg;
            }
        }
        return UNKNOWN;
    }

    public ExpReviewServiceInterface getReviewService() {
        return SpringBeanUtils.getBean(aClass);
    }
}
@Component
public class SpringBeanUtils implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        applicationContext = context;
    }

    public static <T> T getBean(Class<T> tClass) {
        return applicationContext.getBean(tClass);
    }

    public static <T> T getBean(String name) {
        return (T) applicationContext.getBean(name);
    }

    public static <T> T getBean(String name, Class<T> tClass) {
        return applicationContext.getBean(name, tClass);
    }
}

2. 服务

2.1 接口

/**
 * 策略模式接口
 */
public interface ExpReviewServiceInterface {
    /**
     * 实验编辑审核处理流程
     */
    Result<String> handleExpEditReview(ExpReviewDTO expReviewDTO);

    /**
     * 实验编辑审核消息发送
     *
     * @param expReviewDTO 参数
     */
    void sendExpEditDingDingMsg(ExpReviewDTO expReviewDTO);
}

2.2 抽象类

/**
 * 抽象类,定义一些子类通用的处理逻辑
 */
public abstract class AbstractExpReviewService implements ExpReviewServiceInterface {
    private final Logger log = LoggerFactory.getLogger(AbstractExpReviewService.class);

	// 定义一些通用的常量
    protected static final String EXP_REVIEW_KEY = "test:exp_review:id_to_data";
    protected static final int REVIEW_EXPIRE_SEC = (int) TimeUnit.DAYS.toSeconds(2);

    @Override
    public Result<String> handleExpEditReview(ExpReviewDTO expReviewDTO) {
        return new Result<>(HttpStatus.SERVICE_UNAVAILABLE.value(), "未找到对应的服务", "");
    }

    @Override
    public void sendExpEditDingDingMsg(ExpReviewDTO expReviewDTO) {
        List<String> ddUserIdList = getDDUserIdList(expReviewDTO);
        String title = getExpEditMarkdownMsgTitle(expReviewDTO);
        String content = getExpEditMarkdownMsgContent(expReviewDTO);
        DingDingUtil.sendRobotMarkdownMsg(ddUserIdList, title, content);
    }

    /**
     * 获取用户名对应的 dd_user_id, 用于发送钉钉消息
     *
     * @param expReviewDTO dto
     * @return dd_user_id list
     */
    protected List<String> getDDUserIdList(ExpReviewDTO expReviewDTO) {
        log.warn("未找到对应的子类实现");
        return Collections.emptyList();
    }

    /**
     * 获取消息标题,待子类实现
     *
     * @param expReviewDTO dto
     * @return message title
     */
    protected String getExpEditMarkdownMsgTitle(ExpReviewDTO expReviewDTO) {
        return "[Test] title 待子类实现";
    }

    /**
     * 获取消息内容,待子类实现
     *
     * @param expReviewDTO dto
     * @return message content
     */
    protected String getExpEditMarkdownMsgContent(ExpReviewDTO expReviewDTO) {
        return "[Test] content 待子类实现";
    }

    /**
     * 服务器在国外,时间需要转换成北京时间
     * 注意:后续如果服务器转移到国内需要取消转换
     *
     * @param date date
     * @return 北京时间 eg: 2006-01-02 15:04:05
     */
    protected String getBeijingDateTime(Date date) {
        // 处理时区,加8小时
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, 8);
        return DateTimeUtil.getFormatDateTime(calendar.getTime());
    }
}

2.3 服务

@Service
public class ExpReviewWaitingService extends AbstractExpReviewService {
    private final Logger log = LoggerFactory.getLogger(ExpReviewWaitingService.class);


    private Result<String> checkAuthority(ExpModel expModel) {
        // 权限检查
    }

    @Override
    public Result<String> handleExpEditReview(ExpReviewDTO expReviewDTO) {
        // 权限检查
        Result<String> result = checkAuthority(expModel);
        if (result.getCode() != HttpStatus.OK.value()) {
            return result;
        }
        // 业务逻辑处理
        
        // 发送钉钉消息
        this.sendExpEditDingDingMsg(dto);
    }

    @Override
    public void sendExpEditDingDingMsg(ExpReviewDTO expReviewDTO) {
    	// 直接调用了抽象类的公共逻辑
        super.sendExpEditDingDingMsg(expReviewDTO);
    }

    @Override
    protected List<String> getDDUserIdList(ExpReviewDTO expReviewDTO) {
    	// 获取 dd_user_id
    }

    @Override
    protected String getExpEditMarkdownMsgTitle(ExpReviewDTO expReviewDTO) {
        // 定义消息头
    }

    @Override
    protected String getExpEditMarkdownMsgContent(ExpReviewDTO expReviewDTO) {
        // 定义消息体
    }
}

@Service
public class ExpReviewApproveService extends AbstractExpReviewService {
    private final Logger log = LoggerFactory.getLogger(ExpReviewApproveService.class);

        private Result<String> checkAuthority(ExpModel expModel) {
        // 权限检查
    }

    @Override
    public Result<String> handleExpEditReview(ExpReviewDTO expReviewDTO) {
        // 权限检查
        Result<String> result = checkAuthority(expModel);
        if (result.getCode() != HttpStatus.OK.value()) {
            return result;
        }
        // 业务逻辑处理
        
        // 发送钉钉消息
        this.sendExpEditDingDingMsg(dto);
    }

    @Override
    public void sendExpEditDingDingMsg(ExpReviewDTO expReviewDTO) {
    	// 直接调用了抽象类的公共逻辑
        super.sendExpEditDingDingMsg(expReviewDTO);
    }

    @Override
    protected List<String> getDDUserIdList(ExpReviewDTO expReviewDTO) {
    	// 获取 dd_user_id
    }

    @Override
    protected String getExpEditMarkdownMsgTitle(ExpReviewDTO expReviewDTO) {
        // 定义消息头
    }

    @Override
    protected String getExpEditMarkdownMsgContent(ExpReviewDTO expReviewDTO) {
        // 定义消息体
    }
}

@Service
public class ExpReviewRefuseService extends AbstractExpReviewService {
    private final Logger log = LoggerFactory.getLogger(ExpReviewRefuseService.class);

    private Result<String> checkAuthority(ExpModel expModel) {
        // 权限检查
    }

    @Override
    public Result<String> handleExpEditReview(ExpReviewDTO expReviewDTO) {
        // 权限检查
        Result<String> result = checkAuthority(expModel);
        if (result.getCode() != HttpStatus.OK.value()) {
            return result;
        }
        // 业务逻辑处理
        
        // 发送钉钉消息
        this.sendExpEditDingDingMsg(dto);
    }

    @Override
    public void sendExpEditDingDingMsg(ExpReviewDTO expReviewDTO) {
    	// 直接调用了抽象类的公共逻辑
        super.sendExpEditDingDingMsg(expReviewDTO);
    }

    @Override
    protected List<String> getDDUserIdList(ExpReviewDTO expReviewDTO) {
    	// 获取 dd_user_id
    }

    @Override
    protected String getExpEditMarkdownMsgTitle(ExpReviewDTO expReviewDTO) {
        // 定义消息头
    }

    @Override
    protected String getExpEditMarkdownMsgContent(ExpReviewDTO expReviewDTO) {
        // 定义消息体
    }
}

@Service
public class ExpReviewEndService extends AbstractExpReviewService {
    private final Logger log = LoggerFactory.getLogger(ExpReviewEndService.class);

    private Result<String> checkAuthority(ExpModel expModel) {
        // 权限检查
    }

    @Override
    public Result<String> handleExpEditReview(ExpReviewDTO expReviewDTO) {
        // 权限检查
        Result<String> result = checkAuthority(expModel);
        if (result.getCode() != HttpStatus.OK.value()) {
            return result;
        }
        // 业务逻辑处理
        
        // 发送钉钉消息
        this.sendExpEditDingDingMsg(dto);
    }

    @Override
    public void sendExpEditDingDingMsg(ExpReviewDTO expReviewDTO) {
    	// 直接调用了抽象类的公共逻辑
        super.sendExpEditDingDingMsg(expReviewDTO);
    }

    @Override
    protected List<String> getDDUserIdList(ExpReviewDTO expReviewDTO) {
    	// 获取 dd_user_id
    }

    @Override
    protected String getExpEditMarkdownMsgTitle(ExpReviewDTO expReviewDTO) {
        // 定义消息头
    }

    @Override
    protected String getExpEditMarkdownMsgContent(ExpReviewDTO expReviewDTO) {
        // 定义消息体
    }
}

3. 使用

@Service
public class ExpReviewService {
    public Result<String> writeExpReview(ExpModel expModel) {
        ExpReviewDTO expReviewDTO = new ExpReviewDTO();
        expReviewDTO.setExpModel(expModel);
        return ExpReviewServiceManager.WAITING.getReviewService().handleExpEditReview(expReviewDTO);
    }

    public Result<String> updateExpReviewStatus(ExpReviewDTO param) {
        log.info("updateExpReviewStatus expReviewDTO={}", GsonUtil.dump2JsonString(param));
        return ExpReviewServiceManager.of(param.getStatus()).getReviewService().handleExpEditReview(param);
    }
  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值