ps:以下示例仅供参考,设计模式只是一种思想,至于怎么千变万化就看大家了。
一、背景
面试官:你们项目的支付场景用了哪些设计模式,为什么要这么做?
二、方案
- 使用策略模式定义不同支付方式的具体支付策略,每种支付方式对应一个策略类。
- 使用工厂模式创建支付对象,将具体的逻辑封装在工厂类中,工厂类根据不同的支付方式创建相应的支付对象。
- 使用模板模式定义支付流程的通用框架,将整个支付流程抽象成一个模板方法,定义一系列步骤,然后具体的支付方式实现这个模板方法,并完成各自特定的支付逻辑。
三、UML类图
四、代码实现
4.1 Payment——支付接口
定义支付的基本行为。(ps:需要入参加上入参即可)
/**
* @author Created by njy on 2023/7/16
* 支付接口
*/
public interface Payment {
//校验参数
void validatePayment();
//发起请求
void executePayment();
//处理结果
void processPaymentResult();
String getType();
}
4.2 Alipay、WeChatPay——支付具体策略
/**
* @author Created by njy on 2023/7/16
* 支付宝支付
*/
@Component
public class Alipay implements Payment {
@Override
public void validatePayment() {
// 验证支付宝支付参数
System.out.println("验证支付宝支付请求参数。。。");
}
@Override
public void executePayment() {
// 发送支付宝支付请求
System.out.println("发起支付宝支付请求。。。。");
}
@Override
public void processPaymentResult() {
// 处理支付宝支付结果
System.out.println("正在处理支付结果。。。");
}
@Override
public String getType() {
return "Alipay";
}
}
/**
* @author Created by njy on 2023/7/16
* 微信支付
*/
@Component
public class WechatPay implements Payment{
@Override
public void validatePayment() {
// 验证支付宝支付参数
System.out.println("验证微信支付请求参数。。。");
}
@Override
public void executePayment() {
// 发送支付宝支付请求
System.out.println("发起微信支付请求。。。。");
}
@Override
public void processPaymentResult() {
// 处理支付宝支付结果
System.out.println("正在处理支付结果。。。");
}
@Override
public String getType() {
return "WeChatPay";
}
}
4.3 PaymentFactory——支付工厂
创建具体的支付对象。
/**
* @author Created by njy on 2023/7/16
* 支付工厂
*/
@Component
public class PaymentFactory {
private List<Payment> payments;
private static final Map<String, Payment> paymentMap = new ConcurrentHashMap<>();
//项目启动时把支付类型和对应的payment放入map中
@PostConstruct
protected void init() {
if (payments != null) {
payments.forEach(payment -> paymentMap.put(payment.getType(), payment));
}
}
public Payment select(String payType) {
Payment payment = paymentMap.get(payType);
if (null == payment) {
throw new IllegalArgumentException("Invalid payment method");
}
return payment;
}
@Autowired
public void setpayments(List<Payment> payments) {
this.payments = payments;
}
}
4.4 PaymentTemplate——抽象模板
定义了支付流程的通用框架。
/**
* @author Created by njy on 2023/7/17
* 支付模板
*/
public abstract class PaymentTemplate {
//模板方法
public void processPayment() {
Payment payment = selectPay();
//验证参数
payment.validatePayment();
//发起请求
payment.executePayment();
//结果处理
payment.processPaymentResult();
if (isReceipt()) {
System.out.println(payment.getType()+"支付,开具小票。。。。");
}else {
System.out.println(payment.getType()+"支付,不开小票");
}
//do something:支付后的操作,例如成功或失败后的回调
}
//抽象方法
public abstract Payment selectPay();
//钩子方法:是否开具小票
public boolean isReceipt(){
return false;
}
}
4.5 WeChat、AlipayTemplate——具体模板
/**
* @author Created by njy on 2023/7/17
* 微信支付模板
*/
@Component
public class WeChatTemplate extends PaymentTemplate{
@Autowired
private PaymentFactory factory;
@Override
public Payment selectPay() {
return factory.select("WeChatPay");
}
@Override
public boolean isReceipt() {
return true;
}
}
/**
* @author Created by njy on 2023/7/17
* 支付宝支付模板
*/
@Component
public class AliTemplate extends PaymentTemplate{
@Resource
private PaymentFactory factory;
@Override
public Payment selectPay() {
return factory.select("Alipay");
}
}
4.6 test
/**
* @author Created by njy on 2023/7/18
* 策略+工厂+模板模式测试
*/
@SpringBootTest
public class Factory_strategt_template {
@Autowired
AliTemplate aliTemplate;
@Autowired
WeChatTemplate weChatTemplate;
@Test
public void test(){
//支付宝
System.out.println("-------支付宝支付-----------");
aliTemplate.processPayment();
System.out.println("---------微信支付----------");
weChatTemplate.processPayment();
}
}
五、总结
对上述例子做个总结:
Payment和具体的支付类,通过工厂类PaymentFactory创建具体的支付对象,而支付流程则由支付模板类PaymentTemplate控制,并使用策略模式执行具体的支付策略,通过设置不同的支付模板子类,我们可以选择不同的支付方式。
优点如下:
- 支付方式的扩展性:如果以后添加了一种支付方式,那么只需要创建对应的策略类即可,无需修改原有的代码,符合开闭原则。
- 支付流程的通用性:通过模板方法模式,把支付流程的通用步骤抽象成模板方法,确保了一致性的支付流程。
- 灵活且可配置:通过工厂模式创建支付对象,并使用策略模式管理不同的支付方式,可以根据配置或上下文的需要动态选择支付方式。
ps:以上内容,希望对大家有所帮助,如果有纰漏或有更好的想法,请您一定不要吝啬您的赐教。