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策略模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java面向对象之继承、构造方法、重写、重载

    Java面向对象之继承、构造方法、重写、重载

    本章具体介绍了什么是构造方法、继承、重写、重载以及创建方法,整篇文章用老司机和人类来举例,图解穿插代码案例,需要的朋友可以参考下
    2023-03-03
  • Java设计模式之原型模式的示例详解

    Java设计模式之原型模式的示例详解

    原型模式(Prototype Pattern)指使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。本文将通过案例详细讲解一下原型模式,感兴趣的可以了解一下
    2022-02-02
  • Spring Boot 实现字段唯一校验功能(实例代码)

    Spring Boot 实现字段唯一校验功能(实例代码)

    这篇文章主要介绍了Spring Boot 实现字段唯一校验,实现代码很简单,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • 详解java JDK 动态代理类分析(java.lang.reflect.Proxy)

    详解java JDK 动态代理类分析(java.lang.reflect.Proxy)

    这篇文章主要介绍了详解java JDK 动态代理类分析(java.lang.reflect.Proxy)的相关资料,需要的朋友可以参考下
    2017-06-06
  • IDEA 报Plugin'maven-resources-plugin:'not found 的解决方案

    IDEA 报Plugin'maven-resources-plugin:'not found 

    如果在使用 IDEA 时遇到 "Plugin 'maven-resources-plugin:' not found" 错误,可能是由于 Maven 仓库中未找到所需的 Maven 插件,近小编给大家分享几种解决方法,感兴趣的朋友跟随小编一起看看吧
    2023-07-07
  • 使用Java实现获取文件MD5值工具类

    使用Java实现获取文件MD5值工具类

    我们在工作中通常使用MD5对文件进行校验完整性,比较,提高安全性等,这篇文章主要为大家详细介绍了Java如何编写一个实现获取文件MD5值的工具,需要的可以参考下
    2023-12-12
  • 使用SSE流式输出实战记录(Javaweb前后端)

    使用SSE流式输出实战记录(Javaweb前后端)

    这篇文章主要介绍了使用SSE流式输出(Javaweb前后端)的相关资料,SSE是一种允许服务器向客户端推送实时数据的技术,适用于聊天应用、实时数据监控等场景,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-05-05
  • SpringBoot使用JavaMailSender实现发送邮件

    SpringBoot使用JavaMailSender实现发送邮件

    JavaMailSender是Spring Framework中的一个接口,用于发送电子邮件,本文主要为大家详细介绍了SpringBoot如何使用JavaMailSender实现发送邮件,需要的可以参考下
    2023-12-12
  • mybatis项目实现动态表名的三种方法

    mybatis项目实现动态表名的三种方法

    有时在开发过程中java代码中的表名和数据库的表名并不是一致的,此时我们就需要动态的设置表名,本文主要介绍了mybatis项目实现动态表名的三种方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • IDEA类和方法注释模板设置全过程

    IDEA类和方法注释模板设置全过程

    文章介绍了如何在IDEA中使用自定义的注释模板,包括类注释模板和方法注释模板的设置方法,类注释模板可以通过编辑File and Code Templates来实现,而方法注释模板可以通过LiveTemplates功能创建
    2026-01-01

最新评论