3

扩展这个问题,我接受了一个答案,它说在这种情况下使用查找表或哈希图,因为它是处理多个条件的更好构造

当前构造。

类来存储消息。

    public class ProgressMessages 
    {
     public static String msg1="Welcome here .....";
     .
     .
     .
     //around 100 more similar static variables.
    }

条件并显示来自上述类的正确消息。

    int x=calculatedVal1(m,n); 
    int y=calculatedVal2(o,q);

    SimpleDateFormat formater=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date d=new Date();
    String s=formater.format(d);

    try {
          long d1 = formater.parse("2013-01-10 13:53:01").getTime();
          long d2=formater.parse(s).getTime();
          totaldays=Math.abs((d1-d2)/(1000*60*60*24));
         } catch (ParseException e) {
            e.printStackTrace();
         }

    if(totaldays<7&&x<20)
     {
      System.out.println("my message...1"+ProgressMessages.msg1); 
     }

    else if(totaldays<7&&x>10&&y<20)
    {
      System.out.println("my message...2"+ProgressMessages.msg2);
    }   
    ....
    //obvioulsy 100 more else-if's to display 100 messages.

我实际上想知道在这种情况下查找表有什么帮助?

它应该如何在 java Hashmap/Hashtable 等中实现,有什么好处呢?

- - 编辑 - -

我要去@assylias anwer,因为它更干净。但是如果我使用 Enums,那么我就有了解决办法。

为了描述大局...

即消息列表就像...

1) "Welcome," + nameOfUser+"your success rate is"+ succssRate +"%"+ earlier it was +earlier +"%".

2) "Oh yes.."+ succssRate +"%"+ improved from +earlier +"%".

3.) "Now you should focus on "+exerCiseName.

How could I do this using Enumeration as it has fixed String data. Could I make different constructors? How any example with the edit code to assylas answer?

4

3 回答 3

3

You could use an enum, assuming the list of messages is known at compile time. The advantages are that each message is now responsible for holding its condition, and the calling code will be much simpler.

public enum Message {

    MESSAGE1("Welcome") {
        @Override
        boolean isApplicable(long totalDays, int x, int y) {
            return totalDays < 7 && x < 20;
        }
    },
    MESSAGE2("Bye bye") {
        @Override
        boolean isApplicable(long totalDays, int x, int y) {
            return totalDays < 7 && x > 10 && y < 20;
        }
    };

    private String msg;

    Message(String msg) {
        this.msg = msg;
    }

    abstract boolean isApplicable(long totalDays, int x, int y);

    public static String lookupMessage(long totalDays, int x, int y) {
        for (Message m : Message.values()) {
            if (m.isApplicable(totalDays, x, y)) {
                return m.msg;
            }
        }
        throw new IllegalArgumentException();
    }
}

Now in your calling code, no more if / else if, just one line of code:

System.out.println(Message.lookupMessage(1, 2, 3));

Note 1: This is not as efficient as using a Map as the lookup is an O(n) operation, but because n is 100 or so it should not be a significant performance penalty. And it is more readable and maintainable than the solution proposed in the other answer.

Note 2: You could even put the conditions / messages in a flat file, read the file at runtime and use a scripting engine to eval each condition at runtime. It would be slightly slower (but we are talking about sub-milliseconds here) but would remove all the clutter from your code and put it in a configuration file.

于 2013-01-10T07:52:25.213 回答
2

I would use a

Map<Criteria, Message> lookupTable;

where Criteria is a class you write (and override equals() and hashCode()), representing the criteria to choose a message.

Message is also a class you write, which encapsulates the actual message String but also provides you some functionality to set the variables.

With this solution you have to initialize the map once at the beginning of your program and can always use it like this:

Criteria criteria = ... // gather your criteria somehow
Message msg = lookupTable.getMessage(criteria);
// use your variable setting methods here
String message = msg.toString();
于 2013-01-10T13:17:09.233 回答
0

If you have so many conditions, you cant avoid putting those conditions some where in the code. The advantages of using lookup table is 1)Easy to implement. 2)Flexible.If you want to change the value of some message in future, you can go to looktable class and change.

于 2013-01-10T07:37:58.683 回答