引言
在许多电子商务系统中,集成多个支付网关是常见的需求。不同的支付网关有着不同的接口和实现细节。适配器模式可以帮助我们以一种灵活的方式实现这些不同的支付网关接口。
适配器模式简介
适配器模式将一个类的接口转换为客户期望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
示例
假设我们有一个电商平台,需要支持多种支付网关,包括:
- PayPal支付网关
- Stripe支付网关
- Alipay支付网关
步骤
-
定义目标接口 - 首先定义一个目标接口,声明所有支持的支付网关共有的方法。
java深色版本
1public interface PaymentGateway { 2 void processPayment(PaymentRequest request); 3}
-
实现具体的支付网关类 - 接下来,为每种支付网关实现适配器。
-
PayPal支付网关适配器
java深色版本
1import org.springframework.stereotype.Component; 2 3@Component 4public class PayPalPaymentGatewayAdapter implements PaymentGateway { 5 private final PayPalApi paypalApi; 6 7 public PayPalPaymentGatewayAdapter(PayPalApi paypalApi) { 8 this.paypalApi = paypalApi; 9 } 10 11 @Override 12 public void processPayment(PaymentRequest request) { 13 PayPalPaymentRequest paypalRequest = new PayPalPaymentRequest(request); 14 paypalApi.processPayment(paypalRequest); 15 } 16}
-
Stripe支付网关适配器
java深色版本
1import org.springframework.stereotype.Component; 2 3@Component 4public class StripePaymentGatewayAdapter implements PaymentGateway { 5 private final StripeApi stripeApi; 6 7 public StripePaymentGatewayAdapter(StripeApi stripeApi) { 8 this.stripeApi = stripeApi; 9 } 10 11 @Override 12 public void processPayment(PaymentRequest request) { 13 StripePaymentRequest stripeRequest = new StripePaymentRequest(request); 14 stripeApi.processPayment(stripeRequest); 15 } 16}
-
Alipay支付网关适配器
java深色版本
1import org.springframework.stereotype.Component; 2 3@Component 4public class AlipayPaymentGatewayAdapter implements PaymentGateway { 5 private final AlipayApi alipayApi; 6 7 public AlipayPaymentGatewayAdapter(AlipayApi alipayApi) { 8 this.alipayApi = alipayApi; 9 } 10 11 @Override 12 public void processPayment(PaymentRequest request) { 13 AlipayPaymentRequest alipayRequest = new AlipayPaymentRequest(request); 14 alipayApi.processPayment(alipayRequest); 15 } 16}
-
-
定义具体的支付网关 API 接口 - 为每个支付网关定义一个具体的 API 接口。
-
PayPal API 接口
java深色版本
1public interface PayPalApi { 2 void processPayment(PayPalPaymentRequest request); 3}
-
Stripe API 接口
java深色版本
1public interface StripeApi { 2 void processPayment(StripePaymentRequest request); 3}
-
Alipay API 接口
java深色版本
1public interface AlipayApi { 2 void processPayment(AlipayPaymentRequest request); 3}
-
-
实现具体的支付网关 API 类 - 接下来,为每个支付网关实现具体的 API 类。
-
PayPal API 类
java深色版本
1import org.springframework.stereotype.Component; 2 3@Component 4public class PayPalApiImpl implements PayPalApi { 5 @Override 6 public void processPayment(PayPalPaymentRequest request) { 7 System.out.println("Processing payment via PayPal: " + request.getAmount()); 8 } 9}
-
Stripe API 类
java深色版本
1import org.springframework.stereotype.Component; 2 3@Component 4public class StripeApiImpl implements StripeApi { 5 @Override 6 public void processPayment(StripePaymentRequest request) { 7 System.out.println("Processing payment via Stripe: " + request.getAmount()); 8 } 9}
-
Alipay API 类
java深色版本
1import org.springframework.stereotype.Component; 2 3@Component 4public class AlipayApiImpl implements AlipayApi { 5 @Override 6 public void processPayment(AlipayPaymentRequest request) { 7 System.out.println("Processing payment via Alipay: " + request.getAmount()); 8 } 9}
-
-
定义支付请求类 - 定义一个支付请求类,用于封装支付请求的必要信息。
java深色版本
1public class PaymentRequest { 2 private String paymentMethod; 3 private double amount; 4 5 public PaymentRequest(String paymentMethod, double amount) { 6 this.paymentMethod = paymentMethod; 7 this.amount = amount; 8 } 9 10 public String getPaymentMethod() { 11 return paymentMethod; 12 } 13 14 public double getAmount() { 15 return amount; 16 } 17}
-
定义具体的支付请求类 - 为每个支付网关定义一个具体的支付请求类。
-
PayPal支付请求
java深色版本
1public class PayPalPaymentRequest { 2 private final PaymentRequest request; 3 4 public PayPalPaymentRequest(PaymentRequest request) { 5 this.request = request; 6 } 7 8 public String getPaymentMethod() { 9 return request.getPaymentMethod(); 10 } 11 12 public double getAmount() { 13 return request.getAmount(); 14 } 15}
-
Stripe支付请求
java深色版本
1public class StripePaymentRequest { 2 private final PaymentRequest request; 3 4 public StripePaymentRequest(PaymentRequest request) { 5 this.request = request; 6 } 7 8 public String getPaymentMethod() { 9 return request.getPaymentMethod(); 10 } 11 12 public double getAmount() { 13 return request.getAmount(); 14 } 15}
-
Alipay支付请求
java深色版本
1public class AlipayPaymentRequest { 2 private final PaymentRequest request; 3 4 public AlipayPaymentRequest(PaymentRequest request) { 5 this.request = request; 6 } 7 8 public String getPaymentMethod() { 9 return request.getPaymentMethod(); 10 } 11 12 public double getAmount() { 13 return request.getAmount(); 14 } 15}
-
-
使用适配器 - 最后,在我们的业务逻辑中,根据需要选择并使用相应的适配器。
java深色版本
1import org.springframework.beans.factory.annotation.Autowired; 2import org.springframework.stereotype.Service; 3 4@Service 5public class PaymentService { 6 7 private final Map<String, PaymentGateway> paymentGateways; 8 9 @Autowired 10 public PaymentService(Map<String, PaymentGateway> paymentGateways) { 11 this.paymentGateways = paymentGateways; 12 } 13 14 public void processPayment(PaymentRequest request) { 15 PaymentGateway paymentGateway = paymentGateways.get(request.getPaymentMethod()); 16 if (paymentGateway != null) { 17 paymentGateway.processPayment(request); 18 } else { 19 throw new IllegalArgumentException("Unsupported payment method: " + request.getPaymentMethod()); 20 } 21 } 22}
-
控制器 - 我们还需要一个控制器来测试这个逻辑。
java深色版本
1import org.springframework.beans.factory.annotation.Autowired; 2import org.springframework.web.bind.annotation.GetMapping; 3import org.springframework.web.bind.annotation.RequestMapping; 4import org.springframework.web.bind.annotation.RequestParam; 5import org.springframework.web.bind.annotation.RestController; 6 7@RestController 8@RequestMapping("/payments") 9public class PaymentController { 10 11 private final PaymentService paymentService; 12 13 @Autowired 14 public PaymentController(PaymentService paymentService) { 15 this.paymentService = paymentService; 16 } 17 18 @GetMapping("/process") 19 public String processPayment(@RequestParam("method") String method, 20 @RequestParam("amount") double amount) { 21 PaymentRequest request = new PaymentRequest(method, amount); 22 paymentService.processPayment(request); 23 return "Payment processed successfully."; 24 } 25}
-
测试 - 最后,我们可以通过发送 HTTP 请求来测试不同的支付网关。
bash深色版本
1curl 'http://localhost:8080/payments/process?method=paypal&amount=100' 2curl 'http://localhost:8080/payments/process?method=stripe&amount=150' 3curl 'http://localhost:8080/payments/process?method=alipay&amount=200'
结论
通过使用适配器模式,我们可以在运行时灵活地选择不同的支付网关,并使用统一的接口与之交互。这种方式不仅提高了代码的可读性和可维护性,还使得扩展新的支付网关变得非常简单。在 Spring Boot 中,依赖注入机制进一步简化了适配器模式的实现过程。