设计模式 -- 策略模式+Spring Bean代替if/else

简介: 策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

设计模式 -- 策略模式+Spring Bean代替if/else

在这里插入图片描述

策略模式

一、什么是策略模式

  •  策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

二、策略模式的结构

  • 策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。下面就以一个示意性的实现讲解策略模式实例的结构。

在这里插入图片描述
这个模式涉及到三个角色:

  ●  环境(Context)角色:持有一个Strategy的引用。

  ●  抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

  ●  具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

使用策略模式完美的解决了我们if else 太多导致代码臃肿的问题 如:

if(teachinType == 1){
……

}else if(teachinType == 2){
……
        
}else{
            
}

三、实战

介绍:在我们项目实战中,我们通常会遇到 我们后台拿到前端传来的参数走不同的逻辑 (线上 ,线下 业务 ) ,返回相同的数据结构:

if(teachinType == 1){
……
return list<Integer>;

}else if(teachinType == 2){
……
return list<Integer>;
 
}else{
……
return list<Integer>;        
}

普通策略模式

  1. 定义接口
public interface Type {

    /**
     * 获取类型,返回集合
     */
    List<Integer> getType();

}
  1. 定义OfflineType实现类实现Type
@Service
public class OfflineType implements Type {

    @Override
    public List<Integer> getType() {
    List<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    return list;
    }
}
  1. 定义OnlineType实现类 实现Type接口
@Service
public class OnlineType implements Type {

    @Override
    public List<Integer> getType() {
    List<Integer> list = new ArrayList<>();
    list.add(3);
    list.add(4);
    return list;
    }
}
  1. 定义策略工厂类
public class TypeFactory{

    private static TypeFactory typeFactory = new TypeFactory();
    
    //定义Map
    private static Map<Integer,Type> map = new HashMap<>();
    
    static{
        map.put(1,new OfflineType());
        map.put(2,new OnlineType())
        }

    public static TypeFactory getInstance(){
            return typeFactory;
            }

    public Type getByType(Integer type){
        return map.get(type);
    }
}
  1. 使用

@GetMapping("list")
public List<Integer> list(@ApiParam(value ="类型")@RequestParam(required = false) Integer type) {
    return TypeFactory.getInstance().getByType(type).getType();
);

接口测试输入1,输出 1,2
接口测试输入2,输出 3,4

策略模式+Spring Bean代替if/else

  1. 在上面策略模式中如果在实现类中使用
 @Autowired
 private Dao dao;

就会出现 空指针的情况,

java.lang.NullPointerException

因为 发现策略实现中的Dao接口注入的都是Null。

我们回头看spring源码 以及 他的介绍

  • 必须在所有使用了dao的地方,包括调用它的servcie都要进行@Autowired注入,否则之后的注入就会失败
  • 顺着这句话,发现上述使用处不就没使用@Autowired进行注入吗?但是这个策略模式得new啊?
  • 我们还有其他方式:通过给实现类起别名,通过@Qualifier注解获取不同的实现类

改造:

实现类

@Service("offlineType")
public class OfflineType implements Type {

    @Autowired
    private OfflineDao dao;

    @Override
    public List<Integer> getType() {
    return dao.selectList();
    }
}

实现类

@Service("onlineType")
public class OnlineType implements Type {

    @Autowired
    private OnlineDao dao;
    
    @Override
    public List<Integer> getType() {
  
    return dao.selectList();
    }
}

工厂

public class TypeFactory{

    @Resource
    @Qualifier("offlineType")
    private  OnlineType offlineType;

    @Resource
    @Qualifier("onlineType")
    private  OnlineType onlineType;

    
    public  Type getByType(Integer type){
        Map<Integer, Type> map =new HashMap<>();
        map.put(1,offlineType);
        map.put(2,onlineType);
        return map.get(type);
    }
}

使用

    //    工厂注入
    @Autowired
    private TypeFactory typeFactory;

@GetMapping("list")
public List<Integer> list(@ApiParam(value ="类型")@RequestParam(required = false) Integer type) {
    return typeFactory.getByType(type).getType();
);

发现 不会出现空指针,IOC正常注入,数据正常返回
在这里插入图片描述
在这里插入图片描述

相关文章
|
11天前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
11天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
36 2
|
1月前
|
XML Java 数据格式
Spring从入门到入土(bean的一些子标签及注解的使用)
本文详细介绍了Spring框架中Bean的创建和使用,包括使用XML配置文件中的标签和注解来创建和管理Bean,以及如何通过构造器、Setter方法和属性注入来配置Bean。
66 9
Spring从入门到入土(bean的一些子标签及注解的使用)
|
29天前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
1月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文通过游泳运动员的案例,介绍策略模式及其在Kotlin中的改良应用,利用高阶函数简化代码结构,提高灵活性。
30 3
|
1月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文介绍策略模式在Kotlin中的应用,通过游泳运动员的例子,展示如何使用接口和高阶函数实现策略模式,使代码更简洁、灵活。
28 2
|
1月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
62 3
|
1月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
27 3
|
1月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
【10月更文挑战第9天】 策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在PHP开发中,通过使用策略模式,我们可以轻松切换算法或逻辑处理方式而无需修改现有代码结构。本文将深入探讨策略模式的定义、结构以及如何在PHP中实现该模式,并通过实际案例展示其应用价值和优势。
29 1
|
1月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与应用
【10月更文挑战第8天】 在软件开发的浩瀚宇宙中,设计模式如同星辰指引,照亮了代码设计与架构的航道。本文旨在深入探索PHP语境下策略模式(Strategy Pattern)的精髓,不仅剖析其内核原理,还将其融入实战演练,让理论在实践中生根发芽。策略模式,作为解决“如何优雅地封装算法族”的答案,以其独特的灵活性与扩展性,赋予PHP应用以动态变换行为的能力,而无需牵动既有的类结构。
24 2

热门文章

最新文章

  • 1
    C++一分钟之-设计模式:工厂模式与抽象工厂
    43
  • 2
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    46
  • 3
    C++一分钟之-C++中的设计模式:单例模式
    54
  • 4
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    38
  • 5
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    62
  • 6
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    57
  • 7
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    41
  • 8
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    50
  • 9
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    106
  • 10
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    78