TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
在通常的程序运行过程中,具体调用那个函数是事先编制程序时已经指定好了,运行时是按照以前拟定的流程运行。但有时在程序运行后才能指定调用那个函数,如TCP/IP通信时的命令执行,用户自定义方案的解读,表达式解析等场合,程序员首先得到是一个有规则的字符串,他必须解析这个字符串,再确定具体由那个函数来调用。 一般的处理是在解析后,通过特定的字符来决定程序下一步的去向,这样通常有一个庞大的分支语句在等待你创建,扩充和维护(硬编码的典型样板),你必须同时处理好至少两个类才能找到最终函数的归宿,这无疑加大了类与类之间的偶合度, 这与现代软件所追求的高内聚低耦合背道而驰。但java反射机制可以拯救我们脱离苦海。
以下例子实现了一个简单的计算式解析(加,减,乘,除)的功能。
下面是具体的实现
(1)计算类代码:
// 这个类用来实现具体的计算过程,
public class Caculator{
public int sum(int x,int y){
return x+y;
}
public int substract(int x,int y){
return x-y;
}
public int multi(int x,int y){
return x*y;
}
public int divide(int x,int y){
return x/y;
}
}
(2)外部适配器类,用来实现到Caculator具体函数的导向,并隐藏具体接口,统一对外表现为invokeMethod接口。
import java.lang.reflect.Method;
public class Adaptor{
private Adaptor(){
}
public static int invokeMethod(String methodName,int x,int y){
Integer retval=new Integer(0);
try{
// Get Class
String className="Caculator";
Class nativeClass=Class.forName(className);
Caculator caculator=(Caculator)nativeClass.newInstance();
// Setup parameter type array
Class types[]=new Class[2];
types[0]=Integer.TYPE;
types[1]=Integer.TYPE;
// Setup method
Method method=nativeClass.getMethod(methodName,types);
// Setup parameter array
Object inParams[]=new Object[2];
inParams[0]=new Integer(x);
inParams[1]=new Integer(y);
// Invoke method
retval=(Integer)method.invoke(caculator,inParams);
} catch(Exception ex){
StackTraceElement errElement=ex.getStackTrace()[ex.getStackTrace().length-1];
System.out.println("Error File="+errElement.getFileName()+" "+"Error Line="+errElement.getLineNumber());
}
return retval.intValue();
}
}
(3)具体调用如下:
int x=10;
int y=2;
System.out.println("x sum y="+Adaptor.invokeMethod("sum",x,y));
System.out.println("x substract y="+Adaptor.invokeMethod("substract",x,y));
System.out.println("x multi y="+Adaptor.invokeMethod("multi",x,y));
System.out.println("x divide y="+Adaptor.invokeMethod("divide",x,y));
(4)输出如下:
x sum y=12
x substract y=8
x multi y=20
x divide y=5
由上述程序可见,它完全实现了程序运行期函数定位,消除了分支语句,如果增加一种操作,只需在Caculator类中增加相应的函数即可,其他部分不需改变,Adaptor类可以作为反射导向类的模版使用,只需稍加改变就可以适应多种情况。大家应该
学会这种动态导向方法。
|
|