- 需求
由于业务需要,公司系统中接入了多家支付方式,包括支付宝,微信,京东等,现要对支付体系进行设计,达到高内聚,低耦合,易扩展的非功能性要求。 - 思路
这种需求可以用策略或者工厂模式实现,抽象出业务行为,假设行为有两种,支付,退款。使用工厂模式的话,征程流程应该是:
controller->service(工厂分发)->多个service实现
这中实现方式估计很多人都听过用过,但是有个问题是在分发的时候如何避免出现多余的if-else ,都用设计模式了,过多的if-else 看起来就有点碍眼了。 我们可以通过枚举将支付编码与实现类相绑定,结合spring 对bean 进行管理,从而达到消除if-else 的目的
抽象接口,定义了支付和退款两种行为
public interface IPay {
PayVo pay(PayDto dto);
RefundVo refund(RefundDto dto);
defalut void valid(){
}
}
支付枚举
public enum PayEnum {
WX(1,"1001",WeiXinPay.class),
ZFB(2,"1002",ZFBPay.class),
JD(3,"1003",JDPay.class),
UNKNOWN(99,"",null);
private Integer id;
private String code;
private Class cla;
public static PayEnum getInstance(String code){
PayEnum[] payEnums = PayEnum.values();
for (PayEnum pe : payEnums) {
if (pe.getCode().equalsIgnoreCase(code)){
return pe;
}
}
return PayEnum.UNKNOWN;
}
}
京东支付
@Component
public class JDPay implements IPay{
@Override
public PayVo pay(PayDto dto) {
System.out.println("调用京东支付");
return new PayVo();
}
@Override
public RefundVo refund(RefundDto dto) {
return null;
}
}
微信支付
@Component
public class WeiXinPay implements IPay{
@Override
public PayVo pay(PayDto dto) {
System.out.println("调用微信支付");
return new PayVo();
}
@Override
public RefundVo refund(RefundDto dto) {
return null;
}
}
支付宝支付
public class ZFBPay implements IPay{
@Override
public PayVo pay(PayDto dto) {
System.out.println("调用支付宝支付");
return new PayVo();
}
@Override
public RefundVo refund(RefundDto dto) {
return null;
}
}
请求从controller 进来,这里只展示提现设计思路的代码,大概如下
@RestController
@SpringBootApplication
public class WebServiceApplication {
public static void main(String[] args) {
SpringApplication.run(WebServiceApplication.class, args);
}
@Autowired
ApplicationContext context;
@PostMapping("/pay")
public PayVo controller(@Validated @RequestBody PayDto dto) {
PayEnum payEnum = PayEnum.getInstance(dto.getCode());
if (payEnum == PayEnum.UNKNOWN) {
throw new RuntimeException("抛出异常:类型不对");
}
IPay iPay = context.getBean(payEnum.getCla());
return iPay.pay(dto);
}
}
整个过程的亮点就是通过枚举将实现类和支付编码绑定起来,从枚举中拿到支付编码对应的实现类,进而从spring 容器中拿到对应的bean,然后去调用具体支付方式的实现方法,基本满足高内聚,低耦合,强扩展,消除if-else 的需要。
|