设计模式之策略模式:让你的代码灵活应对不同的算法 | 京东云技术团队

京东云开发者
• 阅读 407

作为一个程序员,我们经常会面临着在不同的情况下选择不同的算法来解决问题的需求。这种情况下,策略模式是一个非常有用的设计模式。在本文中,我将向你介绍策略模式的概念、结构以及如何应用这个模式来使你的代码更灵活。

1.什么是策略模式?

策略模式是一种行为型设计模式,它允许在运行时根据不同的情况选择算法的行为。这意味着我们可以将不同的算法封装成不同的策略类,并通过一个统一的接口来调用这些策略。

2.策略模式的结构

策略模式包括以下几个角色:

上下文(Context):持有一个策略对象的引用,并在需要时调用策略对象的方法。上下文可以根据具体情况选择不同的策略。

策略(Strategy):定义了一个公共接口,用于封装不同的算法。这个接口通常只有一个方法,即执行算法的方法。

具体策略(ConcreteStrategy):实现了策略接口,提供具体的算法实现。每个具体策略类都代表了一种特定的算法。

策略模式的关键在于上下文持有一个策略对象的引用,并且通过调用策略对象的方法来执行具体的算法。这种方式使得上下文变得非常灵活,可以根据不同的需求在运行时切换算法。

3.策略模式的应用场景

策略模式适用于以下情况:

  • 当需要在运行时动态地选择算法实现时,可以使用策略模式。
  • 当一个类有多个行为变种,并且这些行为可以灵活地切换时,策略模式可以提供一种优雅的解决方案。

例子(1)例如,在一个电商网站中,我们可能需要根据不同的支付方式来支付购物车的商品。可以是信用卡,当然也可以是京东支付、支付宝支付等等,这时,我们可以将每种支付行为封装成一个具体策略类,然后通过上下文选择合适的支付方式进行支付。

也许你可能见过类似的代码

if(payType==CreditCardType){
     System.out.println("使用信用卡支付:" + amount + " 元"); 
     // 实现具体的信用卡支付逻辑
}else if(payType==jdPayType){
     System.out.println("使用京东支付:" + amount + " 元"); 
     // 实现具体的京东支付逻辑
}else if(payType==alipayType){
    System.out.println("使用支付宝支付:" + amount + " 元"); 
    // 实现具体的支付宝支付逻辑 
}else{
    System.out.println("没实现,白嫖叭"); 
}

好了,这时候微信一看,为啥没把微信支付加上,赶紧支持。研发小哥哥加班修改逻辑如下:

if(payType==creditCardType){
     System.out.println("使用信用卡支付:" + amount + " 元"); 
     // 实现具体的信用卡支付逻辑
}else if(payType==jdPayType){
     System.out.println("使用京东支付:" + amount + " 元"); 
     // 实现具体的京东支付逻辑
}else if(payType==alipayType){
    System.out.println("使用支付宝支付:" + amount + " 元"); 
    // 实现具体的支付宝支付逻辑 
}else if(payType==wxPayType){ 
    System.out.println("使用微信支付:" + amount + " 元"); 
    // 实现具体的微信支付逻辑 
}else{
    System.out.println("没实现,白嫖叭"); 
}

代码修改后,看着挺清晰明了,但是有一个问题,如果之后还有其他如抖音支付、乱七八糟支付的话我们就要一直修改这个类,一直添加 ...else if...

很明显违背了面向对象设计的六大原则之二:单一职责、开闭原则(对扩展开放、对修改关闭),六个违背俩,这活没法干了!

下面演示了如何使用策略模式来实现不同的支付方式:

// 定义一个支付的策略接口
public interface PaymentStrategy {
    //这只是个测试场景,真实场景下应该没人用double类型叭
    void pay(double amount);
}

// 具体策略实现
// 信用卡支付
public class CreditCardPaymentStrategy implements PaymentStrategy {
    public void pay(double amount) {
        System.out.println("使用信用卡支付:" + amount + " 元");
        // 实现具体的信用卡支付逻辑
    }
}
// 京东支付
public class JdPaymentStrategy implements PaymentStrategy {
    public void pay(double amount) {
       System.out.println("使用京东支付:" + amount + " 元"); 
       // 实现具体的京东支付逻辑
    }
}
//省略...
// 支付宝支付
// 微信支付


// 上下文
public class ShoppingCart {
    private PaymentStrategy paymentStrategy;

    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    public void checkout(double amount) {
        // 调用策略对象的支付方法
        paymentStrategy.pay(amount);
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();

        // 设置使用信用卡支付策略
        cart.setPaymentStrategy(new CreditCardPaymentStrategy());
        cart.checkout(1000.00);

        // 设置使用jd支付策略
        cart.setPaymentStrategy(new JdPaymentStrategy());
        cart.checkout(2000.00);
        //如果还想用其他支付 就继续写啊

    }
}

在上面的例子中,PaymentStrategy是策略接口,CreditCardPaymentStrategy和PayPalPaymentStrategy是具体的策略实现。ShoppingCart是上下文,通过setPaymentStrategy方法来设置不同的支付策略,并通过checkout方法调用具体策略的支付方法。看看,是不是可以通过扩展来增加支付方式。每个子类只实现具体的某种支付的策略。

例子(2)实现一个简单的计算器(整数),简单想一想也许涉及以下几种计算方式:加减乘除,也许有人会这样实现,但是我想一定不是你,聪明的你应该已经学会了策略模式在这种场景下的应用

试想 如果我想增加取余操作呢?


int num1 = 10;
int num2 = 5;
String operator = "+";

if (operator.equals("+")) {
    int result = num1 + num2;
    System.out.println("加法结果:" + result);
} else if (operator.equals("-")) {
     int result = num1 - num2;
      System.out.println("减法结果:" + result);
} else if (operator.equals("*")) {
     int result = num1 * num2;
     System.out.println("乘法结果:" + result);
} else if (operator.equals("/")) {
     if (num2 != 0) {
          int result = num1 / num2;
          System.out.println("除法结果:" + result);
     } else {
          System.out.println("除数不能为零");
     }
 } else {
     System.out.println("无效的运算符");
 }


4.总结

策略模式是一种灵活、可扩展的设计模式,它通过将算法封装成策略类来实现不同的行为变种。使用策略模式可以提高代码的可维护性和复用性,同时也符合面向对象设计的原则。

希望本文的介绍对你理解策略模式有所帮助,也希望你能在实际项目中运用到这个强大的设计模式!

作者:京东零售 闫先东

来源:京东云开发者社区 转载请注明来源

点赞
收藏
评论区
推荐文章
责任链和策略设计模式-基于Java编程语言
责任链和策略设计模式这两种设计模式非常实用,下面简单介绍一下我对这两种设计模式的理解和它们在Spring框架源码中的应用。
徐小夕 徐小夕
4年前
《前端实战总结》之使用解释器模式实现获取元素Xpath路径的算法
前端领域里基于javascript的设计模式和算法有很多,在很多复杂应用中也扮演着很重要的角色,接下来就介绍一下javascript设计模式中的解释器模式,并用它来实现一个获取元素Xpath路径的算法。上期回顾《前端实战总结》之迭代器模式的N1种应用场景(https://juejin.im/post/6844904008616771591)
系统认知篇:防腐层、门面模式及适配模式的本质 | 京东云技术团队
门面模式和适配器模式是代码级的设计模式,而防腐层本质是一种防御型策略,在更高的层级对系统进行解耦
Dubbo架构设计与源码解析(三)责任链模式
责任链模式是设计模式中简单且常见的设计模式,可能我们日常中也会经常应用责任链模式,dubbo中的责任链模式将灵活性发挥的很充分。
Easter79 Easter79
3年前
spring中策略模式使用
策略模式工作中经常使用到策略模式工厂模式,实现一个接口多种实现的灵活调用与后续代码的扩展性。在spring中使用策略模式更为简单,所有的bean均为spring容器管理,只需获取该接口的所有实现类即可。下面以事件处理功能为例,接收到事件之后,根据事件类型调用不同的实现接口去处理。如需新增事件,只需扩展实现类即可,无需改动之前的代码。这样即
Wesley13 Wesley13
3年前
Java设计模式
一、策略模式(让算法与对象独立)    策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。!(http://static.oschina.net/uploads/space/2016/1108/180244_oYm8_1789589.png)二、观察者模式(让你的对象知悉现状) 
Wesley13 Wesley13
3年前
00_设计模式之语言选择
设计模式之语言选择设计模式简介背景设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。设计模式(Designpattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的
Wesley13 Wesley13
3年前
Java 设计模式系列(十二)策略模式(Strategy)
Java设计模式系列(十二)策略模式(Strategy)策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。一、策略模式的结构策略模式是对算
Wesley13 Wesley13
3年前
如何利用策略模式避免冗长的 if
策略模式。在实际的项目开发中,这个模式也比较常用。最常见的应用场景是,利用它来避免冗长的ifelse或switch分支判断。不过,它的作用还不止如此。它也可以像模板模式那样,提供框架的扩展点等等。对于策略模式。本篇我们讲解策略模式的原理和实现,以及如何用它来避免分支判断逻辑。后续我会通过一个具体的例子,来详细讲解策略模式的应用场景以及真正的设计意图
前端常用设计模式初探 | 京东云技术团队
设计模式一直是程序员谈论的“高端”话题之一,总有一种敬而远之的心态。在了解后才知道在将函数作为一等对象的语言中,有许多需要利用对象多态性的设计模式,比如单例模式、策略模式等,这些模式的结构与传统面向对象语言的结构大相径庭,实际上已经融入到了语言之中,我们可