前言 思路与模拟业务

源码地址 https://gitee.com/houzheng1216/springboot

整体思路就是通过注解在策略类上指定约定好的type,项目启动之后将所有有注解的type获取到,根据type存储,然后在业务中根据type获取对应的策略即可

模拟订单业务,根据订单的type,需要不同的处理逻辑,比如,免费订单,半价订单等,下面是项目结构:

一 策略接口和实现

/**
* 处理订单策略
*/
public interface OrderStrategy { void handleOrder(Order order);
}
@Component
@HandlerOrderType(Order.FREE) //使用注解标明策略类型
public class FreeOrderStrategy implements OrderStrategy {
@Override
public void handleOrder(Order order) {
System.out.println("----处理免费订单----");
}
}
@Component
@HandlerOrderType(Order.HALF)
public class HalfOrderStrategy implements OrderStrategy {
@Override
public void handleOrder(Order order) {
System.out.println("----处理半价订单----");
}
}
@Component
@HandlerOrderType(Order.DISCOUT)
public class DiscoutOrderStrategy implements OrderStrategy {
@Override
public void handleOrder(Order order) {
System.out.println("----处理打折订单----");
}
}

二 自定义策略注解

@Target(ElementType.TYPE)  //作用在类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited //子类可以继承此注解
public @interface HandlerOrderType {
/**
* 策略类型
* @return
*/
int value();
}

此处只能用基本类型或者String,约定的类型放在Order实体类里

三 业务实体

public class Order {
public static final int FREE=1; //免费订单
public static final int HALF=2; //半价订单
public static final int DISCOUT=3; //打折订单
private String name;
private Double price;
private Integer type;//订单类型
public static Order build(){
return new Order();
}

四 核心功能实现

主要就是这一块实现策略逻辑

/**
* 根据订单类型返回对应的处理策略
*/
@Component
public class HandlerOrderContext {
@Autowired
private ApplicationContext applicationContext;
//存放所有策略类Bean的map
public static Map<Integer, Class<OrderStrategy>> orderStrategyBeanMap= new HashMap<>(); public OrderStrategy getOrderStrategy(Integer type){
Class<OrderStrategy> strategyClass = orderStrategyBeanMap.get(type);
if(strategyClass==null) throw new IllegalArgumentException("没有对应的订单类型");
//从容器中获取对应的策略Bean
return applicationContext.getBean(strategyClass);
}
}
/**
* 策略核心功能,获取所有策略注解的类型
* 并将对应的class初始化到HandlerOrderContext中
*/
@Component
public class HandlerOrderProcessor implements ApplicationContextAware {
/**
* 获取所有的策略Beanclass 加入HandlerOrderContext属性中
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//获取所有策略注解的Bean
Map<String, Object> orderStrategyMap = applicationContext.getBeansWithAnnotation(HandlerOrderType.class);
orderStrategyMap.forEach((k,v)->{
Class<OrderStrategy> orderStrategyClass = (Class<OrderStrategy>) v.getClass();
int type = orderStrategyClass.getAnnotation(HandlerOrderType.class).value();
//将class加入map中,type作为key
HandlerOrderContext.orderStrategyBeanMap.put(type,orderStrategyClass);
});
}
}

五 业务service使用

@Component
public class OrderServiceImpl implements OrderService {
@Autowired
HandlerOrderContext handlerOrderContext;
@Override
public void handleOrder(Order order) {
//使用策略处理订单
OrderStrategy orderStrategy = handlerOrderContext.getOrderStrategy(order.getType());
orderStrategy.handleOrder(order);
}
}

很简单,业务代码以后基本不用再修改,不管添加多少策略或者需求变更多少次

六 controller测试

@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
OrderService orderService;
@GetMapping("/handler/{type}")
public void handleOrder(@PathVariable Integer type){
Order order = Order.build()
.add("name", "微信订单")
.add("price", 99.9)
.add("type", type);
orderService.handleOrder(order);
}
}

使用链式风格构造对象

测试:

再添加策略添加实现类,启用注解即可!

省去了工厂模式,直接用注解实现,避免修改工厂类,

这里贴一个我们之前项目的工厂类实现:

如果再添加策略还是会有轻微的改动!

springboot中使用自定义注解实现策略模式,去除工厂模式的switch或ifelse,实现新增策略代码零修改的更多相关文章

  1. Springboot中如何自定义注解以及使用2例

    不说废话,直接进入正题: java自定义注解主要有3步:1.编写@interface接口2.编写@interface对应的处理方法进行处理3.调用处理方法 示例一:判断奇偶:比如有一个字段no要判断奇 ...

  2. springboot中的常用注解

    springboot中的常用注解个人觉得springboor中常用的注解主要可以分为三种:放入容器型注解.从容器中取出型注解和功能型注解.其中的放入容器型和从容器中取出型就是我们平时所说的控制反转和依 ...

  3. springboot中的controller注解没有生效

    springboot中的controller注解没有生效  , 启动的Application类没有在controller的父目录或同级目录

  4. Java中的GOF23(23中设计模式)--------- 工厂模式(Factory)

    Java中的GOF23(23中设计模式)--------- 工厂模式(Factory) 在给大家介绍工厂模式之前,我想和大家聊聊面向对象的那点事,在这里,引入三个概念. 开闭原则(Open Close ...

  5. python 使用模板模式和工厂模式的混合设计开发各种邮件客户端发送邮件

    1.使用模板模式和工厂模式的混合设计开发各种邮件客户端发送邮件. 2.模板模式的目的:能保证快速开发各种邮箱客户端,子类只需要重写模板类邮箱的抽象方法即可.之后再开发任何邮箱就只要加一个类,写3行代码 ...

  6. javascript模式 (3)——工厂模式和装饰模式

    上节我们讲解了单例模式,这节我们将继续讲解工厂模式和迭代器模式 工厂模式: 工厂模式的目的是为了方便的创建对象(可以在不知道构造的情况下),通过静态方法来实现,在java或c#等静态编译语言中需要通过 ...

  7. 结合实例分析简单工厂模式&工厂方法模式&抽象工厂模式的区别

    之前写过一篇关于工厂模式(Factory Pattern)的随笔,里面分析了简单工厂模式,但对于工厂方法和抽象工厂的分析较为简略.这里重新分析分析三者的区别,工厂模式是java设计模式中比较简单的一个 ...

  8. 简单工厂模式,工厂方法模式,抽象工厂模式,spring的狂想

    菜鸟D在项目中遇见一个比较纠结的高耦合,所以就想办法来解耦.情况是这样的:系统通过用户选择treeview控件的节点判断调用不同的处理,这些处理中某些东西又是类似的.同事的建议是采用简单工厂,耦合就耦 ...

  9. Java设计模式之(工厂模式)--简单工厂模式--工厂方法模式--抽象工厂模式

    工厂模式: 工厂模式可以分为三类: 1)简单工厂模式(Simple Factory) 2)工厂方法模式(Factory Method) 3)抽象工厂模式(Abstract Factory) 简单工厂模 ...

随机推荐

  1. $vjudge-dp$专题题解

    因为感觉题解写不了多少,,,就懒得一道道题目慢慢写了,汇总了算了$QAQ$ 昂然后因为我估计以后还会有些什么$dp$专题啊$balabala$的,,,然后谢总肯定又会建一堆小组啥的,,,所以还是放个链 ...

  2. 什么是Ceph存储?什么是分布式存储?简单明了带你学Ceph--<1>

    Ceph存储介绍 为什么要用Ceph Ceph是当前非常流行的开源分布式存储系统,具有高扩展性.高性能.高可靠性等优点,同时提供块存储服务(rbd).对象存储服务(rgw)以及文件系统存储服务(cep ...

  3. apache相关实验-2

    一.Apache+openssl 实现 https HTTPS(全称:Hypertext Transfer Protocol Secure,超文本传输安全协议),是以安全为目标的 HTTP 通道,简单 ...

  4. 关于Integer 和Double包装类创建对象时的底层解析

    public void method1() { Integer i = new Integer(1); Integer j = new Integer(1); System.out.println(i ...

  5. Linux学习_菜鸟教程_4

    Linux远程登录 已经了解了登录流程,学会了用SecureCRT进行操作 Linux文件基本属性 Linux为保护系统安全,对不同的用户,开放不同的文件访问权限. 在linux中,我们可以使用ll或 ...

  6. PS/2的相关知识

    PS/2接口 很多微机上采用PS/2口来连接鼠标和键盘.PS/2接口与传统的键盘接口除了在接口外型.引脚有不同外,在数据传送格式上是相同的.现在很多主板用PS/2接口插座连接键盘,传统接口的键盘可以通 ...

  7. ffmpeg 视频合并

    /// <summary> /// 视频合并 /// </summary> /// <param name="File1">第一个视频地址< ...

  8. Spring-cloud微服务实战【二】:eureka注册中心(上)

    ## 前言   本系列教程旨在为大家演示如何一步一步构建一整套微服务系统,至于其中的数据库用什么,订单ID如何保持唯一,分布式相关问题等等不在我们讨论范围内,本教程为了方便大家后续下载代码运行测试,不 ...

  9. BFS - 求最短路径

    Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. ...

  10. 盘一盘Tidyverse| 筛行选列之select,玩转列操作

    原文链接:https://mp.weixin.qq.com/s/ldO0rm3UM_rqlFnU3euYaA 2020年,开封 <R 数据科学>R for data science,系统学 ...