Java设计模式之策略模式详解和示例

 更新时间:2024年01月18日 09:53:44   作者:小白不很白  
这篇文章主要介绍了Java设计模式之策略模式详解和示例,策略模式就是一种行为可能会因为不同的逻辑造成多个算法,比如人吃饭,美国人吃饭用刀叉,中国吃饭用筷子,都是吃饭的行为但是使用的工具(算法)不一样,需要的朋友可以参考下

1. 什么是策略模式

策略模式就是一种行为可能会因为不同的逻辑造成多个算法。比如人吃饭,美国人吃饭用刀叉,中国吃饭用筷子。都是吃饭的行为但是使用的工具(算法)不一样。而策略行为就是把这写工具封装为对象,不同的人会动态的调用不同的对象,来实现吃饭这一行为。 ​

2. 策略模式组成

环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。

抽象策略类(Strategy):定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。

具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法。

3. 策略模式UML图

在这里插入图片描述

4. 示例

就按照上面提到的例子,按照策略模式UML图按照策略模式实现人吃饭这件事情。

4.1 创建Strategy抽象策略类

public interface Strategy {
    /**
     * 人类怎么吃饭的
     */
   public void eat();
}

4.2 创建环境类

public class Context {
    private Strategy strategy;
    public Context(){
    }
    public Context(Strategy strategy){
        this.strategy = strategy;
    }
    public void  setStrategy(Strategy strategy){
        this.strategy = strategy;
    }
    public void eat(){
        strategy.eat();
    }
}

上面环境类我根据我是实现了两种方式传入策略类,可以根据自己不同的需求就行灵活应用给

4.3 创建实现

 
 /**
 * 美国人 吃饭
 */
@Component
public class StrategyImplOne implements Strategy{
    @Override
    public void eat() {
        System.out.println("美国人用刀叉吃饭");
    }
}
/**
 * 中国人 吃饭
 */
@Component
public class StrategyImplTwo implements Strategy{
    @Override
    public void eat() {
        System.out.println("中国人用筷子吃饭");
    }
}

4.4 测试

public class MainTest {
    public  static  void test(){
        Context context = new Context();
        context.setStrategy(new StrategyImplOne());
        context.eat();
        context.setStrategy(new StrategyImplTwo());
        context.eat();
    }
    public static void main(String[] args) {
        test();
    }
}

当然了这是简单的场景,在复杂的场景中我们不想经过判断他是美国人还是中国人来创建对应的实现,设置到环境类中,我们可以给每个实现设置一个属性标识,来标识他是中国人还是美国人,然后根据标识通过反射创建对应的实现对象,再设置到环境类中。下面我们看结果。 ​

首先我们加入一个枚举类(enum) 用来存储我们实现的策略类

public enum ManType {
    AMERICAN(1,"American",StrategyImplOne.class),
    CHINESE(1,"Chinese",StrategyImplTwo.class)
    ;
    private Integer code;
    private String type;
    private Class classModel;
    // 定义一个Map 开始的时候就把这信息存储到这里面
    private static HashMap<String,Class> map = new HashMap<>(16);
    static {
        for ( ManType manType:ManType.values()) {
            map.put(manType.getType(),manType.getClassModel());
        }
    }
    ManType(Integer code, String type, Class classModel) {
        this.code = code;
        this.type = type;
        this.classModel = classModel;
    }
    public Integer getCode() {
        return code;
    }
    public String getType() {
        return type;
    }
    public Class getClassModel() {
        return classModel;
    }
    // 这个方法根据type获取指定的类 通过反射来 创建对象
    public static Class getManType(String type){
        return map.get(type);
    }
}

创建好枚举类后,我们的测试方法就变为下面的这个样子。写的有点粗糙,大家见谅。

public class MainTest {
    public   void test(String manType){
        Context context = new Context();
        try {
            Strategy strategy = (Strategy) (ManType.getManType(manType).newInstance());
            context.setStrategy(strategy);
            context.eat();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        new MainTest().test("American");
    }
}

其实也可以不用反射,如果项目是使用的是SpringBoot开发的话 我们可以把实现策略类在项目启动时就给通过@Component 给注册到Spring容器中,然后通过ApplicationContext 从容器中获取指定的对象。这样也是可以的。

我就不一一展示了,感兴趣的话可以自己在下面试一下。 ​

优点和缺点

优点:

1、策略模式符合开闭原则。

2、避免使用多重条件转移语句,如if…else…语句、switch 语句

3、使用策略模式可以提高算法的保密性和安全性。

缺点

1、客户端必须知道所有的策略,并且自行决定使用哪一个策略类。

2、代码中会产生非常多策略类,增加维护难度。

3、如果把策略类初始化时就放到Spring容器中,当策略类太多事也是一种性能消耗。

到此这篇关于Java设计模式之策略模式详解和示例的文章就介绍到这了,更多相关Java策略模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MyBatis自定义映射关系和关联查询实现方法详解

    MyBatis自定义映射关系和关联查询实现方法详解

    这篇文章主要介绍了MyBatis自定义映射关系和关联查询实现方法,当POJO属性名与数据库列名不一致时,需要自定义实体类和结果集的映射关系,在MyBatis注解开发中,使用@Results定义并使用自定义映射,使用 @ResultMap使用自定义映射
    2023-04-04
  • Java实现Excel百万级数据导入功能的示例代码

    Java实现Excel百万级数据导入功能的示例代码

    这篇文章主要为大家详细介绍了Java如何实现Excel百万级数据导入功能,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考下
    2024-04-04
  • Spring Boot 整合 Reactor实例详解

    Spring Boot 整合 Reactor实例详解

    这篇文章主要为大家介绍了Spring Boot 整合 Reactor实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • springboot中Excel文件下载踩坑大全

    springboot中Excel文件下载踩坑大全

    本文主要介绍了springboot中Excel文件下载,但是却容易遇到很多坑,文中通过示例代码介绍的非常详细,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • Mybatis在sqlite中无法读写byte[]类问题的解决办法

    Mybatis在sqlite中无法读写byte[]类问题的解决办法

    这篇文章主要给大家介绍了关于Mybatis在sqlite中无法读写byte[]类问题的解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • Java如何使用SSLContext请求https链接

    Java如何使用SSLContext请求https链接

    这篇文章主要介绍了Java如何使用SSLContext请求https链接问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • IDEA Debug模式下改变各类型变量值的方法

    IDEA Debug模式下改变各类型变量值的方法

    这篇文章主要介绍了IDEA Debug模式下改变各类型变量值的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • JAVA调用Deepseek的api完成基本对话简单代码示例

    JAVA调用Deepseek的api完成基本对话简单代码示例

    这篇文章主要介绍了JAVA调用Deepseek的api完成基本对话的相关资料,文中详细讲解了如何获取DeepSeek API密钥、添加HTTP客户端依赖、创建HTTP请求并使用示例代码来对接DeepSeek API,需要的朋友可以参考下
    2025-02-02
  • 如何理解SpringMVC

    如何理解SpringMVC

    Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发
    2021-06-06
  • Java基础学习之集合底层原理

    Java基础学习之集合底层原理

    今天带大家回顾Java基础的相关知识,文中对集合底层原理作了非常详细的图文介绍,对Java初学者有非常好的帮助,需要的朋友可以参考下
    2021-05-05

最新评论