前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >策略模式

策略模式

作者头像
阿超
发布2022-08-17 20:39:24
2060
发布2022-08-17 20:39:24
举报
文章被收录于专栏:快乐阿超快乐阿超

只有永远躺在泥坑里的人,才不会再掉进坑里。——黑格尔

今天聊聊策略模式

一个导航程序,提供多种出行方式的导航策略

例如最开始就两种策略如步行和公路出行,我们将它写到一个类中

慢慢的,新增了公共交通,步行和公路出行中的逻辑越来越多,越来越复杂

如果此时不进行抽取,则会导致一个类中的代码行数过多,维护起来困难,如果是团队开发,代码冲突不断

抽取后能解决此问题,并且一些公共逻辑抽取出来能减少重复代码

因此我们将所有策略抽取出一个公共接口:

代码语言:javascript
复制
package com.ruben.strategies.exapmle;

import java.util.List;

/**
 * 路线规划策略接口
 *
 * @author <achao1441470436@gmail.com>
 * @since 2021/10/16 19:10
 */
public interface RouteStrategy {

    /**
     * 路线规划
     *
     * @param start 起点
     * @param end   终点
     * @return 路线
     */
    List<String> buildRoute(String start, String end);
}

这里定义的是传入起点和终点,返回途中经过的路线集合

接下来,我们实现具体策略逻辑

代码语言:javascript
复制
package com.ruben.strategies.exapmle;

import java.util.Arrays;
import java.util.List;

/**
 * 公路路线规划,如开车、出租等
 *
 * @author <achao1441470436@gmail.com>
 * @since 2021/10/16 19:13
 */
public class RoadStrategy implements RouteStrategy {

    /**
     * 路线规划
     *
     * @param start 起点
     * @param end   终点
     * @return 路线
     */
    @Override
    public List<String> buildRoute(String start, String end) {
        // 具体逻辑,实际开发中可能超长一串,这里返回通过起点和终点规划出来的公路路线
        return Arrays.asList("先到达成华大道", "途径二仙桥", "路过加油站");
    }
}
代码语言:javascript
复制
package com.ruben.strategies.exapmle;

import java.util.Arrays;
import java.util.List;

/**
 * 步行路线规划
 *
 * @author <achao1441470436@gmail.com>
 * @since 2021/10/16 19:18
 */
public class WalkingStrategy implements RouteStrategy {
    /**
     * 路线规划
     *
     * @param start 起点
     * @param end   终点
     * @return 路线
     */
    @Override
    public List<String> buildRoute(String start, String end) {
        // 具体逻辑,实际开发中可能超长一串,这里返回通过起点和终点规划出来的步行路线
        return Arrays.asList("走到成华大道", "路过二仙桥", "途径菜市场");
    }
}
代码语言:javascript
复制
package com.ruben.strategies.exapmle;

import java.util.Arrays;
import java.util.List;

/**
 * 公共交通出行路线规划
 *
 * @author <achao1441470436@gmail.com>
 * @since 2021/10/16 19:20
 */
public class PublicTransportStrategy implements RouteStrategy {
    /**
     * 路线规划
     *
     * @param start 起点
     * @param end   终点
     * @return 路线
     */
    @Override
    public List<String> buildRoute(String start, String end) {
        // 具体逻辑,实际开发中可能超长一串,这里返回通过起点和终点规划出来的公共交通出行路线
        return Arrays.asList("杉板桥站乘坐地铁8号线", "到达理工大学换成地铁7号线", "二仙桥站下地铁");
    }
}

然后是核心

代码语言:javascript
复制
package com.ruben.strategies.exapmle;

import java.util.List;

/**
 * 导航
 *
 * @author <achao1441470436@gmail.com>
 * @since 2021/10/16 19:31
 */
public class Navigator {

    private RouteStrategy routeStrategy;

    /**
     * 构造函数
     *
     * @param routeStrategy 策略
     */
    public Navigator(RouteStrategy routeStrategy) {
        this.routeStrategy = routeStrategy;
    }

    /**
     * 设置路线规划策略,应变策略变更的情况
     *
     * @param routeStrategy 策略
     */
    public void setRouteStrategy(RouteStrategy routeStrategy) {
        this.routeStrategy = routeStrategy;
    }

    /**
     * 路线规划
     *
     * @param start 起点
     * @param end   终点
     * @return 路线
     */
    public List<String> buildRoute(String start, String end) {
        System.out.println("用户选择了:" + routeStrategy.getClass().getSimpleName());
        System.out.println("起点为:" + start);
        System.out.println("终点为:" + end);
        return this.routeStrategy.buildRoute(start, end);
    }

}

这里路线规划的方法,抽取出了公共部分,打印出用户的选择,以及起点和终点

最后是实际调用,这里只是简单进行一个模拟

代码语言:javascript
复制
package com.ruben.strategies.exapmle;

import java.util.List;

/**
 * 路线规划应用
 *
 * @author <achao1441470436@gmail.com>
 * @since 2021/10/16 19:36
 */
public class NavigatorApplication {
    public static void main(String[] args) {
        String start = "成华大道";
        String end = "二仙桥";
        System.out.println("用户选择了查看步路线");
        Navigator navigator = new Navigator(new WalkingStrategy());
        List<String> route = navigator.buildRoute(start, end);
        System.out.println(route);
        System.out.println("用户变更了策略,选择查看公路路线规划");
        navigator.setRouteStrategy(new RoadStrategy());
        route = navigator.buildRoute(start, end);
        System.out.println(route);
        System.out.println("用户变更了策略,选择查看公共交通路线规划");
        navigator.setRouteStrategy(new PublicTransportStrategy());
        route = navigator.buildRoute(start, end);
        System.out.println(route);
    }

}

运行结果:

image-20211016195228942
image-20211016195228942

策略模式优点

  • 你可以在运行时切换对象内的算法。
  • 你可以将算法的实现和使用算法的代码隔离开来。
  • 你可以使用组合来代替继承。
  • 开闭原则。 你无需对上下文进行修改就能够引入新的策略。

策略模式缺点

  • 如果你的算法极少发生改变, 那么没有任何理由引入新的类和接口。 使用该模式只会让程序过于复杂。
  • 客户端必须知晓策略间的不同——它需要选择合适的策略。
  • 许多现代编程语言支持函数类型功能, 允许你在一组匿名函数中实现不同版本的算法。 这样, 你使用这些函数的方式就和使用策略对象时完全相同, 无需借助额外的类和接口来保持代码简洁。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-10-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 策略模式优点
  • 策略模式缺点
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档