Java中策略设计模式的实现及应用场景

 更新时间:2023年04月25日 08:33:48   作者:.番茄炒蛋  
策略设计模式是Java中一种常用的设计模式,它通过定义一系列算法并将其封装成独立的策略类,从而使得算法可以在不影响客户端的情况下随时切换。策略设计模式主要应用于系统中存在多种相似的算法、需要灵活调整算法逻辑或者需要扩展新的算法等场景

介绍

Java策略模式(Strategy Pattern)是一种行为设计模式,它允许再运行时动态选择算法的行为.策略模式通过将算法封装在可互换的策略对象中,使得客户端代码能够轻松地切换算法,而无需修改原始代码.在策略模式中,每个算法都被实现为一个单独的策略类,这些策略类都实现了相同的接口,从而允许它们在运行时互相替换.

在Java中,可以使用接口或抽象类来定义策略接口.然后对于每个算法,都可以创建一个具体的实现类来实现这个接口.客户端代码可以通过将不同的策略对象传递给上下文对象来选择不同的算法.

Java策略模式通常包括以下三种角色:

  • Context(上下文):是策略模式中的核心类,用来管理具体策略实现类的创建,配置和执行,以及在运行时动态地选择具体的策略实现类.
  • Strategy(策略):是一个接口或抽象类,定义了策略实现类的通用方法和属性,具体策略实现类必须实现这些方法和属性.
  • ConcreteStrategy(具体策略):是策略接口的实现类,根据具体业务需求实现了策略接口定义的方法和属性.可以又多个具体策略实现类,Context类在运行时根据需要动态地选择具体的策略实现类.

实现

支付策略接口(Strategy)

public interface PaymentStrategy {
    /**
     * 支付
     *
     * @param amount
     */
    void pay(double amount);
}

微信支付和支付宝支付(ConcreteStrategy)

public class WechatPayment implements PaymentStrategy {
    private String username;
    private String password;
    public WechatPayment(String username, String password) {
        this.username = username;
        this.password = password;
    }
    /**
     * 支付
     *
     * @param amount
     */
    @Override
    public void pay(double amount) {
        System.out.println("微信支付:" + amount + "元");
    }
}
public class AliPayment implements PaymentStrategy{
    private String username;
    private String password;
    public AliPayment(String username, String password) {
        this.username = username;
        this.password = password;
    }
    /**
     * 支付
     *
     * @param amount
     */
    @Override
    public void pay(double amount) {
        System.out.println("支付宝支付:" + amount + "元");
    }
}

购物车类(Context)

public class ShoppingCart {
    private List<Item> itemList;
    private PaymentStrategy paymentStrategy;
    public ShoppingCart() {
        itemList = new ArrayList<>();
    }
    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }
    public void addItem(Item item){
        itemList.add(item);
    }
    public void removeItem(Item item){
        itemList.remove(item);
    }
    public double calculateTotal(){
        return itemList.stream().mapToDouble(Item::getPrice).sum();
    }
    public void pay(){
        paymentStrategy.pay(calculateTotal());
    }
}

商品类

@Data
public class Item {
    private String name;
    private double price;
    public Item(String name, double price) {
        this.name = name;
        this.price = price;
    }
}

测试

public class Demo {
    public static void main(String[] args) {
        ShoppingCart shoppingCart = new ShoppingCart();
        Item item1 = new Item("item1",10);
        Item item2 = new Item("item2",10);
        shoppingCart.addItem(item1);
        shoppingCart.addItem(item2);
        shoppingCart.setPaymentStrategy(new AliPayment("aliPayUsername","aliPayPassword"));
        shoppingCart.pay();
        shoppingCart.setPaymentStrategy(new WechatPayment("wechatUsername","wechatPassword"));
        shoppingCart.pay();
    }
}

上面代码演示了一个简单的策略模式实现.我们定义了一个PaymentStrategy接口,它表示所有支付方式的共同操作.我们还定义了两个实现该接口的具体类AliPayment和WechatPayment,它们分别表示使用支付宝和微信支付的操作.我们还定义了一个ShoppingCart类,该类使用PaymentStrategy接口来表示支付方式,并根据需要切换实际的支付方式.

在我们的Demo类中,我们创建了一个ShoppingCart对象,并添加了两个Item对象,我们然后选择使用AliPayment进行支付,并调用pay()方法.我们接下来又选择使用WechatPayment进行支付,并再次调用pay()方法.

这样,我们就可以轻松地在不同的支付方式之间进行切换,并根据需要添加新的支付方式.

总结

优点

  • 容易扩展和维护:通过定义一个抽象的策略接口,可以方便地增加新的策略实现类,而不需要修改现有代码
  • 易于替换算法:在运行时可以动态地切换算法实现,无需修改客户端代码
  • 降低了耦合度:客户端只需要知道策略接口即可,不需要知道具体的策略实现类
  • 提高了复用性:不同的策略实现类可以在多个场景下复用

缺点

  • 增加了类的数量:为每个具体策略都定义了一个实现类,可能会增加类的数量.
  • 客户端必须知道策略接口:客户端需要知道具体的策略接口,才能正确使用策略实现类.
  • 运行时开销较大:在运行时,需要根据不同的策略实现类进行判断和选择,会带来一定的开销

应用场景

  • 有多个相似的类,只有行为有差异的情况下,可以考虑使用策略模式.
  • 需要在运行时动态切换算法的情况下,可以使用策略模式.
  • 一个系统需要在不同时间应用不同的业务规则情况下,可以使用策略模式
  • 在一个系统中,有许多类需要根据某种规则进行排序,查找等操作的情况下,可以使用策略模式.

到此这篇关于Java中策略设计模式的实现及应用场景的文章就介绍到这了,更多相关Java策略设计模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈Java中FastJson的使用

    浅谈Java中FastJson的使用

    今天给大家带来的是关于Java的相关知识,文章围绕着FastJson的使用展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • 使用IntelliJ IDEA调式Stream流的方法步骤

    使用IntelliJ IDEA调式Stream流的方法步骤

    本文主要介绍了使用IntelliJ IDEA调式Stream流的方法步骤,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • 使用mybatis的@Interceptor实现拦截sql的方法详解

    使用mybatis的@Interceptor实现拦截sql的方法详解

    拦截器是一种基于 AOP(面向切面编程)的技术,它可以在目标对象的方法执行前后插入自定义的逻辑,本文给大家介绍了使用mybatis的@Interceptor实现拦截sql的方法,需要的朋友可以参考下
    2024-03-03
  • 关于 Java 的数据结构链表

    关于 Java 的数据结构链表

    这篇文章主要介绍了关于 Java 的数据结构链表的相关资料,需要的朋友可以参考下面文章内容
    2021-09-09
  • 使用注解+RequestBodyAdvice实现http请求内容加解密方式

    使用注解+RequestBodyAdvice实现http请求内容加解密方式

    这篇文章主要介绍了使用注解+RequestBodyAdvice实现http请求内容加解密方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • IDEA内存调试插件(好用)

    IDEA内存调试插件(好用)

    本文给大家分享IDEA中一个很有用的内存调试插件,非常不错,具有参考借鉴价值,需要的朋友参考下
    2018-02-02
  • SpringBoot2.x配置多数据源方式

    SpringBoot2.x配置多数据源方式

    这篇文章主要介绍了SpringBoot2.x配置多数据源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • 解决springboot MultipartFile文件上传遇到的问题

    解决springboot MultipartFile文件上传遇到的问题

    本文给大家带来了解决springboot MultipartFile文件上传遇到的问题,解决方法超简单,感兴趣的朋友参考下本文
    2018-08-08
  • Java数据结构与算法之单链表深入理解

    Java数据结构与算法之单链表深入理解

    这篇文章主要介绍了Java数据结构与算法之单链表深入理解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • springBoot+webMagic实现网站爬虫的实例代码

    springBoot+webMagic实现网站爬虫的实例代码

    这篇文章主要介绍了springBoot+webMagic实现网站爬虫的实例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05

最新评论