当前位置:  技术问答>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
        {
        }
    }
}





|
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.

|
这个跟Struts的思路差不多吧,可以参考一下他的实现。好像是用Map,初始化时用Reflection读配置文件填Map,然后匹配时直接用Map就可以了。

|
我不知道,但来友情up!

为什么要避免反射呢?考虑到效率问题是吗?

|
是否可以用运行时的子类识别技术?
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.



|
my code assumes an immutable hashtable. but you don't have the source code.
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.

|
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!

|
帮忙UP,收益非浅!

|
佩服

    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • Linux/Unix是如何避免硬盘碎片的
  • java自动根据文件内容的编码来读取避免乱码
  • 大家提供一个避免空指针操作的好方法?
  • 指教怎样避免空指针。。。
  • redhat7.3是不是有问题??为什么在拖动窗口的时候容易死机??怎么避免??
  • jquery防止重复执行动画避免页面混乱
  • 有潜在危险的 Request.Form 值避免方法
  • 打开窗口时如何避免自动切换到中文输入法?
  • unix-遍程基础:避免僵尸进程defunc的方法有那些?欢迎参与讨论
  • 我每次用emacs编辑文件后,总要生成一个副本,问怎么避免它
  • HELP~~~~~~JTREE里面如何避免重复的节点出现
  • 如何简单的避免程序的重复启动?
  • broken pipe是什么意思啊,如何避免阿?
  • 请问Killed系统错误是什么原因造成的?如何避免?
  • 从window上传到linux文件(覆盖同名文件),为什么文件的访问权限会变,怎么避免?
  • 取seesion当seesion为空是抛出异常?怎么避免?
  • 请问,在一个进程中创建多线程时如何能避免不同的线程获得同一个线程标识
  • 一个字符串分割来存到DB中的问题:如何避免一个汉字被从中间分割掉?
  • 请教如何避免不登录就直接访问一个jsp文件
  • sql语句中单引号嵌套问题(一定要避免直接嵌套)


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3