使用spring插件实现策略模式


策略模式是一种行为设计模式,可让您定义一系列算法/实现并允许在运行时选择它们。  
假设我们有一个支持不同支付类型的支付服务,如信用卡、贝宝、条纹等。我们想根据用户请求决定使用哪种支付方式。让我们开始实施。
 
添加spring插件依赖:

<dependency> 
  <groupId> org.springframework.plugin </groupId> 
  <artifactId> spring-plugin-核心</artifactId> 
  <version> 2.0.0.RELEASE </version>
</dependency> 

支付插件代码:

import org.springframework.plugin.core.Plugin;

public interface PaymentPlugin extends Plugin<PaymentMethod> {

  void pay(int paymentAmount);

}

PaymentPlugin 接口是我们定义合约的基本接口。这里我们需要扩展插件并传递一个类类型作为用于解析插件(实现)的类型参数。
这里 PaymentMethod 是一个枚举,它包含不同类型的支付方式。
我们来看看Spring插件的
Plugin
内部接口:
package org.springframework.plugin.core;
public interface Plugin<S> {
  boolean supports(S var1);
}

下面是 PaymentPlugin对其的一种实现:


import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class PayByPaypal implements PaymentPlugin {

  @Override
  public void pay(int paymentAmount) {
    log.info("Paid by paypal, amount: " + paymentAmount);
  }

  @Override
  public boolean supports(PaymentMethod paymentMethod) {
    return paymentMethod == PaymentMethod.PAYPAL;
  }
}

我们必须覆盖 pay 方法和 support 方法,pay 方法包含需要执行的算法/业务逻辑,支持插件接口附带的方法决定是否应该根据给定的分隔符调用插件(在我们的例子中为 PaymentPlugin) . 我添加了另一个类 PayByCard 来模拟通过卡功能支付。接下来我们将使用一个服务类来注册我们的插件并使用它。

package com.rkdevblog.plugin;

import java.util.Optional;

import org.springframework.plugin.core.PluginRegistry;
import org.springframework.plugin.core.config.EnablePluginRegistries;
import org.springframework.stereotype.Service;

import lombok.RequiredArgsConstructor;

@Service
@EnablePluginRegistries(PaymentPlugin.class)
@RequiredArgsConstructor
public class PaymentService {

  private final PluginRegistry<PaymentPlugin, PaymentMethod> plugins;

  public PaymentPlugin choosePaymentMethod(PaymentMethod paymentMethod) {

    Optional<PaymentPlugin> pluginFor = plugins.getPluginFor(paymentMethod);
    if (pluginFor.isPresent()) {
      return pluginFor.get();
    }
    throw new UnsupportedOperationException("No such payment method");
  }
  
}

在服务类中,我们通过使用@EnablePluginRegistries 为配置的插件类型启用 PluginRegistry 实例,注入 PluginRegistry 并使用它通过传递 PaymentMethod 来选择插件,PaymentMethod 将相应地返回 PaymentPlugin 的实例。
 
现在让我们运行应用程序并查看,在主类中调用 PaymentService 并传递您需要的 PaymentMethod 并检查日志输出。 
测试PaymentMethod Card :
@Bean
ApplicationRunner runner(PaymentService paymentService) {
  return args -> {
    PaymentPlugin paymentPlugin = paymentService.choosePaymentMethod(PaymentMethod.CARD);

    paymentPlugin.pay(10);
  };
}

 
测试PaymentMethod Paypal:

@Bean
ApplicationRunner runner(PaymentService paymentService) {
  return args -> {
    PaymentPlugin paymentPlugin = paymentService.choosePaymentMethod(PaymentMethod.PAYPAL);

    paymentPlugin.pay(10);
  };
}

 
代码下载:https://github.com/Rajithkonara/spring-plugin