前言
这篇文章使用Java中多态的特性来完成不同方式的支付功能。
案例:使用接口多态的特性来完成微信
、支付宝
、银联
的支付。
开始
1 创建一个接口InterfaceHandler
(注:这里面的方法只作为演示,可按照自身的需求来更改,handler()
方法除外)
public interface InterfaceHandler {
/**
* 调用入口
*/
void handler();
/**
* 准备
*/
void prepare();
/**
* 开始
*/
void begin();
/**
* 结束
*/
void end();
}
-
perpare():这里作为我们支付前的准备工作,比如我们需要先进行
生成订单
,或者从数据库中读取支付的配置
等操作,可按照自身的需求进行修改。 -
begin():在这个方法里就是来发起支付的功能流程,比如将参数组装好去调用
微信API
的支付接口,返回prepay_id
等操作。 -
end():这个是在调用完微信支付后处理的逻辑。
-
handler():此方法作为我们整个支付程序的调用入口。
2 创建一个抽象类AbstractHandler
来实现InterfaceHandler
接口,并重写handler
方法。
(注:一个类实现某个接口必须重写接口中的所有抽象方法,否则该类必须定义为抽象类。)
public abstract class AbstractHandler implements InterfaceHandler{
@Override
public void handler() {
//准备
prepare();
//开始
begin();
//结束
end();
}
}
handler()方法作为我们整个支付程序的调用入口,在这个里面控制我们支付的执行流程。
3 创建微信、支付宝、银联支付的实现类,并继承AbstractHandler
(注:当一个普通类继承抽象类后,这个普通类必须重写抽象类中的所有抽象方法)
WechatPayService
、AlipayPayService
、UnionPayService
@Service("wechat-pay")
public class WechatPayService extends AbstractHandler {
@Override
public void prepare() {
System.err.println("微信支付参数准备!");
}
@Override
public void begin() {
System.err.println("微信支付发起支付!");
}
@Override
public void end() {
System.err.println("微信支付结束!");
}
}
@Service("alipay-pay")
public class AlipayPayService extends AbstractHandler {
@Override
public void prepare() {
System.err.println("支付宝支付参数准备!");
}
@Override
public void begin() {
System.err.println("支付宝支付发起支付!");
}
@Override
public void end() {
System.err.println("支付宝支付结束!");
}
}
@Service("union-pay")
public class UnionPayService extends AbstractHandler {
@Override
public void prepare() {
System.err.println("银联支付参数准备!");
}
@Override
public void begin() {
System.err.println("银联支付发起支付!");
}
@Override
public void end() {
System.err.println("银联支付结束!");
}
}
可以看到我们每个支付的实例都继承了AbstractHandler
抽象类,并重写方法,到这我们就已经完成整个流程的部署工作了,但是有个问题是,使用微信支付的时候,能不能正确调用到微信的实例,而不是调用到其它的支付实例?
测试
public class PayOrder {
public static void main(String[] args) {
InterfaceHandler wechatPayService = new WechatPayService();
wechatPayService.handler();
}
}
微信支付参数准备!
微信支付发起支付!
微信支付结束!
Process finished with exit code 0
这种就是向上转型,什么是向上转型?向上转型就是父类引用指向子类对象。父类引用可以调用子类和父类的公用方法(如果子类重写了父类的方法,则调用子类的方法)。
使用向上转型我们可以在对象实例化的时候根据不同需求实例化不同的对象。
进阶
在第3步的三个实现类中,我们将这三个类使用了@Service
注解,并给他们设置了自定义的bean名称,这说明我们可以在IOC容器中获取这三个实例。
那么我们可以通过不同的Bean名称来获取到不同支付的实例,来执行每个实例的handler()
方法,就可以实现微信支付的功能就会去执行微信的实例。
@Service
@AllArgsConstructor
public class PayOrderImpl implements PayOrderService {
private final Map<String, InterfaceHandler> interfaceHandlerMap;
@Override
public void pay() {
InterfaceHandler handler = interfaceHandlerMap.get("wechat-pay");
handler.handler();
}
}
我们可以在业务的实现中通过全局map的形式来获取到不同的handler
实例,从而实现不同的支付通道执行不同的支付方法。