Java设计模式-策略模式

策略模式(Strategy)

基本介绍

策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以互换。策略模式让算法的变化独立于使用算法的客户。它的核心思想是将算法使用算法的上下文****分离,从而提高代码的灵活性和可维护性。

关键组成部分:

  1. 策略接口(Strategy)
    • 这是一个公共接口,定义了所有支持的算法或策略的方法。
  2. 具体策略(Concrete Strategy)
    • 实现策略接口的具体算法或行为。每个具体策略类实现了接口中定义的方法。
  3. 上下文(Context)
    • 持有对策略接口的引用,客户端通过上下文调用策略的方法。上下文可以在运行时选择具体的策略。

使用场景:

策略模式适用于以下场景:

  • 当你有多个算法可以选择,且这些算法可以在运行时互换。
  • 当你希望将算法的实现细节封装起来,并使其独立于使用算法的客户。
  • 当你希望避免使用大量的条件语句(如if-elseswitch语句)来选择算法。

优点:

  1. 开放-关闭原则:可以通过添加新的策略类来扩展算法,而无需修改现有代码。
  2. 提高可读性:将不同的算法封装到独立的策略类中,减少了条件语句的复杂性。
  3. 灵活性:可以在运行时选择或切换策略。

缺点

  1. 增加类的数量:每个策略都需要一个具体的类,可能导致类的数量增加。
  2. 客户端需要了解策略:客户端需要了解所有的策略类,以便选择合适的策略。

策略模式在许多场景中都非常有用,尤其是在需要根据不同条件选择算法时,可以显著提高代码的可维护性和灵活性。

实例演示

:::tips
假设小明去买了一个冰淇凌,现在他需要付款,请使用策略模式设计一个支付的功能,使得小明能够在不同的支付方式间来回的切换

tips:支付方式(支付宝、微信支付、PayPal、现金支付等等)

:::

  1. 首先设计一种支付策略接口 PaymentStrategy
package com.strategy.paymentStrategy;

/**
 * @program: JavaDesignPatterns
 * @description: 支付策略
 * @author: LyttonYang
 * @create: 2024-10-30 15:00
 */
public interface PaymentStrategy {
    void pay(double amount);
}

  1. 设计具体的支付策略 ConcreteStrategy
/**
 * @program: JavaDesignPatterns
 * @description: 支付宝支付
 * @author: LyttonYang
 * @create: 2024-10-30 15:02
 */
public class AliPayment implements PaymentStrategy{
    @Override
    public void pay(double amount) {
        System.out.println("使用支付宝支付"+amount+"元");
    }
}

/**
 * @program: JavaDesignPatterns
 * @description: PayPal支付
 * @author: LyttonYang
 * @create: 2024-10-30 15:02
 */
public class PayPalPayment implements PaymentStrategy{
    @Override
    public void pay(double amount) {
        System.out.println("使用PayPal支付" + amount + "元");
    }
}

/**
 * @program: JavaDesignPatterns
 * @description: 微信支付
 * @author: LyttonYang
 * @create: 2024-10-30 15:01
 */
public class WeChatPayment implements PaymentStrategy{
    @Override
    public void pay(double amount) {
        System.out.println("使用微信支付支付了"+amount+"元");
    }
}

  1. 让支付者持有这个 支付策略(接口)
package com.strategy.paymentStrategy;

/**
 * @program: JavaDesignPatterns
 * @description: 支付者
 * @author: LyttonYang
 * @create: 2024-10-30 15:04
 */
public class PaymentContext {
    private PaymentStrategy paymentStrategy;

    public PaymentContext(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }
    
    public void checkout(double money){
        if (paymentStrategy != null) {
            paymentStrategy.pay(money);
        } else {
            System.out.println("请选择支付方式");
        }
    }
}

  1. 在使用时可以灵活选择不同的支付策略进行支付
package com.strategy.paymentStrategy;

/**
 * @program: JavaDesignPatterns
 * @description: 算法使用者
 * @author: LyttonYang
 * @create: 2024-10-30 15:03
 */
public class Client {
    public static void main(String[] args) {
        // 使用支付宝支付
        PaymentContext paymentContext = new PaymentContext(new AliPayment());
        paymentContext.checkout(1000);
        
        // 使用微信支付
        paymentContext.setPaymentStrategy(new WeChatPayment());
        paymentContext.checkout(1000);
        
        // 使用银行卡支付
        paymentContext.setPaymentStrategy(new PayPalPayment());
        paymentContext.checkout(1000);
    }
}

项目实战分析

JDK 源码分析-Array 中的策略模式

package com.strategy.ArrayStrategy;

import java.util.Arrays;
import java.util.Comparator;

/**
 * @program: JavaDesignPatterns
 * @description:
 * @author: LyttonYang
 * @create: 2024-10-30 15:27
 */
public class Client {
    public static void main(String[] args) {
        Integer[] array = {11, 22, 13, 44, 25, 96, 57, 28, 19, 10};

        //比较策略接口
        Comparator<Integer> comparator1 = new Comparator<Integer>() {
            @Override
            //具体的比较策略(升序)
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        };
        
        //比较策略接口
        Comparator<Integer> comparator2 = new Comparator<Integer>() {
            @Override
            //具体的比较策略(降序)
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        };

        //使用比较策略接口(升序)
        Arrays.sort(array, comparator1);
        System.out.println(Arrays.toString(array));
        
        //使用比较策略接口(降序)
        Arrays.sort(array, comparator2);
        System.out.println(Arrays.toString(array));
    }
}

Arrays.sort() 方法中就用到了策略模式

:::info
public static <T> void sort(T[] a, Comparator<? super T> c)

:::

其中 Comparator<? super T> c就是一个 比较策略接口

具体使用哪种比较策略完全由用户自己决定, 在上面的代码中我们使用了两种具体的比较策略, 分别是升序和降序的策略:

  • 具体策略 1:
//比较策略接口
Comparator<Integer> comparator1 = new Comparator<Integer>() {
    @Override
    //具体的比较策略(升序)
    public int compare(Integer o1, Integer o2) {
        return o1 - o2;
    }
};
  • 具体策略 2:
//比较策略接口
Comparator<Integer> comparator2 = new Comparator<Integer>() {
    @Override
    //具体的比较策略(降序)
    public int compare(Integer o1, Integer o2) {
        return o2 - o1;
    }
};

还可以自定义其他各种具体的比较策略…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值