在Java中进行编程的最有效方法

时间:2011-09-28 13:35:14

标签: java logic

好吧,假设你有一个简单的程序,它采用字母az,如果你输入“c”,它会做一些事情,例如“e”可能会添加2个随机数,“h”显示单词“hello”, “x”显示时间等。

现在我试图通过26个不同的方法来解决这个问题,每个字母一个,然后是一个主体代码,扫描用户输入然后调用适当的方法。

现在他们显然有100种方法可以解决这个问题,但我想到的主要两种方法是你可以有26个if或者一个switch语句(例如,if(userInput.equals(“a”))然后调用方法a等等)。或者我正在考虑的另一种方法是使用标记为az的方法,然后让用户输入“f”而不是检查它是哪个字母而不是信任用户并完全调用他们输入的字母。

例如:

- >用户输入Y

userInput = y;

userInput(); - (这实际上是调用方法名称y())。

我相信有一种方法可以使用“反思”来阅读这里,但我听说要避免过早优化,但在这种情况下,这不是最合乎逻辑的事情吗?

5 个答案:

答案 0 :(得分:6)

我看到的方式:

  • 1)设置一个大的if / else if树来检查用户输入
  • 2)设置一些 片状,不稳定和缓慢反射的东西
  • 3)使用Map,其中'String'是字母和CmdHandler 将是一个具有被调用函数的类。 (命令模式)
对于这样一个简单的例子,#3是一个更多的架构,但它有助于更​​好地扩展。

编辑:快速肮脏的例子

public class Testing {
    public static void main(String[] args) {
    CmdHandler ch = null;

    /* Setup & populate our map */
    HashMap<String, CmdHandler> cmdMap = new HashMap<String,CmdHandler>();

    ch = new AKeyHandler();
    cmdMap.put(ch.getCmd(), ch);

    ch = new BKeyHandler();
    cmdMap.put(ch.getCmd(), ch);
    /* ..etc.. */

    /* Actually use the system now! */
    String input = "";
    input = "a"; /* Get our input from... whereever */

    /* Do any input validation/manipulation here */

    CmdHandler handler = cmdMap.get(input.toUpperCase());
    if (handler != null)
        handler.doWork();
    else
        System.err.println("Egads!  A null!");

    }

public static abstract class CmdHandler {
    private final String cmd;
    public CmdHandler(String cmd) {
        super();
        this.cmd = cmd.toUpperCase();
    }
    public String getCmd(){
        return this.cmd;
    }
    public abstract void doWork();
}
public static class AKeyHandler extends CmdHandler{     
    public AKeyHandler() {
        super("a");
    }
    public void doWork() {
        System.out.println("Executing the A Key cmd doWork()");
    }
}
public static class BKeyHandler extends CmdHandler{     
    public BKeyHandler() {
        super("b");
    }
    public void doWork() {
        System.out.println("Executing the B Key cmd doWork()");
    }
}

/* ...etc... */

}

答案 1 :(得分:1)

我会考虑使用enum

enum Letter{
    A("a"){
        @Override
        void foo(){
            // do stuff
        }
    }, 
    B("b"){
        @Override
        void foo(){
            // do stuff
        }
    },
    .
    .
    .
    Z("z"){
        @Override
        void foo(){
            // do stuff
        }
    };

    private final String text;
    Letter(final String text){
        this.text = text;
    }

    abstract void foo();
    public static final Letter getInstance(final String s){
        for(Letter l: Letter.values()){
            if(s.equalsIgnoreCase(l.text)){
                return l;
            }
        }

        return null;
    }
}

通过这种方式,您只需获取用户输入,调用Letter.getInstance(...),然后获取相应的Letter实例。然后从那里,您只需在foo()实例上调用Letter,这将执行特定于该字母的操作。

答案 2 :(得分:0)

这是Command Pattern (编辑:删除所有幽默;感谢幽默巡逻队的好处)。有许多方法可以实现它,但最简单的是命令处理程序的映射。

答案 3 :(得分:0)

好的,首先,反射实际上很慢。它需要程序检查它自己的代码(虽然这可能不是缓慢的来源)。

你真的需要26种不同的方法吗?对我来说闻起来有些奇怪。这些方法中是否有任何重复代码?如果是的话,你应该找到这种共性,并有一个或一组if语句来管理特定于字母的代码。这实际上会更有效,并且会为您的应用创建更小的占用空间。

令人担心切换与效率相关的主要问题,正如我所看到的那样,除非您正在编写任务关键型软件,或者非常优化某些东西(您可能不会用java编写),有问题的代码每秒被调用数千次,差异可以忽略不计。

假设你实际上需要这26种不同的方法,Dave Newton的回答可能就是你想要的。

答案 4 :(得分:0)

反射可能是一种选择,但您将面临用户输入不存在的函数后缀的风险。如果使用数据库不是一个选项,那么最好的选择可能是实例化一个Map,其中字母为键,显示结果为值,并以用户输入为键调用get(Object key)方法。如果结果为null(用户没有输入字母),您可以适当地处理它。

如果在用户输入字母时需要计算值,则可以使用“过程”方法为实现某些界面的对象填充地图。当您拉出值时,您只需要调用过程方法。注意使用匿名类,因为在这种情况下这可能是最好的。

map.put("a", new Processor(){
     @Override
     public String process(){
          return "someString";
     }
}

其中Processor是您创建的某个界面。