JAVA设计模式之【策略模式】

工厂模式是解耦对象的创建和使用,观察者模式是解耦观察者和被观察者。策略模式跟两者类似,也能起到解耦的作用,解耦的是策略的定义、创建、使用这三部分。
通常的使用方式
**

1.策略定义

**
一个策略接口和一组实现这个接口的策略类。因为所有的策略类都实现相同的接口,所以,客户端代码基于接口而非实现编程,可以灵活地替换不同的策略。

public interface Strategy {
  void algorithm();
}

public class StrategyA implements Strategy {
  @Override
  public void  algorithm() {
    //具体的算法...
  }
}

public class StrategyB implements Strategy {
  @Override
  public void  algorithm() {
    //具体的算法...
  }
}

2.策略创建
一组策略,使用时一般通过type来判断创建哪个策略。
工厂封装创建逻辑,对客户端屏蔽创建细节

public class StrategyFactory {
  private static final Map<String, Strategy> strategies = new HashMap<>();

  static {
    strategies.put("A", new StrategyA());
    strategies.put("B", new StrategyB());
  }

  public static Strategy getStrategy(String type) {
    if (type == null || type.isEmpty()) {
      throw new IllegalArgumentException("type should not be empty.");
    }
    return strategies.get(type);
  }
}

如果策略类是无状态的,不包含成员变量,只是纯粹的算法实现,这样的策略对象是可以被共享使用的,使用map缓存
如果策略类是有状态的,根据业务场景的需要,我们希望每次从工厂方法中,获得的都是新创建的策略对象,而不是缓存好可共享的策略对象,则:

public class StrategyFactory {
  public static Strategy getStrategy(String type) {
    if (type == null || type.isEmpty()) {
      throw new IllegalArgumentException("type should not be empty.");
    }

    if (type.equals("A")) {
      return new StrategyA();
    } else if (type.equals("B")) {
      return new StrategyB();
    }

    return null;
  }
}

3.策略的使用
最常见的是运行时动态确定使用哪种策略,这也是策略模式最典型的应用场景。
Strategy strategy=StrategyFactory.getStrategy(type)

简便的使用方式
1.策略定义

public interface Strategy {
  //用来匹配策略
  boolean match(String type);  
  String algorithm();
}

public class StrategyA implements Strategy {
    @Override
    public boolean match(String type) {
        return "A".equals(type);
    }
    
    @Override
    public String  algorithm() {
        //具体的算法...
        return "this is A";
    }
}

public class StrategyB implements Strategy {
    @Override
    public boolean match(String type) {
        return "B".equals(type);
    }
    
    @Override
    public String  algorithm() {
        //具体的算法...
        return "this is B";
    }
}

//默认执行的策略
public class DefaultStrategy implements Strategy {

    @Override
    public boolean match(String type) {
        return false;
    }

    @Override
    public String algorithm() {
        return "this is 默认方法";
    }
}

2.策略使用

    @Autowired
    private List<Strategy> strategyList;

    @Autowired
    private DefaultStrategy defaultStrategy;

    @Test
    public void test_Strategy(){
       String type="A";
       //直接使用lamba表达式,match匹配执行Strategy
       String result=strategyList.stream()
           .filter(strategy -> strategy.match(type))
           .findFirst()
           .orElse(defaultStrategy)
           .algorithm();
    }

输出result="this is A";

实战代码优化
原代码写法

if (TradeChannelTypeEnum.RAPID_SEND.getType() == tradeChannel) {
    result = rapidSendInvSaleMatch.match(dbEntity, EnumsMatchType.NORMAL.getType(), tradeChannel..);
} else if (TradeChannelTypeEnum.FLASH_SEND.getType() == tradeChannel) {
    result = flashSendInvSaleMatch.match(dbEntity, EnumsMatchType.NORMAL.getType(), tradeChannel..);
} else if (TradeChannelTypeEnum.BRAND_OFFER.getType() == tradeChannel) {
    result = brandOfferInvSaleMatch.match(dbEntity, EnumsMatchType.NORMAL.getType(), tradeChannel..);
} else {
    result = defaultInvSaleMatch.match(dbEntity, EnumsMatchType.NORMAL.getType(), tradeChannel..);
}

可以看出,在业务增加的情况下,不断增加if-else,增加 InvSaleMatch service。根据不同的tradeChannel选择不同的 **InvSaleMatch (**InvSaleMatch都继承自AbsInvSaleMatch),可直接使用策略模式。

优化之后

//AbsInvSaleMatch增加 tradeChannelMatch方法
 boolean tradeChannelMatch(int tradeChannel)//各个InvSaleMatch 实现类里判断tradeChannel,用来替代之前代码里的if判断
@Autowired
private List<AbsInvSaleMatch> saleMatchList;

result = saleMatchList.stream().filter(hander -> hander.tradeChannelMatch(tradeChannel)).findFirst()
                    .orElse(defaultInvSaleMatch)
                    .match(dbEntity, EnumsMatchType.NORMAL, tradeChannel..);
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值