Java设计模式之策略模式

一、策略模式的定义:

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

策略模式的结构图

在这里插入图片描述

二、策略模式出现背景举例:

当我们给人支付工资的时候可以使用不同的支付方式:

1、使用人民币现金
2、使用美元现金
3、使用信用卡
4、使用微信支付
5、使用支付宝
等等,有很多种支付方式,那到底最终要选择哪一种支付方式呢,其实是不确定的,针对不同的人,需要使用不同的支付方式【比如在国外可能就需要使用到美元支付等】;另外在不同的时间、地点也可能使用不同的支付方式【比如支付宝没钱了,就可能选择微信支付等】。

如果要写一个总的支付系统类,那么我们是否通通使用if elseif…来完成呢。显然是很不好的:

1、首先该类中包含了所有的支付类型的算法,使得这个类会非常庞大。
2、违背了“开–闭原则”,当不同的支付手段需要调整的时候,总会去修改该类,非常容易产生问题。

三、策略模式的功能:

在如上的举例中,策略模式应运而生,策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性。

四、策略模式代码示例:

1、定义任务的策略接口

/**
 * 策略接口
 */
public interface TaskStrategy {
    /**
     * 匹配
     *
     * @param obj DTO
     * @return
     */
    public <T> ResponseUtils match(T obj);
    /**
     * 执行器
     *
     * @param obj 执行器dto
     * @return
     */
    public  <T>ResponseUtils execute(T obj);
}

2、抽象类策略

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * 抽象类策略
 */
public abstract class AbstractTaskStrategy implements TaskStrategy {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
}

3、定义具体的策略实现类

import java.util.HashMap;
import java.util.Map;

/**
 * 策略接口实现类:执行具体业务实现,同一个业务类型,只需要重写具体业务实现类
 * @Order 指定bean的执行顺序
 */
@Order(1)
@Component
public class TaskStatusStrategy extends AbstractTaskStrategy {

    //执行业务匹配逻辑
    @Override
    public <T> ResponseUtils match(T obj) {
        System.out.println("TaskStatusStrategy执行顺序");
        //这里写自己的匹配逻辑,true继续执行,false就会终止执行,匹配逻辑可以设计成表
        if (obj == null) {
            return ResponseUtils.fail("执行器不匹配");
        }
        Map map = new HashMap();
        map.put("张三", 1);
        return ResponseUtils.success(map);
    }
    //执行业务具体逻辑
    @Override
    public <T> ResponseUtils execute(T obj) {
        //执行具体的业务逻辑
        return null;
    }
}
import com.example.strategy.AbstractTaskStrategy;
import com.example.utils.ResponseUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(0)
@Component
public class UpdateTaskStrategy extends AbstractTaskStrategy {
    @Override
    public <T> ResponseUtils match(T obj) {
        System.out.println("UpdateTaskStrategy执行顺序");
        return ResponseUtils.success();
    }
    @Override
    public <T> ResponseUtils execute(T obj) {
        return ResponseUtils.success();
    }
}

4、枚举:

public interface AbstractBaseExceptionEnum {
    String getCode();
    String getMessage();
}
import java.util.HashMap;
import java.util.Map;

public enum CoreExceptionEnum implements AbstractBaseExceptionEnum {
    SUCCESS("200", "成功"),
    FAIL("500", "失败"),
    ;
    private String msg;
    private String code;
    CoreExceptionEnum(String msg, String code) {
        this.msg = msg;
        this.code = code;
    }
    public static Map<String, CoreExceptionEnum> allMap = new HashMap<>(16);
    static {
        for (CoreExceptionEnum coEnum : CoreExceptionEnum.values()) {
            allMap.put(coEnum.code, coEnum);
        }
    }
    @Override
    public String getCode() {
        return code;
    }
    @Override
    public String getMessage() {
        return msg;
    }
}

5、Rest工具类:

import com.example.enums.CoreExceptionEnum;

public class ResponseUtils<T> {

    private Boolean isSucceed;
    private String msg;
    private String code;
    private CoreExceptionEnum coreExceptionEnum;
    private T data;

    @Deprecated
    public ResponseUtils() {
    }
    public Boolean getSucceed() {
        return isSucceed;
    }
    public void setSucceed(Boolean succeed) {
        isSucceed = succeed;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public CoreExceptionEnum getCoreExceptionEnum() {
        return coreExceptionEnum;
    }
    public void setCoreExceptionEnum(CoreExceptionEnum coreExceptionEnum) {
        this.coreExceptionEnum = coreExceptionEnum;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
    public boolean isSucceed(){
        return isSucceed;
    }

    /**
     * 成功时-返回data
     *
     * @param <T>
     * @return
     */
    public static ResponseUtils success() {
        ResponseUtils responseUtils = new ResponseUtils();
        responseUtils.isSucceed = true;
        responseUtils.msg = "";
        responseUtils.code = CoreExceptionEnum.SUCCESS.getCode();
        return responseUtils;
    }

    /**
     * 成功-返回message
     *
     * @param <T>
     * @return
     */
    public static <T> ResponseUtils<T> success(String msg) {
        ResponseUtils responseUtils = new ResponseUtils();
        responseUtils.isSucceed = true;
        responseUtils.msg = msg;
        return responseUtils;
    }

    /**
     * 成功-返回message和code
     *
     * @param <T>
     * @return
     */
    public static <T> ResponseUtils<T> success(String msg, String code) {
        ResponseUtils responseUtils = new ResponseUtils();
        responseUtils.isSucceed = true;
        responseUtils.msg = msg;
        responseUtils.code = code;
        return responseUtils;
    }
    /**
     * 成功时-返回data
     *
     * @param <T>
     * @return
     */
    public static <T> ResponseUtils<T> success(T data) {
        ResponseUtils responseUtils = new ResponseUtils();
        responseUtils.isSucceed = true;
        responseUtils.msg = "";
        responseUtils.code = CoreExceptionEnum.SUCCESS.getCode();
        responseUtils.data = data;
        return responseUtils;
    }

    /**
     * 失败
     *
     * @param <T>
     * @return
     */
    public static <T> ResponseUtils<T> fail(String msg) {
        ResponseUtils responseUtils = new ResponseUtils();
        responseUtils.isSucceed = false;
        responseUtils.msg = msg;
        return responseUtils;
    }

    /**
     * 失败-code
     *
     * @param <T>
     * @return
     */
    public static <T> ResponseUtils<T> fail(CoreExceptionEnum code, String msg) {
        ResponseUtils responseUtils = new ResponseUtils();
        responseUtils.isSucceed = false;
        responseUtils.code = code.getCode();
        responseUtils.msg = msg;
        return responseUtils;
    }
}

6、策略类调用:

import com.example.strategy.TaskStrategy;
import com.example.utils.ResponseUtils;
import com.example.vo.BaseEntity;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
import java.util.Map;

@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
class DesignModeApplicationTests {
    @Autowired
    private List<TaskStrategy> taskStrategy;
    @Test
    public void testStrategy() {
        BaseEntity obj = new BaseEntity();
        obj.setCreateBy("sss");
        for (TaskStrategy executors : taskStrategy) {
            String simpleName = executors.getClass().getSimpleName();

            ResponseUtils match = executors.match(obj);
            Map map = (Map) match.getData();
            System.out.println("执行器: " + simpleName + ", 是否匹配: " + match.isSucceed() + ",不匹配信息: " + match.getMsg());
            //match==teue执行
            if (match.isSucceed()) {
                executors.execute(obj);
            }
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
策略模式(Strategy Pattern)是Java设计模式中的一种行为型模式,它定义了一系列的算法,并将每个算法封装在独立的类中,使得它们可以互相替换。这样可以使得算法的变化独立于使用它们的客户端。 在策略模式中,有三个主要角色: 1. 环境类(Context):持有一个策略类的引用,用于调用具体的策略。 2. 抽象策略类(Strategy):定义了一个公共接口或抽象类,用于具体策略类的统一调用。 3. 具体策略类(Concrete Strategy):实现了抽象策略类定义的接口或抽象类,提供具体的算法实现。 使用策略模式可以实现算法的动态切换,增加新的算法也不会影响到已有的代码。例如,假设我们需要实现一个排序算法,可以定义一个抽象策略类 SortStrategy,然后具体的排序算法(如快速排序、归并排序等)分别实现 SortStrategy,并在环境类中持有 SortStrategy 的引用。这样,通过更换不同的 SortStrategy 对象,就可以在运行时选择不同的排序算法。 策略模式能够有效地解耦策略的定义和使用,提高代码的灵活性和可维护性。同时,它也符合面向对象设计原则中的"开闭原则"(对扩展开放,对修改关闭)和"单一职责原则"(一个类应该只有一个引起变化的原因)。 希望这个简要的介绍能够帮助到你对策略模式的理解。如果还有其他问题,可以继续提问!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值