为了账号安全,请及时绑定邮箱和手机立即绑定

谈谈组合策略模式及在生产的应用

标签:
设计模式

谈谈组合策略模式及在生产的应用

组合模式

学设计模式第一次听到这个模式时被迷惑了,以为所谓的组合模式是跟面向对象编程里的组合概念的一样

// 想象中的组合模式class Car {
  private Door door;
  private Wheel Whee;}

读了 GOF 的设计模式之后,书里是将组合模式描述为

将对象组合成树形结构的部分-整体层次结构,使得客户使用单个对象或组合对象都有一致性

也就是说组合部分与被组合部分在对外表现上,应该都是一致的,也就是其实是这样的

class Node {
  private Node part1;
  private Node part2;}

真正让我理解组合模式和它的妙用是在《领域驱动设计》这本书里面,作者提出了一个航线的概念,也就是这样,通过组合基本组件以达到功能更强大的一个组件

interface Route {
    Route segement1, segement2;} // 路线class NationalHighway implements Route{} // 国道class CountryRoad implements Route {} // 乡道

策略模式

所谓策略,则可以理解为针对某种特定问题的算法,由于不同的算法各有优劣,所以需要将策略抽象为一个接口,让客户代码根据需求选择不同策略来解决问题,代码如下

interface Strategy{
    void execute(..);}class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }
    
    void execute(){
        strategy.execute(..);
    }}class StrategyA implements Strategy{
    // 具体实现}// 使用Context context = new Context(new StrategyA());context.execute();

二者的结合

组合与策略两者的结合,不仅可以充分利用组合模式的灵活性,同时也可以利用策略模式的不同算法可选择性

interface Strategy{
    void execute(..);}class StrategyA implements Strategy{
    // 具体实现}class StrategyB implements Strategy{
    // 具体实现}// 组合策略class CompositeStrategy implements Strategy {
  private Strategy strategyA, strategyB;}

通过组合不仅可以显式编程,交由不同的具体客户满足不同的需求,同时细粒度的策略也暴露了出去,也能让策略更有针对性及可选择性,更进一步,可以使用工厂模式将策略的组装与生成封装在工厂内部,这样客户代码也不必关心他使用的具体策略是什么,只要策略满足他的需求即可

生产上的应用

这个业务场景是这样

  • 我们有许多三方接口来获取某种信息

  • 每种接口不仅需要单独对外提供服务,同时也需要聚合所有接口数据再对外提供服务

通过封装,这些返回的信息基本上都是一样的,但由于我们的项目在不同的地方运行,不同的地方可能有些接口可用,有些接口不可用,所以此时就通过组合策略模式来满足以上的所有需求

interface FetchInfoStrategy {
    Info fetch(...);}// 具体三方接口class ThirdPartAFetchInfoStrategy implements FetchInfoStrategy{...}class ThirdPartBFetchInfoStrategy implements FetchInfoStrategy{...}class ThirdPartCFetchInfoStrategy implements FetchInfoStrategy{...}// 组合三方接口class CompositeFetchInfoStrtegy implements FetchInfoStrategy {
  // 通过配置化动态注入
  private static final List<Class<? extends FetchInfoStrategy>> STRATEGY_LIST;

  Info fetch(...) {
    // 循环调用策略,记录各个接口返回结果
    // 合并结果并返回
  }}

通过这样子的组合策略,不仅满足了需求,也为后续的优化留下了空间,若想通过异步调用各个接口,或者调整具体合并逻辑,都可以通过新增一个组合策略,避免修改老代码带来预期之外的问题


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消