Spring与设计模式实战之策略模式

news/2024/8/26 14:02:07 标签: spring, 设计模式, 策略模式

Spring与设计模式实战之策略模式

引言

在现代软件开发中,设计模式是解决常见设计问题的有效工具。它们提供了经过验证的解决方案,帮助开发人员构建灵活、可扩展和可维护的系统。本文将探讨策略模式在Spring框架中的应用,并通过实际例子展示如何通过Spring的特性来实现和管理策略模式

1. 策略模式(Strategy Pattern)的概述

策略模式是一种行为型设计模式,它允许定义一系列算法,并将每个算法封装起来,使它们可以互换。这种模式让算法的变化独立于使用算法的客户。在Java中,策略模式通常通过接口和它们的实现类来实现。

1.1 策略模式的结构

  • 策略接口:声明了所有具体策略类都必须实现的操作。
  • 具体策略类:实现了策略接口,定义了具体的算法。
  • 上下文类:维护一个对策略对象的引用,并在需要时调用策略对象的方法。

2. ApplicationContextAware接口的介绍

在Spring框架中,ApplicationContext是一个非常核心的概念。它代表Spring IoC容器,负责实例化、配置和管理Beans。通过实现ApplicationContextAware接口,Spring Bean可以访问Spring的ApplicationContext,从而获取其他Beans或上下文信息。

2.1 ApplicationContextAware的使用

当一个Bean实现ApplicationContextAware接口时,Spring会在初始化该Bean时自动调用其setApplicationContext方法,并传入ApplicationContext实例。这样,该Bean就可以使用这个上下文来获取其他Beans或与Spring容器交互。

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class MyBean implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    public void doSomething() {
        // 使用applicationContext获取其他Bean
        AnotherBean anotherBean = applicationContext.getBean(AnotherBean.class);
        anotherBean.performTask();
    }
}

3. StrategyFactory的设计与实现

StrategyFactory是一个策略工厂类,负责根据业务需求创建和提供策略实例。它使用自定义的@TradeStrategy注解来识别和创建具体的策略类实例。

3.1 自定义注解@TradeStrategy

我们首先定义一个自定义注解@TradeStrategy,用于标注具体的策略类。这个注解可以在运行时通过反射机制进行处理。

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TradeStrategy {
    String value();
}

3.2 StrategyFactory的实现

StrategyFactory使用Spring的ApplicationContext来动态地获取所有添加了@TradeStrategy注解的Beans,并根据业务编码获取具体的策略类实例。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

@Component
public class StrategyFactory {

    @Autowired
    private ApplicationContext applicationContext;

    private Map<String, ITradeStrategy> strategyMap = new HashMap<>();

    @PostConstruct
    public void init() {
        Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(TradeStrategy.class);
        for (Object bean : beansWithAnnotation.values()) {
            TradeStrategy tradeStrategy = bean.getClass().getAnnotation(TradeStrategy.class);
            strategyMap.put(tradeStrategy.value(), (ITradeStrategy) bean);
        }
    }

    public ITradeStrategy getStrategy(String code) {
        return strategyMap.get(code);
    }
}

4. TradeStrategyContext的角色

TradeStrategyContext充当策略上下文的角色,提供获取策略实例的方法。它包含一个tradeStrategyMap,用于存储策略枚举和对应的策略实现。

4.1 TradeStrategyContext的实现

TradeStrategyContext依赖于StrategyFactory来获取策略实例,并提供一个统一的方法来执行策略。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class TradeStrategyContext {

    @Autowired
    private StrategyFactory strategyFactory;

    public void executeStrategy(String code) {
        ITradeStrategy strategy = strategyFactory.getStrategy(code);
        if (strategy != null) {
            strategy.process();
        } else {
            throw new IllegalArgumentException("No strategy found for code: " + code);
        }
    }
}

5. ITradeStrategy接口及其实现

ITradeStrategy是一个策略接口,声明了一个process方法,所有具体策略类都需要实现这个接口。

5.1 ITradeStrategy接口

public interface ITradeStrategy {
    void process();
}

5.2 具体策略类的实现

以下是几个具体策略类的实现示例:

import org.springframework.stereotype.Component;

@TradeStrategy("apply")
@Component
public class ApplyServiceStrategy implements ITradeStrategy {
    @Override
    public void process() {
        System.out.println("Processing apply service strategy");
    }
}

@TradeStrategy("redeem")
@Component
public class RedeemServiceStrategy implements ITradeStrategy {
    @Override
    public void process() {
        System.out.println("Processing redeem service strategy");
    }
}

@TradeStrategy("convert")
@Component
public class CovertServiceStrategy implements ITradeStrategy {
    @Override
    public void process() {
        System.out.println("Processing convert service strategy");
    }
}

@TradeStrategy("withdraw")
@Component
public class WithDrawServiceStrategy implements ITradeStrategy {
    @Override
    public void process() {
        System.out.println("Processing withdraw service strategy");
    }
}

6. TradeController的设计

TradeController是交易请求的统一入口,提供了一个tradeIndex方法来处理交易请求。它使用TradeStrategyContext来获取并执行相应的策略。

6.1 TradeController的实现

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TradeController {

    @Autowired
    private TradeStrategyContext tradeStrategyContext;

    @GetMapping("/trade")
    public String tradeIndex(@RequestParam String code) {
        tradeStrategyContext.executeStrategy(code);
        return "Trade executed successfully for strategy: " + code;
    }
}

7. 策略的动态加载与维护

通过Spring的ApplicationContextStrategyFactory可以动态地获取所有添加了@TradeStrategy注解的Beans,并根据业务编码获取具体的策略类实例。这使得系统在添加新的策略时,只需要添加新的策略类并标注@TradeStrategy注解即可,无需修改现有代码。

8. 策略的扩展性

通过自定义注解和策略工厂,系统可以很容易地添加新的策略,而不需要修改现有的代码,提高了系统的扩展性。例如,当需要添加一个新的交易策略时,只需要创建一个新的策略类并标注@TradeStrategy注解,然后在需要时通过业务编码来调用该策略。

8.1 添加新策略的示例

@TradeStrategy("newStrategy")
@Component
public class NewServiceStrategy implements ITradeStrategy {
    @Override
    public void process() {
        System.out.println("Processing new service strategy");
    }
}

总结

策略模式在Spring框架中的应用展示了设计模式的强大和灵活性。通过自定义注解和Spring的ApplicationContext,我们可以实现策略的动态管理和扩展。这种方法不仅提高了代码的可维护性,还增强了系统的可扩展性。在实际项目中,合理地应用设计模式和Spring特性,可以显著提升系统的设计质量和开发效率。

附一张基金代销渠道订单处理流程图
在这里插入图片描述


http://www.niftyadmin.cn/n/5558188.html

相关文章

单例模式-C#

在C#中实现单例模式&#xff0c;主要目的是确保一个类仅有一个实例&#xff0c;并提供一个全局访问点来获取这个实例。以下是一个简单的单例模式实现示例&#xff0c;它使用了一个私有静态变量来保存类的唯一实例&#xff0c;并提供了一个公有的静态方法来获取这个实例。此外&a…

Telegram Bot、小程序开发(三)Mini Apps小程序

文章目录 一、Telegram Mini Apps小程序二、小程序启动方式三、小程序开发小程序调试模式初始化小程序Keyboard Button Mini Apps 键盘按钮小程序【依赖具体用户信息场景,推荐】**Inline Button Mini Apps内联按钮小程序**initData 的自动传递使用内联菜单时候哪些参数会默认传…

构建未来智能边缘:4G定制化ARM边缘计算网关解决方案

在当今数字化转型的时代背景下&#xff0c;边缘计算正成为连接物理世界与数字世界的关键桥梁&#xff0c;为企业提供实时数据处理和决策能力。为了满足市场对高性能、灵活且可定制的边缘计算解决方案的需求&#xff0c;一款专为各类品牌量身定制的ARMxy边缘计算网关 产品亮点&…

E: Unable to locate package google-chrome-stable_current_amd64.deb

意思是我无法定位到google-chrome-stable_current_amd64.deb 我提前下载好了文件 我执行的命令为: apt install google-chrome-stable_current_amd64.deb 这个是先定位网络资源&#xff0c;然后现在安装。我是已经下载好了。 所以执行一下命令: apt install ./google-chro…

通过手机控制家用电器的一个程序的设计(一)

一、概述 设计一款安卓平台上的家庭智能控制软件&#xff0c;通过语音识别指令控制家用电器。该软件结合离线语音识别技术、红外线和WIFI通讯技术&#xff0c;实现对家电的智能控制&#xff0c;如开关机、调温度、调频道等操作。 二、主要功能模块 离线语音识别模块 功能&…

Web前端-Web开发CSS基础5-浮动

一. 基础 1. 设置<div>元素的宽为100像素&#xff0c;高也为100像素&#xff0c;并且向左悬浮&#xff1b; 2. 设置<div>元素的宽为100像素&#xff0c;高也为100像素&#xff0c;并且向右悬浮&#xff1b; 3. 设置<img>元素向左悬浮&#xff1b; 4. 设置<…

基于STM32的无人机控制系统:硬件选择与软件实现(内附资料)

无人机&#xff08;Unmanned Aerial Vehicle, UAV&#xff09;在现代应用中越来越广泛&#xff0c;从军事侦察到民用物流&#xff0c;无人机技术的发展不断推动着相关硬件和软件的进步。STM32系列微控制器以其高性能、低功耗和丰富的外设接口&#xff0c;成为无人机控制系统的理…

第一阶段面试题总结

1. 线程和进程的概念&#xff0c;区别、以及什么时候用线程什么时候用进程 1.1 线程概念 线程是进程中的一个执行单元&#xff0c;一个进程可以包含多个线程 线程是一个轻量级的进程 线程是CPU任务调度的最小单元 1.2 进程概念 进程是一个程序的运行实例&#xff0c;它包含了…