程序员必知!策略模式的实战应用与案例分析

Java核心基础 - 程序员古德

策略模式允许在运行时改变对象行为,创建代表不同策略的对象,上下文对象根据所选策略改变执行算法,在电商平台支付系统中,用户可选多种支付方式,每种方式有独特处理流程,策略模式将各支付方式作为策略封装,用户选择时执行相应逻辑,这遵循开闭原则,增强系统可扩展性和可维护性。

定义

程序员必知!策略模式的实战应用与案例分析 - 程序员古德

策略模式(Strategy Pattern)是行为设计模式之一,它能在运行时改变对象的行为,在策略模式中,一个类的行为或其算法可以在运行时更改,这种类型的设计模式属于行为模式,在策略模式中,需要创建表示各种策略的对象,和一个行为随着策略对象改变而改变的上下文对象,策略对象会改变上下文对象的执行算法。

举一个业务中的实际例子,假设正在开发一个电商平台的支付系统,在这个系统中,用户可以选择多种支付方式,比如支付宝、微信支付、银行卡支付等,每种支付方式都有自己的一套流程和算法,这个场景中可以使用策略模式,可以把每种支付方式看作是一个策略,每个策略都封装了各自支付方式的流程和算法,当用户选择某种支付方式时,只需要在运行时动态地切换到对应的策略即可。

具体来说,可以定义一个支付策略的接口,这个接口中定义了支付方法,然后,为每种支付方式创建一个类,这些类实现了支付策略的接口,并实现了各自的支付方法,最后,创建一个上下文类,这个类中包含一个支付策略的引用,以及一个执行支付的方法,当用户选择支付方式时,只需要在上下文类中设置对应的支付策略,然后调用执行支付的方法即可。

这样的好处是,如果以后需要增加新的支付方式,只需要创建新的策略类,而不需要修改上下文类和其他已有的策略类,这也符合开闭原则,使得系统更加灵活和可扩展。

代码案例

程序员必知!策略模式的实战应用与案例分析 - 程序员古德

反例

下面是一个未使用策略模式的反例代码,有一个支付系统,它支持支付宝和微信支付,但是支付方式的选择是硬编码在支付处理类中的,而不是通过策略模式动态选择的,如下代码:

// 支付方式接口  
public interface PaymentMethod {  
    void pay(double amount);  
}  
  
// 支付宝支付实现  
public class Alipay implements PaymentMethod {  
    @Override  
    public void pay(double amount) {  
        System.out.println("使用支付宝支付 " + amount + " 元");  
    }  
}  
  
// 微信支付实现  
public class WechatPay implements PaymentMethod {  
    @Override  
    public void pay(double amount) {  
        System.out.println("使用微信支付 " + amount + " 元");  
    }  
}

然后,创建一个支付处理类,但是它没有使用策略模式,而是直接在内部决定了使用哪种支付方式,如下代码:

// 未使用策略模式的支付处理类  
public class PaymentProcessor {  
    // 假设这里硬编码选择了支付宝支付  
    private PaymentMethod method = new Alipay();  
      
    // client调用此方法来进行支付  
    public void processPayment(double amount) {  
        // 这里直接调用了内部选择的支付方式  
        method.pay(amount);  
    }  
      
    // 假设有一个方法可以切换支付方式,但实际上这种切换是硬编码的,不够灵活  
    public void setPaymentMethodToAlipay() {  
        this.method = new Alipay();  
    }  
      
    public void setPaymentMethodToWechatPay() {  
        this.method = new WechatPay();  
    }  
}

现在,编写client代码来调用这个支付处理类,如下代码:

public class Client {  
    public static void main(String[] args) {  
        // 创建支付处理对象  
        PaymentProcessor processor = new PaymentProcessor();  
          
        // 调用支付方法  
        processor.processPayment(100.0); // 输出:使用支付宝支付 100.0 元  
          
        // 尝试切换支付方式到微信支付  
        processor.setPaymentMethodToWechatPay();  
        processor.processPayment(200.0); // 输出:使用微信支付 200.0 元  
          
        // 假设系统升级,需要添加新的支付方式,那么就需要修改PaymentProcessor类  
        // 这违反了开闭原则,因为添加新功能需要修改已有代码  
    }  
}

在这个反例中,PaymentProcessor 类内部硬编码了支付方式的选择逻辑,虽然提供了切换支付方式的方法,但是这种方式不够灵活,因为每次添加新的支付方式都需要修改 PaymentProcessor 类,此外,如果需要在运行时根据用户的选择或其他条件动态切换支付方式,这种硬编码的方式就无法满足需求。

使用策略模式可以很好地解决这个问题,通过将支付方式封装为策略对象,并在运行时动态地传递给上下文对象(比如 PaymentProcessor),可以更加灵活和可扩展地管理支付方式,如下面正例。

正例

下面是一个使用策略模式的正例代码实现,在这个例子中,同样有一个支付系统,它支持多种支付方式,包括支付宝、微信支付等,通过使用策略模式,可以动态地选择支付方式,而不需要修改支付处理类的代码,如下代码:

// 支付策略接口  
public interface PaymentStrategy {  
    void pay(double amount);  
}  
  
// 支付宝支付策略实现  
public class AlipayStrategy implements PaymentStrategy {  
    @Override  
    public void pay(double amount) {  
        System.out.println("使用支付宝支付 " + amount + " 元");  
    }  
}  
  
// 微信支付策略实现  
public class WechatPayStrategy implements PaymentStrategy {  
    @Override  
    public void pay(double amount) {  
        System.out.println("使用微信支付 " + amount + " 元");  
    }  
}

接着,创建一个支付上下文类,它可以根据client的选择来动态地切换支付策略,如下代码:

// 支付上下文类,使用策略模式  
public class PaymentContext {  
    // 持有支付策略的引用  
    private PaymentStrategy strategy;  
      
    // 构造函数,接收支付策略作为参数  
    public PaymentContext(PaymentStrategy strategy) {  
        this.strategy = strategy;  
    }  
      
    // 执行支付  
    public void executePayment(double amount) {  
        strategy.pay(amount);  
    }  
      
    // 在运行时动态改变支付策略  
    public void setStrategy(PaymentStrategy strategy) {  
        this.strategy = strategy;  
    }  
}

最后,编写client代码来演示如何使用策略模式进行支付,如下代码:

public class Client {  
    public static void main(String[] args) {  
        // 创建支付上下文对象,并设置支付策略为支付宝  
        PaymentContext context = new PaymentContext(new AlipayStrategy());  
        context.executePayment(100.0); // 输出:使用支付宝支付 100.0 元  
          
        // 动态切换支付策略到微信支付  
        context.setStrategy(new WechatPayStrategy());  
        context.executePayment(200.0); // 输出:使用微信支付 200.0 元  
          
        // 假设需要添加新的支付方式(比如银联支付),只需实现PaymentStrategy接口  
        // 而不需要修改PaymentContext类或其他已有的支付策略类,这符合开闭原则  
    }  
}

在这个正例中,通过策略模式实现了支付方式的动态切换,client代码可以根据需要在运行时选择不同的支付策略,而不需要修改支付上下文类的代码。如果以后需要添加新的支付方式,只需要实现PaymentStrategy接口,并创建相应的策略实现类即可,这完全符合开闭原则,提高了系统的灵活性和可扩展性。

核心总结

程序员必知!策略模式的实战应用与案例分析 - 程序员古德

策略模式在Java开发过程中非常的实用,它让算法或行为能随需切换,增强了系统的灵活性与扩展性,当业务逻辑复杂、需多种算法并行时,策略模式可避免大量条件判断,使代码更简洁、易维护,但是,策略模式也存在很大的问题,它可能增加系统类和对象的数量,导致额外的开销,同时,client必须了解所有策略,才能选择合适的策略,这有时会增加client的复杂性,对于对于变化频繁、需求多样的场景,策略模式是不二之选;而对于稳定、简单的业务逻辑,过度使用策略模式可能适得其反。

个人思考

策略模式和责任链模式有什么区别?

策略模式关注的是如何根据不同的策略或算法来执行特定的任务,它允许在运行时根据需要动态地选择不同的策略,在策略模式中,client通常知道所有的策略,并且负责选择使用哪一个,它的优点是提供了更好的扩展性,因为添加新的策略只需要实现相应的策略接口,而不需要修改已有的代码。

相比之下,责任链模式则关注的是如何将请求沿着一个处理链进行传递,直到有一个处理者能够处理它为止。在责任链模式中,每个处理者都对请求进行检查,看自己是否能够处理,如果不能处理,则将请求传递给链中的下一个处理者,client通常不知道链中的具体处理者,也不需要关心请求是如何被处理的,这种模式的优点是减少了请求的发送者和接收者之间的耦合,因为发送者只需要知道链中的第一个处理者即可。

总结:策略模式更关注于根据不同的策略来执行任务,而责任链模式更关注于将请求沿着一个处理链进行传递。

关注我,每天学习互联网编程技术 - 程序员古德

  • 27
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 《程序员必知的硬核知识大全》是一本面向程序员的综合性知识手册,涵盖了各个领域的关键知识点,旨在帮助程序员提升技术水平和解决实际问题。该书以PDF格式出版,便于读者在电脑、手机等设备上随时查阅。 该书内容包括以下几个方面的硬核知识: 1. 编程语言知识:介绍了主流的编程语言,如Java、C++、Python等,包括语法、数据结构、算法等方面的内容。 2. 操作系统和计算机原理:详细介绍了操作系统的基本原理和常见问题解决方法,以及计算机组成原理和计算机网络等相关知识。 3. 数据库和存储知识:讲解了数据库设计和管理的基本原理,介绍了关系型数据库如MySQL和非关系型数据库如MongoDB等的使用方法和优化技巧。 4. 网站和网络开发知识:包括Web开发的基本原理、前后端开发技术、网络安全和性能优化等方面的内容。 5. 软件工程和开发方法论:介绍了软件工程的基本概念和常用开发方法,包括敏捷开发、测试驱动开发和持续集成等。 6. 设计模式和架构知识:详细介绍了常用的设计模式和软件架构,帮助程序员设计可维护、可扩展和高效的软件系统。 除了以上几个方面的内容,该书还涵盖了其他与程序员工作密切相关的技术和知识,如版本控制、软件部署、性能调优等。《程序员必知的硬核知识大全》适合本科或者有一定编程经验的程序员阅读,对于提高技术实力和职业发展都有很大帮助。 ### 回答2: "程序员必知的硬核知识大全 pdf"是一份提供程序员必备知识的电子书,PDF格式可以方便地在各种设备上阅读。这本书包含了各个方面的硬核知识,帮助程序员提高技术能力和解决问题的能力。 这本电子书的内容包括了数据结构和算法,编程语言,操作系统,网络通信,数据库管理等各方面的知识。对于程序员而言,这些都是非常重要的基础知识,能够帮助他们理解和设计高效的程序。 在数据结构和算法部分,程序员将学习到各种基础的数据结构,如数组、链表、栈和队列,以及常见的算法,如排序和搜索算法。这些知识对于程序的效率和性能优化至关重要。 编程语言部分将介绍多种编程语言,如C、C++、Java和Python等。这些语言在不同的领域有各自的优点和适用范围,程序员需要了解它们的特点和使用方法,以便在开发项目时选择合适的语言。 操作系统部分将深入讲解操作系统的原理和设计。程序员将了解到进程管理、内存管理、文件系统等重要概念,这些对于编写具有高可靠性和高性能的程序至关重要。 网络通信部分将介绍计算机网络的基本原理和常见的协议,如TCP/IP和HTTP等。程序员需要理解网络通信的基础知识,以便与其他系统进行数据交换和通信。 数据库管理部分将详细介绍关系型数据库和非关系型数据库的原理和使用方法。程序员需要了解数据库的设计和优化,以提高数据的存储和检索效率。 总之,这本电子书涵盖了程序员必备的硬核知识,对于提高他们的技术能力和解决问题的能力非常有帮助。 ### 回答3: 《程序员必知的硬核知识大全》是一本汇集了程序员必备的核心知识的书籍,可以帮助程序员提升自己的技术水平。这本书涵盖了计算机科学的各个领域和重要概念,包括数据结构与算法、操作系统、编程语言、网络通信、数据库、Web开发、软件工程等。 在数据结构与算法部分,书中介绍了常用的数据结构如链表、栈、队列以及各种排序和搜索算法,帮助程序员理解和应用这些经典的算法。在操作系统方面,书中讲解了进程、线程、内存管理、文件系统等重要概念,帮助程序员深入了解计算机系统的工作原理。 在编程语言方面,书中列举了多种编程语言的特性和应用场景,如C++、Java、Python等,有助于程序员选择适合自己的编程语言并掌握其特性。在网络通信部分,书中介绍了TCP/IP协议、HTTP协议等重要的网络通信协议和技术,帮助程序员理解网络通信的基本原理。 此外,书中还介绍了数据库的相关知识,包括关系数据库、SQL语言、数据备份与恢复等内容,有助于程序员设计和管理数据库。在Web开发方面,书中介绍了前端开发、后端开发、服务器部署等关键技术,帮助程序员构建高效、安全的Web应用程序。 最后,在软件工程方面,书中讲解了软件开发的生命周期、需求分析、设计模式、测试和持续集成等内容,有助于程序员理解和掌握软件开发过程中的重要环节。 总的来说,这本《程序员必知的硬核知识大全》提供了一站式的学习资料,涵盖了程序员必备的核心知识,可以帮助程序员系统地学习和应用这些知识,提升自己的技术能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员古德

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值