写点什么

StrategyPattern- 策略模式

作者:梁歪歪 ♚
  • 2022 年 6 月 01 日
  • 本文字数:2127 字

    阅读完需:约 7 分钟

StrategyPattern-策略模式

策略模式

策略模式(Strategy Pattern):是指定义了不同的算法逻辑,并将不同的算法分别封装起来,让它们之间可以互相替换,使用者可以使用任意一种算法。策略模式可以让算法逻辑发生变化时不会影响到使用算法逻辑的用户,一般常用来改造代码中大量的 if 逻辑。示例:日常生活中,我们经常使用的支付方式(支付宝、微信、云闪付等),就相当于是策略模式中的算法,我们使用任意一种支付方式都不会影响最终的结果。那么,我们就以支付为例来看看怎么使用策略模式。


  • 首先创建一个顶层的策略接口IPayStrategy.java


package cn.liangyy.strategy;
import java.math.BigDecimal;
/** * 顶层的策略接口 */public interface IPayStrategy { /** * 支付 * @param money 支付金额 * @return */ boolean pay(int money);
/** * 查询余额 * @return */ BigDecimal queryBalance();}
复制代码


  • 定义支付宝支付类ALiPayStrategy.java


package cn.liangyy.strategy;
import java.math.BigDecimal;
/** * 支付宝支付类 */public class ALiPayStrategy implements IPayStrategy { /** * 支付 * * @param money 支付金额 * @return */ @Override public boolean pay(int money) { System.out.println("支付宝支付成功!"); return true; }
/** * 查询余额 * * @return */ @Override public BigDecimal queryBalance() { System.out.println("支付宝余额为 20 元!"); return new BigDecimal("20"); }}
复制代码


  • 定义微信支付类WeChatPayStrategy.java


package cn.liangyy.strategy;
import java.math.BigDecimal;
/** * 微信支付类 */public class WeChatPayStrategy implements IPayStrategy { /** * 支付 * * @param money 支付金额 * @return */ @Override public boolean pay(int money) { System.out.println("微信支付成功!"); return true; }
/** * 查询余额 * * @return */ @Override public BigDecimal queryBalance() { System.out.println("微信余额为 30 元!"); return new BigDecimal("30"); }}
复制代码


  • 创建测试类TestPayStrategy.java


package cn.liangyy.strategy;
/** * 策略模式-测试类 */public class TestPayStrategy { public static void main(String[] args) { //支付类型 String pay = "aliPay"; IPayStrategy payStrategy = null; //根据不同的支付类型,选择不同的支付种类 if (pay.equals("aliPay")){ payStrategy = new ALiPayStrategy(); }else if (pay.equals("wechatPay")){ payStrategy = new WeChatPayStrategy(); } payStrategy.pay(10); payStrategy.queryBalance(); }}
复制代码


上面是策略模式的一个简单写法,但是上面的写法存在一个很大的问题,就是例如有很多策略,那么我们的 if 判断就会变得很庞大,这明显不利于维护,所以需要再对上面的例子进行改造。


  • 新建一个枚举类PayEnum.java,将所有的策略和 key 值对应关系维护在枚举类中。


package cn.liangyy.strategy;
/** * 枚举类 * 用来维护所有的策略和key值对应关系 */public enum PayEnum { AliPay("aliPay",new ALiPayStrategy()), WechatPay("wechatPay",new WeChatPayStrategy());
private String key; private IPayStrategy value;
PayEnum(String key, IPayStrategy value) { this.key = key; this.value = value; }
public static IPayStrategy getValue(String key){ //遍历枚举类 for (PayEnum payEnum : PayEnum.values()){ if (payEnum.key.equals(key)){ return payEnum.value; } } //如果没有合适的key就默认使用支付宝支付 return new ALiPayStrategy(); }}
复制代码


  • 再新建一个测试类TestPayStrategy.java,进行测试


package cn.liangyy.strategy;
public class TestPayStrategy2 { public static void main(String[] args) { IPayStrategy iPayStrategy = PayEnum.getValue("aliPay"); iPayStrategy.pay(10); iPayStrategy.queryBalance(); }}
复制代码


对比前后两种方式,很显然,第二种写法更加优雅方便,在实际中应用场景更多。


策略模式适用场景同一个系统假如存在场景可能有很多分支,而每次又只可能是一种分支,那么这种情况就非常适合使用策略模式来编码,彼此策略之间独立又可互相替换。


策略模式优点


  • 策略模式各个算法之间彼此独立,新增算法只需新增类就好了,符合开闭原则。

  • 可以简化代码中存在的大量 if 或者 switch 循环分支,提升了代码的可读性,方便维护和扩展。


策略模式缺点


  • 当系统中存在很多策略的时候,会产生很多类,增加了系统的复杂性。

  • 使用者需要自行选择策略,故而其必须清楚的知道每种策略,否则无法做出合适的选择。

发布于: 刚刚阅读数: 4
用户头像

梁歪歪 ♚

关注

还未添加个人签名 2021.07.22 加入

还未添加个人简介

评论

发布
暂无评论
StrategyPattern-策略模式_设计模式_梁歪歪 ♚_InfoQ写作社区