package com.lh.demo.service;
import com.lh.demo.domain.Order;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author: fenda
* @createDate: 2022/11/16 11:26
* @version: 1.0
* @description:
*/
@Slf4j
@Component
public class PaymentStrategyManager {
private final Map<String, PaymentStrategy> processMap = new ConcurrentHashMap<>();
public void registerHandler(PaymentStrategy strategy) {
if (processMap.containsKey(strategy.key())) {
log.error("Key is already in use! key={}", strategy.key());
throw new RuntimeException("Key is already in use! key=" + strategy.key());
}
processMap.put(strategy.key(), strategy);
}
public void work(Order order) {
PaymentStrategy paymentStrategy = processMap.get(order.getPaymentType());
if (paymentStrategy != null) {
paymentStrategy.pay(order);
}
}
}
package com.lh.demo.service;
import com.lh.demo.domain.Order;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
/**
* @author: fenda
* @createDate: 2022/11/16 11:17
* @version: 1.0
* @description:
*/
public abstract class PaymentStrategy {
@Autowired
private PaymentStrategyManager manager;
@PostConstruct
public void init() {
manager.registerHandler(this);
}
public abstract String key();
public abstract void pay(Order order);
}
package com.lh.demo.service;
import com.lh.demo.domain.Order;
import com.lh.demo.domain.PaymentType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @author: fenda
* @createDate: 2022/11/16 14:25
* @version: 1.0
* @description:
*/
@Slf4j
@Service
public class WxPaymentService extends PaymentStrategy {
@Override
public String key() {
return PaymentType.WX.getCode();
}
@Override
public void pay(Order order) {
log.info("wx pay ...");
// TODO 支付逻辑
}
}
package com.lh.demo.service;
import com.lh.demo.domain.Order;
import com.lh.demo.domain.PaymentType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @author: fenda
* @createDate: 2022/11/16 14:27
* @version: 1.0
* @description:
*/
@Slf4j
@Service
public class AlPaymentService extends PaymentStrategy {
@Override
public String key() {
return PaymentType.AL.getCode();
}
@Override
public void pay(Order order) {
log.info("ali pay ...");
// TODO 支付逻辑
}
}
package com.lh.demo.service;
import com.lh.demo.domain.Order;
import com.lh.demo.domain.PaymentType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @author: fenda
* @createDate: 2022/11/16 14:29
* @version: 1.0
* @description:
*/
@Slf4j
@Service
public class YsfPaymentService extends PaymentStrategy {
@Override
public String key() {
return PaymentType.YSF.getCode();
}
@Override
public void pay(Order order) {
log.info("ysf pay ...");
// TODO 支付逻辑
}
}
package com.lh.demo.domain;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author: fenda
* @createDate: 2022/11/16 11:23
* @version: 1.0
* @description:
*/
@Getter
@AllArgsConstructor
public enum PaymentType {
WX("WX", "微信"),
AL("AL", "支付宝"),
YSF("YSF", "云闪付");
public final String code;
public final String msg;
}
package com.lh.demo.domain;
import lombok.Data;
import java.math.BigDecimal;
/**
* @author: fenda
* @createDate: 2022/11/16 11:21
* @version: 1.0
* @description:
*/
@Data
public class Order {
/**
* 支付方式
*/
private String paymentType;
/**
* 金额
*/
private BigDecimal amt;
}
package com.lh.demo.controller;
import com.lh.demo.domain.Order;
import com.lh.demo.service.PaymentStrategyManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
/**
* @author: fenda
* @createDate: 2022/11/16 14:31
* @version: 1.0
* @description:
*/
@RestController
public class PaymentController {
@Autowired
private PaymentStrategyManager manager;
@PostMapping("/pay")
public String pay(@RequestBody Order order) {
manager.work(order);
return "ok";
}
}