接口优于反射
写在前面:最近在做一个需求:要针对不同的度量模型来执行不同的方法,同时要让后面接手的开发同学用最少的代码、最简单的方式来复用并实现更多度量模型。该需求一方面学到了一个新的设计模式——模板方法设计模式。另外一方面还得到一个经验————接口优于反射。
Effective Java的作者说接口优先于反射机制
,这个之前就有看过,但是当时也没搞明白接口和反射能有啥联系,直到最近。才发现这句话的确是有道理的。
我的需求:
有一批度量模型,要根据这些度量模型定义的规则给所有应用计算分数,不同的度量模型的计算方法需要对应不同的算法。整个计算过程需要离线计算(通过定时任务定时执行)。
我刚开始的做法(使用反射):
定义一个枚举:
public enum MeasureModelEnum {
CHECK_SPECIFIC_DEV_OWNER("execute","com.alibaba.intl.batch.sla.service.impl.SpecificDevOwnerCalculator");
/**
* 要执行的方法名
*/
String method;
/**
* 要执行的类的全路径名
*/
String clazz;
private MeasureModelEnum(String method ,String clazz){
this.method = method;
this.clazz = clazz;
}
public String getMethod(){
return this.method;
}
public String getClazz(){
return this.clazz;
}
}
然后用以下代码遍历枚举项,执行对应的方法:
for(MeasureModelEnum measureModel :MeasureModelEnum.values()){
String calculateMethod = measureModel.getMethod();
String calculateClass = measureModel.getClazz();
Class<?> class1 = null;
class1 = Class.forName(calculateClass);
Method method = class1.getMethod(calculateMethod,List.class,LeafMeasureModel.class);
method.invoke(class1.newInstance(),items,measureModel);
}
后来的做法(使用接口):
定义一个枚举:
public enum MeasureModelLeafNode {
CHECK_SPECIFIC_DEV_OWNER(new SpecificDevOwnerCalculator());
//SpecificDevOwnerCalculator是AbstractNodeCalculator的实现类
/**
* 实现类
*/
AbstractNodeCalculator calculateNode ;
private MeasureModelLeafNode(AbstractNodeCalculator calculateNode){
this.calculateNode = calculateNode;
}
public AbstractNodeCalculator getMeasureModel(){
return this.calculateNode;
}
}
然后用以下代码遍历枚举项,执行对应的方法:
for(MeasureModelLeafNode measureModel:MeasureModelLeafNode.values()){
measureModel.getMeasureModel().execute(items, measureModel);
}
总结
以上两部分代码的内容都是遍历枚举项,然后执行execute()
方法进行逻辑处理。区别在于一个使用反射调用方法,一个使用接口+多态的形式执行方法。
反射效率低。需要读取字节码到内存然后分配内存生成类实例最后执行。接口就省去这些步骤了,效率肯定好。