ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

从未这么明白的设计模式(四):策略模式

2019-07-10 16:36:05  阅读:191  来源: 互联网

标签:TravelService 出行 从未 travelService void TravelStrategy 模式 设计模式 public


cover

本文原创地址:jsbintask的博客(食用效果最佳),转载请注明出处!

前言

策略模式是一种行为模式,它用以运行时动态的改变类的行为,通过将一系列类似的算法封装成不同的类来达到目的,可以有效减少代码中if else的冗余。它实现的关键是面向接口接口编程以及有一个算法切换者。它的优点是扩展性良好,可以自由切换策略。

栗子

周末天气不错,小明准备去爬武功山,于是他请教它的出行助手应该选择怎样的工具去目的地才能让他最大化周末的快乐。于是它的出行助手开始了一段计算,操作。。。最终。。。

抽象

针对上面的案例,重点在于出行助手如何帮小明选择出行工具,这恰好可以对应我们一开始说的需要封装的算法,并且能够随意切换,于是我们可以得出下面的uml类图:
Strategy
小明通过使用出行助手来选择不同的交通工具。而出行助手内部则通过代理TravelStrategy接口来切换不同的出行算法。

实现

首先定义出行接口TravelStrategy

@FunctionalInterface
public interface TravelStrategy {
    void travel();
}

接着实现不同的出行算法,此处有BikeTravelStrategy, FootTravelStrategy, CarTravelStrategy

@Slf4j
public class BikeTravelStrategy implements TravelStrategy {
    @Override
    public void travel() {
      log.info("自行车骑行半小时,行程18公里,感觉卡路里在燃烧!");
    }
}
============================================================
@Slf4j
public class FootTravelStrategy implements TravelStrategy {

    @Override
    public void travel() {
        log.info("徒步旅行半小时,行走5公里,可以好好欣赏周边景色");
    }
}
============================================================
@Slf4j
public class CarTravelStrategy implements TravelStrategy {
    @Override
    public void travel() {
      log.info("自驾旅行半小时,行程40公里,感觉时间走的真慢。");
    }
}

接着就需要实现出行助手类:TravelService,它内部通过代理TravelStategy来切换不同的策略:

public class TravelService {
    private TravelStrategy travelStrategy;

    public void chooseTravelStrategy(TravelStrategy travelStrategy) {
        this.travelStrategy = travelStrategy;
    }

    public void doTravel() {
        this.travelStrategy.travel();
    }
}

最后,编写一个测试类:

@Slf4j
public class App {
    public static void main(String[] args) {
        System.out.println("天气不错,小明准备出门旅行,它带上了它的旅行助手'TravelService'来帮它制定出行策略.");
        TravelService travelService = new TravelService();

        System.out.println("'TravelService': 天气不错,您可以选择徒步出行");
        travelService.chooseTravelStrategy(new FootTravelStrategy());
        travelService.doTravel();

        System.out.println("'TravelService': 2小时后可能转小雨,建议您选择自行车加快形成,锻炼身体!");
        travelService.chooseTravelStrategy(new BikeTravelStrategy());
        travelService.doTravel();

        System.out.println("'TravelService': 半小时后会有暴雨,建议您选择自驾汽车去目的地.");
        travelService.chooseTravelStrategy(new CarTravelStrategy());
        travelService.doTravel();

        System.out.println("'TravelService': 天气已经好转,您可以随意选择出行方式。");
        travelService.chooseTravelStrategy(() -> {
            log.info("骑行摩托车开始,半小时形成30公里。刺激!");
        });

        System.out.println("'TravelService': 您已到达目的地.");
    }
}

注意上面的关键代码为TravelService根据不同的天气选择了不同的出行策略。
[外链图片转存失败(img-1wgEFLnl-1562747421980)(https://raw.githubusercontent.com/jsbintask22/static/master/design-mode/strategy-2.png)]
根据结果我们可以知道我们切换了三次不同的策略,并且使用lambda表达式添加了一个匿名策略。

总结

使用策略模式的关键在于面向接口编程,并且有一个全局切换策略的辅助类,它的优点在于扩展性良好,算法可以自由切换动态改变类的行为。
而它的缺点也很明显:策略类过多会导致“类爆炸“,并且所有的策略类都需要向外暴露。 所以使用时如果策略过多可以考虑使用混合模式,配合其它模式一起使用。

关注我,这里只有干货!

标签:TravelService,出行,从未,travelService,void,TravelStrategy,模式,设计模式,public
来源: https://blog.csdn.net/Iperishing/article/details/95348914

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有