Java中常用的设计模式之策略模式详解

 更新时间:2022年02月27日 11:46:57   作者:Asurplus、  
这篇文章主要为大家详细介绍了Java中常用的设计模式之策略模式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

优点

1.算法可以自由切换。

2.避免使用多重条件判断。

3.扩展性良好。

缺点

1.策略类会增多。

2.所有策略类都需要对外暴露。

使用场景

1.如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。

2.一个系统需要动态地在几种算法中选择一种。

3.如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

一、实现方式

假设一个场景,我们在电商系统中,订单分为很多种,例如:普通订单,秒杀订单,拼团订单等等。我们需要创建一个订单的时候,由于订单的类型不同,我们需要根据订单的类型执行不同的业务逻辑。

1、订单类型枚举类

package com.asurplus.common.strategy;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
 * 订单类型枚举类
 */
@Getter
@AllArgsConstructor
public enum OrderTypeEnum {
    COMMON(1001, "普通订单"),
    SECKILL(1002, "秒杀订单"),
    SPELL(1003, "拼团订单");
    int type;
    String desc;
}

我们的订单分为三种,普通订单,秒杀订单,拼团订单。

2、订单处理接口

package com.asurplus.common.strategy;
/**
 * 订单处理接口
 */
public interface OrderService {
    /**
     * 创建订单
     *
     * @return
     */
    void createOrder();
    /**
     * 获取订单类型
     *
     * @return
     */
    OrderTypeEnum type();
}

3、普通订单处理器

package com.asurplus.common.strategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
 * 普通订单处理器
 */
@Slf4j
@Service
public class CommonOrderServiceImpl implements OrderService {
    @Override
    public void createOrder() {
        log.info("创建 普通订单");
    }
    @Override
    public OrderTypeEnum type() {
        return OrderTypeEnum.COMMON;
    }
}

4、秒杀订单处理器

package com.asurplus.common.strategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
 * 秒杀订单处理器
 */
@Slf4j
@Service
public class SeckillOrderServiceImpl implements OrderService {
    @Override
    public void createOrder() {
        log.info("创建 秒杀订单");
    }
    @Override
    public OrderTypeEnum type() {
        return OrderTypeEnum.SECKILL;
    }
}

5、拼团订单处理器

package com.asurplus.common.strategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
 * 拼团订单处理器
 */
@Slf4j
@Service
public class SpellOrderServiceImpl implements OrderService {
    @Override
    public void createOrder() {
        log.info("创建 拼团订单");
    }
    @Override
    public OrderTypeEnum type() {
        return OrderTypeEnum.SPELL;
    }
}

6、下单管理器

package com.asurplus.common.strategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
/**
 * 订单管理器
 */
@Component
public class OrderManager {
    /**
     * Autowired 注解的强大之处
     */
    @Autowired
    private List<OrderService> orderServices;
    /**
     * 创建订单
     *
     * @param type 订单类型
     * @return
     */
    public void createOrder(int type) {
        /**
         * 根据订单类型,找到对应的处理器
         */
        Optional<OrderService> any = orderServices.stream().filter(f -> f.type().getType() == type).findAny();
        /**
         * 没有对应的处理器
         */
        if (!any.isPresent()) {
            throw new RuntimeException("没有找到相应的订单实现");
        }
        // 创建订单
        any.get().createOrder();
    }
}

这里就能体现出 @Autowired 的强大之处,可以一次性自动注入多个对象。根据订单类型,选出对应的处理器来处理该订单。

二、测试

1、引入依赖

<!-- 测试依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

2、测试用例

package com.asurplus.common.strategy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
 * 策略模式
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestMain {
    @Autowired
    private OrderManager orderManager;
    @Test
    public void test() {
        // 创建 秒杀订单
        orderManager.createOrder(OrderTypeEnum.SECKILL.getType());
    }
}

输出结果

在这里插入图片描述

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!   

相关文章

  • IDEA取消SVN关联,再重新分享项目的操作

    IDEA取消SVN关联,再重新分享项目的操作

    这篇文章主要介绍了IDEA取消SVN关联,再重新分享项目的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • java递归实现复制一个文件夹下所有文件功能

    java递归实现复制一个文件夹下所有文件功能

    这篇文章主要介绍了java递归实现复制一个文件夹下所有文件功能n次,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • Springboot实现多文件上传代码解析

    Springboot实现多文件上传代码解析

    这篇文章主要介绍了Springboot实现多文件上传代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • 使用Feign扩展包实现微服务间文件上传

    使用Feign扩展包实现微服务间文件上传

    这篇文章主要为大家详细介绍了使用Feign扩展包实现微服务间文件上传,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-04-04
  • Java的枚举,注解和反射(一)

    Java的枚举,注解和反射(一)

    今天小编就为大家分享一篇关于Java枚举,注解与反射原理说明,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2021-07-07
  • GraphQL入门总体创建教程

    GraphQL入门总体创建教程

    这篇文章主要为大家介绍了GraphQL入门总体创建教程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Java 时间相减算法题解示例

    Java 时间相减算法题解示例

    这篇文章主要为大家介绍了Java 时间相减算法题解示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • Java中equals比较方法使用详解

    Java中equals比较方法使用详解

    这篇文章主要给大家介绍了关于Java中equals比较方法使用的相关资料,在Java中equals()方法是Object类的一个实例方法,用于比较两个对象是否相等,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • Java深入探索线程安全和线程通信的特性

    Java深入探索线程安全和线程通信的特性

    这篇文章主要介绍了Java线程安全和线程通信的特性,线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况
    2022-05-05
  • Java中增强for循环代码示例

    Java中增强for循环代码示例

    这篇文章主要给大家介绍了Java中增强for循环的相关资料,for/in循环就是JDK5.0中所谓的增强For循环,它能对数组和集合进行遍历,使用它会使用你的代码短小而精炼的多,需要的朋友可以参考下
    2023-10-10

最新评论