【问题标题】:Help with breaking out of if/elses?帮助打破 if/else?
【发布时间】:2011-02-22 12:32:45
【问题描述】:

我正在编写一个协议类,其中包含很多 if/else..这是类:

public class Protocol {
    Scanner scan = new Scanner(System.in);
    private static final int WAITING = 0;
    private static final int SENTREQUEST = 1;
    private static final int SENTITEMS = 2;
    private static final int ANOTHER = 3;
    private static final int CHOICE = 4;
    private int choice;

    private int state = WAITING;



    public String processInput(String theInput) {
        String theOutput = null;

        if (state == WAITING) {
            theOutput = "Do you accept the terms of agreement? Y/N?";
            state = SENTREQUEST;
        } else if (state == SENTREQUEST) {
            if (theInput.equalsIgnoreCase("y")) {

              theOutput = ": 1. program file 2. pictures 3. documentation";
              state = CHOICE;
             } else {
                theOutput = "Invalid Input!";
                state = SENTITEMS;

            }

        }
        else if (state == CHOICE) {
            choice = scan.nextInt();
            switch(choice) {
                case 1: theOutput = "show something";
                break;
                case 2: theOutput = "show something";
                break;
                case 3: theOutput = "show something";
                break;
            }
        }
        else if (state == SENTITEMS) {

              theOutput = "Want another? (y/n)";
                state = ANOTHER;

        } else if (state == ANOTHER) {

              theOutput = "Do you accept the terms of agreement? Y/N?";

            if (theInput.equalsIgnoreCase("y")) {
                theOutput ="test";
                state = SENTREQUEST;
            } else {
                theOutput = "Bye.";
                state = WAITING;
            }
        }
        return theOutput;
    }
}

它没有到达 switch 案例,我确定这是正确打破 if/elses 子句的问题,但我找不到问题。

【问题讨论】:

  • 你还没有展示它是如何被调用的。例如,对它的 first 调用总是将状态设置为 SENT_REQUEST 然后返回。也不清楚为什么你不首先打开状态(或者确实使用枚举)。
  • 你设置断点调试了吗?这就是我正常开始的地方。
  • 了解 scan.nextInt() 仅尝试将下一个令牌读取为 int 可能很有用,因此您需要先确保下一个令牌实际上是 int
  • 和 chimoo 的评论一样,我很好奇为什么你有一个 scan.nextInt() 而代码的其余部分使用“theInput”。您是否不小心“吃掉”了您在 theInput 中的号码并挂断了对 nextInt 的呼叫?一些示例程序输出可能有助于了解正在发生的事情。
  • @M. Jessup 你完全正确,我将 theInput 转换为一个整数,它现在可以工作了。

标签: java class switch-statement if-statement


【解决方案1】:

为了解决类似的问题,一旦我将strategy pattern 实现为枚举。对于每个策略,您为枚举创建一个新值,将代码封装在一个枚举方法中:

public enum Strategy {

    FIRST_STRATEGY {
        public String process(String input) {
            // Implementation for first strategy
            return null;
        }       
    },

    SECOND_STRATEGY {
        public String process(String input) {
            // Implementation for second strategy
            return null;
        }       

    };

    public abstract String process(String input);

}

您可以根据您拥有的枚举值应用所选策略,实际上删除 if/else 语句链:

Strategy chosenStrategy = Strategy.FIRST_STRATEGY;
String output = chosenStrategy.process(input);

这是我为我的一个问题应用的解决方案,也许它不是最佳的或更面向对象的解决方案。您必须为您的问题选择正确的解决方案,但我希望我的经验能有所帮助。

【讨论】:

  • 虽然这是编写相同程序的一种更优雅的方式,但我认为它并不能真正解决原始问题的问题。
【解决方案2】:

像这样使用状态模式:

public class Protocol {
    Scanner scan = new Scanner(System.in);

    private abstract class State { abstract String doit(String theInput); }

    private final class WAITING extends State {
      String doit(String theInput) {
         state = SENTREQUEST;
         return "Do you accept the terms of agreement? Y/N?";
      }
    }

    private final class SENTREQUEST extends State {
      String doIt(String theInput) {
        if (theInput.equalsIgnoreCase("y")) {
              state = CHOICE;
              return ": 1. program file 2. pictures 3. documentation";
             } else {
                state = SENTITEMS;
                return "Invalid Input!";
            }
      }
    }

 //TODO refactoring to State classes for all
 //        private static final int SENTITEMS = 2;
 //        private static final int ANOTHER = 3;
 //        private static final int CHOICE = 4;*/
    private int choice;

    private State state = WAITING;



    public String processInput(String theInput) {
        return state.doIt(theInput);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多