首页 > 编程语言 >设计模式之策略模式:让你的代码灵活应对不同的算法

设计模式之策略模式:让你的代码灵活应对不同的算法

时间:2023-10-17 10:44:42浏览次数:27  
标签:策略 amount 代码 System 算法 支付 println 设计模式 out

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

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.总结

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

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

作者:京东零售 闫先东

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

标签:策略,amount,代码,System,算法,支付,println,设计模式,out
From: https://www.cnblogs.com/jingdongkeji/p/17769155.html

相关文章

  • 完美兼容IE,chrome,ff的设为首页、加入收藏及保存到桌面js代码
    今天给大家分享一段设为首页、收藏本站及保存到桌面的js代码,非常实用。scripttype="text/javascript"//设为首页functionSetHome(obj,url){try{obj.style.behavior=’url(#default#homepage)’;obj.setHomePage(url);}catch(e){if(window.netscape){try{netscape.security.Priv......
  • java serverlets使用数据源连接oracle数据库,并执行查询操作代码
    packagechap03;importjava.io.IOException;importjava.io.PrintWriter;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.PreparedStatement;importjava.sql.Statement;importjava.u......
  • 算法--hash取模
    一、简介    hash取模算法常用于分布式缓存集群系统。一般3种:普通hash取模,一致性hash,hash槽。    场景:用户注册系统,用户数量会不断的增大,需要几个服务器共同存储。二、普通hash取模    1、创建4个服务器【canister】,然后对注册的用户idhash取模。例如......
  • IDEA代码突然爆红
    1,检查setting配置,2,检查projectStructure配置 3,如果以上配置没问题,就不是配置的问题。尝试重新导入代码,或者重新加载项目:项目名右击-Maven-Reloadproject或者项目名右击-Maven-reimport  ......
  • VSCode 小技巧 配置代码模版 vscode snippets
    第一步mac输入shift+command+p(windows输入ctrl+shift+p),输入snippets,点击如下图选项。第二步,选中新建全局代码片段文件。第三步,输入一个全局配置文件名,例如snippet.config第四步,进行配置{//Placeyour全局snippetshere.Eachsnippetisdefinedu......
  • 前端调试时不改代码但又想打印变量信息怎么办?
    我们都知道,Chrome的控制台可以在调试的时候打断点。程序运行到这的时候会停止但有时候我们不希望程序断点执行,我们只是想看一些变量的信息。按照以前的方式,我们只能去修改源码增加打印日志的语句,这样既浪费时间,又需要在调试完成后清理掉我们打印的日志代码。其实,Chrome浏览......
  • 代码随想训练营第五天(Python)| 242.有效的字母异位词、349. 两个数组的交集、第202题.
    242.有效的字母异位词1、数组法这个思路贼6,在这个题的效率也高classSolution:defisAnagram(self,s:str,t:str)->bool:#全部转为asii码如果是互为异为词,则最后的-+后的结果为0record=[0]*26#范围是26。一维foriins......
  • 2-快速上手——从0到1掌握算法面试需要的数据结构(一)
    数据结构层面,大家需要掌握以下几种:数组栈队列链表树(这里我们着重讲二叉树)对于这些数据结构,各位如果没有大量的可支配时间可以投入,那么其实不建议找厚厚的大学教材来刷。此时此刻,时间为王,我们追求的是效率的最大化。不同的数据结构教材,对数据结构有着不同的划分、不同的解......
  • 冒泡排序算法(Bubble Sort)—经典排序算法
    导言冒泡排序是最基本、最简单的排序算法之一,它通过多次遍历待排序的数组或列表,依次比较相邻的元素并交换位置,使得较大(或较小)的元素逐渐“浮”到数组的一端。原理分析冒泡排序算法通过多次遍历待排序的数组或列表,依次比较相邻的元素并交换位置,使得较大(或较小)的元素逐渐“浮”到数组......
  • 代码随想录第六天 | 哈希表、242.有效的字母异位词 、349. 两个数组的交集 、202. 快
    哈希表什么是哈希表哈希表是根据关键码的值而直接进行访问的数据结构。简单的例子:数组什么时候想到用哈希法当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。哈希碰撞元素通过哈希函数被映射到同一个索引下标位置解决方法:拉链法从发生冲......