策略模式

策略模板模式

1.策略模式的本质

策略模式的本质:分离算法,选择实现。

纵观整个策略模式实现的功能和设计,它的本质还是“分离算法,选择实现”,因为分离并封装了算法,才能够很容易地修改和添加算法;也能很容易地动态切换使用不同的算法,也就是动态选择一个算法来实现需要的功能。

策略模式的本质是将算法的定义、选择和使用分离,使得它们可以独立变化。在策略模式中,将具体的算法封装成独立的策略类,使得这些策略类可以相互替换,而不影响使用它们的客户端代码。

2.何时选用策略模式

建议在以下情况中选用策略模式。

  • 当一个系统需要在多个算法中选择一种合适的算法时,可以考虑使用策略模式。通过将每个算法封装成独立的策略类,可以在运行时动态地选择和切换算法,而不需要修改客户端代码。

  • 当一个类有多个相关的行为,而这些行为在不同的情况下需要不同的实现时,可以考虑使用策略模式。每个行为可以封装成一个具体的策略类,客户端根据需要选择合适的策略类进行调用。

3.优缺点

策略模式有以下优点。

  • 策略模式实现了算法的定义、选择和使用的分离。通过将不同的算法封装成独立的策略类,使得算法可以独立变化,而不影响使用算法的客户端代码。这提高了代码的灵活性和可维护性。

  • 策略模式遵循开闭原则。通过添加新的策略类,可以方便地扩展系统的功能,而不需要修改现有的代码。这使得系统更具可扩展性和可复用性。

  • 策略模式可以减少条件语句的使用。不同的算法被封装在独立的策略类中,客户端只需要选择合适的策略类进行调用,而不需要使用大量的条件语句来判断不同的算法。

  • 策略模式可以方便地切换算法。由于算法被封装在独立的策略类中,可以在运行时动态地选择和切换算法,而不需要修改客户端代码。这使得系统更具灵活性和适应性。

策略模式有以下缺点。

  • 策略模式增加了系统中的类和对象数量。每个具体策略类都需要一个单独的类进行实现,这可能会增加系统的复杂性。

  • 客户端需要了解不同的策略类,并选择合适的策略类进行调用。这增加了客户端的复杂性,特别是当策略类的数量较多时。

  • 策略模式将算法的选择推迟到客户端,可能导致客户端代码变得复杂。客户端需要根据具体的条件选择合适的策略类,这可能涉及到较多的条件判断逻辑。

4.策略模式的结构

在这里插入图片描述

  • 环境类(Context):它持有一个策略类的引用,通过调用策略类的方法来执行具体的算法。环境类提供了一个统一的接口,使得客户端可以方便地使用不同的策略。

  • 抽象策略类(Strategy):它定义了一个公共接口,用于封装具体的算法。不同的具体策略类实现这个接口,提供了不同的算法实现。

  • 具体策略类(Concrete Strategy):它实现了抽象策略类定义的算法接口,具体实现了具体的算法逻辑。

5.实现

支付案例

策略模式在工作中使用,一下就能想到的就是支付
模拟支付宝、微信、银联支付
在这里插入图片描述

1.支付策略及其实现类

/**
 * @description:支付策略接口
 */
public interface PayStrategy {

    /**
     * 支付方法
     * @param orderId 订单id
     * @param amount 金额
     * @return
     */
    boolean pay(String orderId, Long amount);
}

/**
 * @description:微信支付策略
 */
public class WxPay implements PayStrategy{
    @Override
    public boolean pay(String orderId, Long amount) {
        System.out.println("调用微信支付策略-->订单id:"+orderId+" ,金额:"+amount);
        return true;
    }
}

/**
 * @description:支付宝支付策略
 */
public class ZfbPay implements PayStrategy{
    @Override
    public boolean pay(String orderId, Long amount) {
        System.out.println("调用支付宝支付策略-->订单id:"+orderId+" ,金额:"+amount);
        return true;
    }
}

/**
 * @description:银联支付策略
 */
public class YlPay implements PayStrategy{
    @Override
    public boolean pay(String orderId, Long amount) {
        System.out.println("调用银联支付策略-->订单id:"+orderId+" ,金额:"+amount);
        return true;
    }
}

2.支付上下文类

/**
 * @description:支付上下文类
 */
public class PayContext {

    /**
     * 订单id
     */
    private String orderId;
    /**
     * 金额
     */
    private Long amount;

    private PayStrategy payStrategy;

    public PayContext(String orderId, Long amount, PayStrategy payStrategy) {
        this.orderId = orderId;
        this.amount = amount;
        this.payStrategy = payStrategy;
    }

    public void payContext(){
        //调用具体策略的支付
        this.payStrategy.pay(orderId,amount);
    }
}

3.测试类

public class Client {

    public static void main(String[] args) {
        //微信支付
        new PayContext("10001",100L,new WxPay()).payContext();
        //支付宝支付
        new PayContext("10002",200L,new ZfbPay()).payContext();
        //银联支付
        new PayContext("10003",300L,new YlPay()).payContext();
    }
}

4.结果
在这里插入图片描述

看起来好像没有上下文什么事情,但是如果没有上下文,那么就需要客户端来直接与具体的策略交互,尤其是当需要提供一些公共功能,或者是相关状态存储的时候,会大大增加客户端使用的难度。因此,引入上下文还是很必要的,有了上下文,这些工作就由上下文来完成了,客户端只需要与上下文交互就可以了,这样会让整个设计模式更独立、更有整体性,也让客户端更简单。

支付案例参数不一致问题

实际使用各种支付时,各自的参数必然不一样,但是策略又是接口定义好的,那应该怎么办呢,这时介于客户端和策略方法中间的上下文类就发挥作用了,可以在这里面搞点小动作,把微信和支付宝用到的参数声明在这里,然后把自己传给策略类,不同的策略类需要什么参数就取什么参数

1.策略类及其实现类

/**
 * @description:支付策略接口
 */
public interface PayStrategy {

    /**
     * 支付方法
     * @return
     */
    boolean pay(PayContext payContext);
}

/**
 * @description:微信支付策略
 */
public class WxPay implements PayStrategy{
    @Override
    public boolean pay(PayContext payContext) {
        System.out.println("微信支付参数:"+payContext.getWxAppserect());
        System.out.println("调用微信支付策略-->订单id:"+payContext.getOrderId()+" ,金额:"+payContext.getAmount());
        return true;
    }
}

/**
 * @description:支付宝支付策略
 */
public class ZfbPay implements PayStrategy{
    @Override
    public boolean pay(PayContext payContext) {
        System.out.println("支付宝支付参数:"+payContext.getZfbId());
        System.out.println("调用支付宝支付策略-->订单id:"+payContext.getOrderId()+" ,金额:"+payContext.getAmount());
        return true;
    }
}

/**
 * @description:银联支付策略
 */
public class YlPay implements PayStrategy{
    @Override
    public boolean pay(PayContext payContext) {
        System.out.println("银联支付没有参数");
        System.out.println("调用银联支付策略-->订单id:"+payContext.getOrderId()+" ,金额:"+payContext.getAmount());
        return true;
    }
}

2.支付上下文类

/**
 * @description:支付上下文类
 */
@Getter
public class PayContext {

    /**
     * 订单id
     */
    private String orderId;
    /**
     * 金额
     */
    private Long amount;

    /**
     * 微信支付需要的参数
     */
    private String wxAppserect;
    /**
     * 支付宝支付需要的参数
     */
    private String zfbId;

    private PayStrategy payStrategy;

    public PayContext(String orderId, Long amount, String wxAppserect, String zfbId, PayStrategy payStrategy) {
        this.orderId = orderId;
        this.amount = amount;
        this.wxAppserect = wxAppserect;
        this.zfbId = zfbId;
        this.payStrategy = payStrategy;
    }

    public void payContext(){
        //调用具体策略的支付
        this.payStrategy.pay(this);
    }
}

3.测试类

public class Client {

    public static void main(String[] args) {
        //微信支付
        PayContext wxPay = new PayContext("10001", 100L, "wx123", "", new WxPay());
        wxPay.payContext();
        //支付宝支付
        PayContext zfbPay = new PayContext("10001", 100L, "", "zfb123", new ZfbPay());
        zfbPay.payContext();
        //银联支付
        PayContext ylPay = new PayContext("10001", 100L, "", "", new YlPay());
        ylPay.payContext();
    }
}

4.结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值