当前位置: 技术问答>java相关
如何避免反射
来源: 互联网 发布时间:2015-05-29
本文导语: 为了维护的方便,我在自己的应用中引入了反射,以替代长篇累牍的if else。但由于反射带来了一定的副作用,敬请各位为我提出一套好的解决方案,以最大程度优化设计,先谢谢大家了:) 就以一个论坛为例吧,客...
为了维护的方便,我在自己的应用中引入了反射,以替代长篇累牍的if else。但由于反射带来了一定的副作用,敬请各位为我提出一套好的解决方案,以最大程度优化设计,先谢谢大家了:)
就以一个论坛为例吧,客户端在浏览器输入http://127.0.0.1/servlet/Control?FunctionID=111,根据配置文件中所对应的功能名称进行判断,执行对应的功能,我的ForumControl如下
/**
* 论坛控制器。
*/
public class ForumControl implements Command
{
public String execute()
{
// 论坛列表
if ( functionID.equals( fc.getFunctionID ( "ForumList" )))
{
}
// 信息列表
if ( functionID.equals( fc.getFunctionID ( "ForumMessageList" )))
{
}
// 删除消息
if ( functionID.equals( fc.getFunctionID ( "ForumDeleteMessage" )))
{
}
//......
}
}
如果把上千个功能分布到十几个控制器类中,每个类中的if else就会把execute方法变得很庞大,违反我们所规定的“每个方法体语句不能超出25行”的原则,难于维护。
迫于无奈,我只好引入了反射:
/**
* AbstractCommand控制器接口。
*
*@author iSee
*@created 2002年4月7日
*/
public abstract class AbstractCommand
implements Command
{
//~ Instance/static variables .............................................
public Category cat = Category.getInstance( UserControler.class.getName() );
/**
* 执行操作。
*
*@return java.lang.String
*/
public String execute()
{
try
{
FunctionCode fc = FunctionCode.getInstance();
String className = this.getClass().getName() + "$" +
fc.get( functionID ).functionName;
Class innerClass = Class.forName( className );
Object[] initArgs = new Object[]{ this };
Class[] paramTypes = new Class[]{ this.getClass() };
Constructor innerConstr = innerClass.getConstructor( paramTypes );
AbstractAction action = ( AbstractAction ) innerConstr.newInstance(
initArgs );
ActionParams ap = new ActionParams();
ap.setRequest( req );
ap.setResponse( res );
action.setActionParams( ap );
action.actionPerformed();
out.close();
}
catch ( Exception exp )
{
// 集中错误处理
cat.info( "Error", exp );
}
return null;
}
}
/**
* 抽象操作类,用于系统控制器。
* Company: iSee Studio
* @author iSee
* @version 1.0
*/
public class AbstractAction
implements Action
{
//~ Instance/static variables .............................................
protected HttpServletRequest req;
protected HttpServletResponse res;
//~ Methods ...............................................................
/**
* 执行操作。
* @throws Exception 操作失败时抛出
*/
public void actionPerformed()
throws Exception
{
}
}
/**
* 论坛控制器。
*/
public class ForumControl
extends AbstractCommand
{
//~ Constructors ..........................................................
public ForumControl()
{
}
//~ Inner classes .........................................................
/**
*
* 删除消息
* @author iSee
* @version 1.0
*/
public class ForumDeleteMessage
extends AbstractAction
{
//~ Methods ...........................................................
public void actionPerformed()
throws Exception
{
Forum forum = ForumManager.getInstance();
// ......
}
}
/**
*
* 论坛列表
* @author iSee
* @version 1.0
*/
public class ForumList
extends AbstractAction
{
//~ Methods ...........................................................
public void actionPerformed()
throws Exception
{
}
}
/**
*
* 论坛消息列表
* @author iSee
* @version 1.0
*/
public class ForumMessageList
extends AbstractAction
{
//~ Methods ...........................................................
public void actionPerformed()
throws Exception
{
}
}
/**
*
* 显示/下载附件
* @author iSee
* @version 1.0
*/
public class ForumShowAttachment
extends AbstractAction
{
//~ Methods ...........................................................
public void actionPerformed()
throws Exception
{
}
}
}
就以一个论坛为例吧,客户端在浏览器输入http://127.0.0.1/servlet/Control?FunctionID=111,根据配置文件中所对应的功能名称进行判断,执行对应的功能,我的ForumControl如下
/**
* 论坛控制器。
*/
public class ForumControl implements Command
{
public String execute()
{
// 论坛列表
if ( functionID.equals( fc.getFunctionID ( "ForumList" )))
{
}
// 信息列表
if ( functionID.equals( fc.getFunctionID ( "ForumMessageList" )))
{
}
// 删除消息
if ( functionID.equals( fc.getFunctionID ( "ForumDeleteMessage" )))
{
}
//......
}
}
如果把上千个功能分布到十几个控制器类中,每个类中的if else就会把execute方法变得很庞大,违反我们所规定的“每个方法体语句不能超出25行”的原则,难于维护。
迫于无奈,我只好引入了反射:
/**
* AbstractCommand控制器接口。
*
*@author iSee
*@created 2002年4月7日
*/
public abstract class AbstractCommand
implements Command
{
//~ Instance/static variables .............................................
public Category cat = Category.getInstance( UserControler.class.getName() );
/**
* 执行操作。
*
*@return java.lang.String
*/
public String execute()
{
try
{
FunctionCode fc = FunctionCode.getInstance();
String className = this.getClass().getName() + "$" +
fc.get( functionID ).functionName;
Class innerClass = Class.forName( className );
Object[] initArgs = new Object[]{ this };
Class[] paramTypes = new Class[]{ this.getClass() };
Constructor innerConstr = innerClass.getConstructor( paramTypes );
AbstractAction action = ( AbstractAction ) innerConstr.newInstance(
initArgs );
ActionParams ap = new ActionParams();
ap.setRequest( req );
ap.setResponse( res );
action.setActionParams( ap );
action.actionPerformed();
out.close();
}
catch ( Exception exp )
{
// 集中错误处理
cat.info( "Error", exp );
}
return null;
}
}
/**
* 抽象操作类,用于系统控制器。
* Company: iSee Studio
* @author iSee
* @version 1.0
*/
public class AbstractAction
implements Action
{
//~ Instance/static variables .............................................
protected HttpServletRequest req;
protected HttpServletResponse res;
//~ Methods ...............................................................
/**
* 执行操作。
* @throws Exception 操作失败时抛出
*/
public void actionPerformed()
throws Exception
{
}
}
/**
* 论坛控制器。
*/
public class ForumControl
extends AbstractCommand
{
//~ Constructors ..........................................................
public ForumControl()
{
}
//~ Inner classes .........................................................
/**
*
* 删除消息
* @author iSee
* @version 1.0
*/
public class ForumDeleteMessage
extends AbstractAction
{
//~ Methods ...........................................................
public void actionPerformed()
throws Exception
{
Forum forum = ForumManager.getInstance();
// ......
}
}
/**
*
* 论坛列表
* @author iSee
* @version 1.0
*/
public class ForumList
extends AbstractAction
{
//~ Methods ...........................................................
public void actionPerformed()
throws Exception
{
}
}
/**
*
* 论坛消息列表
* @author iSee
* @version 1.0
*/
public class ForumMessageList
extends AbstractAction
{
//~ Methods ...........................................................
public void actionPerformed()
throws Exception
{
}
}
/**
*
* 显示/下载附件
* @author iSee
* @version 1.0
*/
public class ForumShowAttachment
extends AbstractAction
{
//~ Methods ...........................................................
public void actionPerformed()
throws Exception
{
}
}
}
|
will this work?
public interface ActionManager
{
public Action getAction(ActionId id)
throws NoSuchElementException;
public ActionManager addAction(ActionId id, Action act);
}
Then, in some action registration function, do
ActionManager register(ActionManager man)
{
return man.addAction(ActionIdFactory.buildActionId("ForumList", ForumListAction.instance())
.addAction(ActionIdFactory.buildActionId("ForumMessageList", ForumMessageAction.instance())
......
;
}
it does not make any sense to limit it to 25 lines if you have 1000 actions to register.
public interface ActionManager
{
public Action getAction(ActionId id)
throws NoSuchElementException;
public ActionManager addAction(ActionId id, Action act);
}
Then, in some action registration function, do
ActionManager register(ActionManager man)
{
return man.addAction(ActionIdFactory.buildActionId("ForumList", ForumListAction.instance())
.addAction(ActionIdFactory.buildActionId("ForumMessageList", ForumMessageAction.instance())
......
;
}
it does not make any sense to limit it to 25 lines if you have 1000 actions to register.
|
这个跟Struts的思路差不多吧,可以参考一下他的实现。好像是用Map,初始化时用Reflection读配置文件填Map,然后匹配时直接用Map就可以了。
|
我不知道,但来友情up!
为什么要避免反射呢?考虑到效率问题是吗?
为什么要避免反射呢?考虑到效率问题是吗?
|
是否可以用运行时的子类识别技术?
http://developer.ccidnet.com/pub/disp/Article?columnID=295&articleID=9586&pageNO=1
http://developer.ccidnet.com/pub/disp/Article?columnID=295&articleID=9586&pageNO=1
|
first of all, register is not type safe. you can easily end up with delicate code.
if you have code like Class.forName("A").newInstance();
you are requiring
1. A is a class (you cannot make it an inner class, make it private or change the name later)
2. A has to have a public constructor with no parameter.
The problem here is, even if you change A class, the compiler won't complain! the Java type system does not protect you from stupid mistakes. You may find out this problem a year after production!
secondly, reflection is inefficient.
if you have code like Class.forName("A").newInstance();
you are requiring
1. A is a class (you cannot make it an inner class, make it private or change the name later)
2. A has to have a public constructor with no parameter.
The problem here is, even if you change A class, the compiler won't complain! the Java type system does not protect you from stupid mistakes. You may find out this problem a year after production!
secondly, reflection is inefficient.
|
my code assumes an immutable hashtable. but you don't have the source code.
you may try it in mutable way.
you may try it in mutable way.
|
don't use reflection, RTTI unless necessary.
reflection is bad not only because of performance, type safety is the main drawback.
reflection is bad not only because of performance, type safety is the main drawback.
|
one senario that you may want to use reflection is:
you are concerned about the cost of deploying new class and functionality.
With reflection, you simply configure your new class name in some configuration xml file and your application can automatically use that class file. No code change and recompilation is necessary.
The drawback is, you don't have the Java type system to protect you. have to be very careful!
you are concerned about the cost of deploying new class and functionality.
With reflection, you simply configure your new class name in some configuration xml file and your application can automatically use that class file. No code change and recompilation is necessary.
The drawback is, you don't have the Java type system to protect you. have to be very careful!
|
帮忙UP,收益非浅!
|
佩服
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。