策略模式(Strategy Pattern)深度解析教程!
开篇语
哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛
今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。
我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。
小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!
前言
在开发过程中,常常会遇到这样的需求:同一操作在不同的场景下可能会有不同的实现方式。比如,一个系统中可能有多个排序算法,根据不同的数据和场景选择不同的排序方式,或者在支付系统中,不同的支付方式采用不同的支付策略。为了处理这些场景,设计模式提供了许多有用的解决方案,其中策略模式(Strategy Pattern)就是一个非常实用的模式。
今天,我们将通过一个详细的示例和深入的分析,帮助你更好地理解策略模式的核心思想、应用场景及实现方式。
一、策略模式概述
策略模式是一种行为型设计模式,它定义了一系列算法,将每一个算法封装起来,并使它们可以相互替换。策略模式让算法的使用者可以独立于算法的变化来选择所需的算法。
1. 策略模式的组成
策略模式通常由以下几个部分组成:
- Context(上下文):持有一个策略实例,并通过调用策略实例的方法来完成具体的操作。
- Strategy(策略接口):定义一个共同的接口,用来实现具体的策略。
- ConcreteStrategy(具体策略):实现策略接口的具体算法。
- Client(客户端):客户端可以根据需要选择具体的策略。
2. 策略模式的优点
- 避免使用大量的条件语句:策略模式将不同的算法封装成独立的类,而不是通过大量的条件判断来切换不同的算法。
- 增强代码的可扩展性:当需要新增某种策略时,我们只需要创建一个新的策略类并实现策略接口,完全不影响现有代码。
- 提高代码的可维护性:每个策略类独立处理自己的业务,易于测试和维护。
二、策略模式的应用场景
策略模式主要应用于以下几种场景:
-
算法的可变性:当一个类的行为取决于其状态,或者有多个算法可以选择时,可以使用策略模式。客户端可以根据具体情况选择不同的策略。
-
避免条件语句的复杂度:当系统中有多条条件语句,判断不同的情况下执行不同的行为时,策略模式可以将这些条件语句封装到不同的策略类中,避免大量的条件判断。
-
需要根据不同环境选择不同算法时:比如支付系统中的不同支付方式,不同的数据排序算法等。
三、策略模式的结构
在策略模式中,我们需要抽象出一个共同的策略接口,然后实现多个具体的策略类。具体代码实现如下:
1. 定义策略接口
public interface PaymentStrategy {
void pay(int amount);
}
这里的 PaymentStrategy
是策略接口,定义了一个 pay
方法。任何具体的支付方式都需要实现这个接口。
2. 实现具体策略类
接下来,我们实现多个具体的支付策略类,模拟不同的支付方式。
public class CreditCardPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using Credit Card.");
}
}
public class PayPalPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using PayPal.");
}
}
public class BitcoinPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using Bitcoin.");
}
}
在这里,我们定义了三个具体的支付方式:信用卡支付(CreditCardPayment
)、PayPal 支付(PayPalPayment
)和比特币支付(BitcoinPayment
)。每种支付方式实现了 PaymentStrategy
接口,并在 pay
方法中实现了具体的支付逻辑。
3. 定义上下文类
上下文类 PaymentContext
用于与策略进行交互,选择合适的策略进行支付。
public class PaymentContext {
private PaymentStrategy paymentStrategy;
// 设置支付策略
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
// 执行支付操作
public void executePayment(int amount) {
paymentStrategy.pay(amount);
}
}
PaymentContext
类包含一个 PaymentStrategy
类型的成员变量,代表当前的支付方式。通过 setPaymentStrategy
方法,我们可以动态地设置支付策略。executePayment
方法负责执行支付操作,并委托给具体的支付策略。
4. 客户端使用策略模式
客户端可以根据需要选择具体的支付方式,并通过上下文类执行支付操作。
public class StrategyPatternDemo {
public static void main(String[] args) {
PaymentContext paymentContext = new PaymentContext();
// 使用信用卡支付
paymentContext.setPaymentStrategy(new CreditCardPayment());
paymentContext.executePayment(100); // 输出:Paid 100 using Credit Card.
// 使用 PayPal 支付
paymentContext.setPaymentStrategy(new PayPalPayment());
paymentContext.executePayment(200); // 输出:Paid 200 using PayPal.
// 使用比特币支付
paymentContext.setPaymentStrategy(new BitcoinPayment());
paymentContext.executePayment(300); // 输出:Paid 300 using Bitcoin.
}
}
在 StrategyPatternDemo
类中,我们通过 PaymentContext
动态切换支付方式。当我们需要不同的支付方式时,只需要设置不同的策略对象即可。
四、策略模式的优缺点
1. 优点
- 消除条件判断:在很多情况下,代码中的条件语句会变得非常庞大和复杂。策略模式通过封装不同的算法,将复杂的条件判断移到具体的策略类中,减少了代码中的条件判断。
- 易于扩展:如果需要增加新的策略,只需要实现一个新的策略类,并在上下文中配置即可,完全不需要修改现有代码,符合开闭原则(Open/Closed Principle)。
- 简化代码:每个策略类都只关注一种算法,保持了代码的单一职责,代码结构更加清晰。
2. 缺点
- 策略类过多:当有大量的策略时,可能会导致类的数量急剧增加,从而影响代码的维护。
- 客户端需要了解策略类:虽然策略模式解耦了上下文和算法的实现,但客户端仍然需要知道并选择具体的策略类。
五、策略模式与其他设计模式的关系
策略模式和其他设计模式如工厂模式、模板方法模式等有一定的关联。
-
策略模式与工厂模式:
- 工厂模式用于对象的创建,而策略模式用于对象的行为选择。两者可以结合使用,工厂模式可以用来根据需要创建不同的策略对象。
-
策略模式与模板方法模式:
- 模板方法模式是通过定义算法的框架,让子类来实现具体的步骤。而策略模式是将不同的算法封装成不同的策略,并由上下文选择合适的策略。在某些情况下,策略模式和模板方法模式可以协同工作,策略模式负责封装具体的算法,而模板方法模式负责定义执行的流程。
六、总结
策略模式是一种非常常见且实用的设计模式,通过将不同的算法封装在独立的策略类中,策略模式让我们能够动态地选择不同的算法并应用于具体的场景。在面对有多个算法的场景时,策略模式能够有效地解耦类和算法,提高系统的灵活性和可维护性。
通过上述实例,我们展示了如何在实际开发中使用策略模式来处理不同的支付方式,同时避免了大量的条件判断,使代码更加清晰、易于扩展。如果你在开发中需要处理类似的多算法切换的场景,策略模式无疑是一个非常好的解决方案。
… …
文末
好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。
… …
学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!
wished for you successed !!!
⭐️若喜欢我,就请关注我叭。
⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。
版权声明:本文由作者原创,转载请注明出处,谢谢支持!
- 点赞
- 收藏
- 关注作者
评论(0)