设计模式之策略模式

经典案例:如果我们调用支付方式的支付接口。

/**
 * @author maoyouhua
 * @time 2024/3/18
 * @jdkversion jdk21
 *
 *      调用支付方式
 *
 *      面临问题:
 *          假如我们即将接入新的支付方式,必须修改代码
 *          假如后面支付方式接口发生了改变或者替换,也必须修改代码
 *
 *      这段代码有两个主要问题:
 *          一是不符合开闭原则,可以预见
 *          二是不符合迪米特法则,发奖逻辑和各个下游接口高度耦合,这导致接口的改变将直接影响到代码的组织,使得代码的可维护性降低
 */
public interface PayService {
    void payment(String payType, String params);
}

@Service
class PayServiceImpl implements PayService {

    @Override
    public void payment(String payType, String params) {
        if ("Alipay".equals(payType)) {
            System.out.println("调用支付宝支付方式接口");
        } else if ("WeChatPay".equals(payType)) {
            System.out.println("调用微信支付方式接口");
        }  else {
            throw new IllegalArgumentException("payType error!");
        }
    }
}

 引申出的问题:

        假如我们即将接入新的支付方式,必须修改代码。

        假如后面支付方式接口发生了改变或者替换,也必须修改代码。

其实不难看出这段代码的问题是:

         一是不符合开闭原则,可以预见 。

        二是不符合迪米特法则,逻辑和各个支付接口高度耦合,这导致接口的改变将直接影响到代码的组织,使得代码的可维护性降低。

那么可以使用策略模式解决以上的问题,参考美团:设计模式二三事

策略模式定义了一系列的算法,并将每一个算法封装起来,使它们可以相互替换。策略模式通常包含以下角色:
抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
环境(Context)类:持有一个策略类的引用,最终给客户端调用。
/**
 * @author maoyouhua
 * @time 2024/3/18
 * @jdkversion jdk21
 *
 *      抽象策略
 */
public interface Pay {
    void pay(String type);

}
public abstract class AbstractPay implements Pay {
    // 类注册方法
    public void register() {
        PayContext.registerStrategy(getClass().getSimpleName(), this);
    }

}
/**
 * @author maoyouhua
 * @time 2024/3/18
 * @jdkversion jdk21
 *
 *      策略环境
 */
@Component
public class PayContext {

    private static final Map<String, Pay> registerMap = new HashMap<>();

    // 注册策略
    public static void registerStrategy(String payType, Pay strategy) {
        registerMap.putIfAbsent(payType, strategy);
    }

    // 获取策略
    public static Pay getStrategy(String payType) {
        return registerMap.get(payType);
    }

}
/**
 * @author maoyouhua
 * @time 2024/3/18
 * @jdkversion jdk21
 *      具体策略
 *      支付宝支付
 */
@Component
public class Alipay extends AbstractPay {
    public Alipay() {
        super.register();
    }
    private static final String payType = "支付宝支付";
    @Override
    public void pay(String parm) {
        System.out.println(parm);
        System.out.println("调用" + payType  + "方式");
    }
}
@Component
public class PostalPay extends AbstractPay {
    public PostalPay() {
        super.register();
    }
    private static final String payType = "邮政支付";
    @Override
    public void pay(String parm) {
        System.out.println(parm);
        System.out.println("调用" + payType  + "方式");
    }
}
@Component
public class WeChatPay extends AbstractPay {
    public WeChatPay() {
        super.register();
    }
    private static final String payType = "微信支付";
    @Override
    public void pay(String parm) {
        System.out.println(parm);
        System.out.println("调用" + payType  + "方式");
    }
}
/**
 * @author maoyouhua
 * @time 2024/3/18
 * @jdkversion jdk21
 */
public interface PayServiceByrebuild {
        void payment(String payType, String params);
}

@Service
public class PayServiceImplByrebuild implements PayServiceByrebuild {
    @Override
    public void payment(String payType, String params) {
        Pay pay = PayContext.getStrategy(payType);
        pay.pay(params);
    }
}
/**
 * @author maoyouhua
 * @time 2024/3/18
 * @jdkversion jdk21
 */
@RestController
@RequestMapping("/payment")
public class PayController {

    @Autowired
    private PayService payService;

    @Autowired
    private PayServiceByrebuild payServiceByrebuild;
    @RequestMapping("/test")
    public String testPay(){
        return "测试调用支付接口";
    }

    @RequestMapping("/pay")
    public String testPay(String payType, String parm){
        payService.payment(payType,parm);
        return "调用普通支付接口";
    }
    @RequestMapping("/paybystrategy")
    public String testPayByRebulid(String payType, String parm){
        payServiceByrebuild.payment(payType,parm);
        return "调用策略模式支付接口";
    }


}

相关推荐

  1. 设计模式策略模式

    2024-03-19 11:10:01       32 阅读
  2. 设计模式策略模式

    2024-03-19 11:10:01       33 阅读
  3. 设计模式策略模式

    2024-03-19 11:10:01       20 阅读
  4. 设计模式策略模式

    2024-03-19 11:10:01       15 阅读
  5. 设计模式策略模式

    2024-03-19 11:10:01       12 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-19 11:10:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-19 11:10:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-19 11:10:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-19 11:10:01       20 阅读

热门阅读

  1. 华为设备配置命令大全

    2024-03-19 11:10:01       21 阅读
  2. node后端helmet中间件

    2024-03-19 11:10:01       22 阅读
  3. win git filter-repo教程

    2024-03-19 11:10:01       20 阅读
  4. Vim替换时区分大小写

    2024-03-19 11:10:01       19 阅读
  5. word 及PPT 中修改公式字体

    2024-03-19 11:10:01       19 阅读
  6. Spring MVC中redirect重定向几种方式(重构)

    2024-03-19 11:10:01       20 阅读
  7. 【Git】012-Git 仓库初始化

    2024-03-19 11:10:01       14 阅读