记录一次在Java项目中关于反射机制的使用案例

173 阅读2分钟

之前做过一个关于支付的系统,系统中包含了10几种支付方式,这些支付方式往往需要跟第三方进行对接,可是不同服务商的支付接口又包含了不同的参数配置和功能。如果不考虑清楚就直接上手堆代码,很容易造出“屎山”。

多种支付方式需要考虑的问题

如何完成不同支付的调用,也就是说如何创建不同支付方式的对象,因为有10几种支付方式,并且后续很可能在扩展新的支付方式,总不能用if-else去判断用户选择了什么支付方式

解决办法

我想到的是使用java的反射机制来实现,因为在代码编写阶段,无法去知晓用户选择的支付方式具体是哪一种,而且如果支付方式的种类太多,也不应该使用if-else去实现。由于反射机制可以在代码运行的时候根据已经编译好的.class文件动态的生成对象,所以我们可以传递一个与具体支付方式的类名相同的字符串,通过反射机制创建实例

创建一个支付方式接口类,包含支付和查询订单状态两个抽象方法

public interface PayMode {
    //支付
    void pay();
    //查询订单状态
    void sett();
}

创建两个实现类,分别表示支付宝和微信支付

/**
 * 支付宝
 */
public class AliPay implements PayMode{
    @Override
    public void pay() {
        System.out.println("支付宝支付");
    }
    @Override
    public void sett() {
        System.out.println("支付宝查询订单状态");
    }
}
/**
 * 微信支付
 */
public class WeiXin implements PayMode{
    @Override
    public void pay() {
        System.out.println("微信支付");
    }
    @Override
    public void sett() {
        System.out.println("微信查询订单状态");
    }
}

创建一个支付方式的简单工厂,用来创建支付方式实例

/**
 * 支付方式工厂
 */
public class PayModeFactory {
    public static PayMode getPayMode(String mode) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        PayMode payMode = (PayMode)Class.forName("com.example.xypro.demos.mode."+mode).newInstance();
        return payMode;
    }
}

上面的代码可以看到,可以调用getPayMode方法并传入提前定义好的代表支付方式的字符串,通过Class.forName获取支付方式的.class类文件对象,再执行Class对象的newInstance()方法创建出支付方式的实例。

测试一下

public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    PayMode pay = PayModeFactory.getPayMode("WeiXin");
    pay.pay();
}

image.png
成功获取到想要的支付方式对象

通过反射节省了很多代码量,提高了程序得灵活性和可扩展性。所以,如果一个操作或者选择在代码的编译阶段是不确定的,只有运行的时候才能知晓的话,那就可以考虑使用反射机制来实现。