开发者

Defining Values of Fields as Constants in Java

I'm implementing a standard as an object oriented library in Java. Standard includes many messages which passing over network through terminals. Every message i开发者_运维技巧s implemented as a single class.

Some of the fields is represented as char types and those fields have one of the values that is defined in the standard. For example,

public class OutgoingMessage {
    private char action;

and action has these values,

'0' - Do not print
'1' - Print
'2' - Print and Forward
'3' - Print and Reply
'F' - Forward
'R' - Reply

Also some of the classes have more than 2 fields like this. Defining those as constants in the class can be messy in these situations.

So I'm trying to implement those values as

public class OutgoingMessage {
    private char action;

    public final class ActionTypes {
        public static final char DO_NOT_PRINT = '0';
        public static final char PRINT = '1';
        ...

And using as below

...
message.setAction(OutgoingMessage.ActionTypes.DO_NOT_PRINT);
...
message.setFooBar(OutgoingMessage.FooBarTypes.FOO_BAR);
...

What do you think? Is there anything wrong with this approach? How would you define these constants in the library?

Thanks a lot


Use enums in preference to int or char constants:

public enum Action {
    DoNotPrint,
    Print,
    PrintAndForward,
    PrintAndReply,
    Forward,
    Reply
}

public class OutgoingMessage {
     private Action action;

If you need to associate a char with the action, do this:

public enum Action {
    DoNotPrint('0'),
    Print('1'),
    PrintAndForward('2'),
    PrintAndReply('3'),
    Forward('F'),
    Reply('R');

    private static Map<Character, Action> map = new HashMap<Character, Action>() {{
        for (Action action : Action.values()) {
            put(action.getChar(), action);
        }
    }};

    private final char c;

    private Action(char c) {
        this.c = c;
    }

    public char getChar() {
        return c;
    }

    public static Action parse(char c) {
        if (!MapHolder.map.containsKey(c))
            throw new IllegalArgumentException("Invalid char: " + c);
        return MapHolder.map.get(c);
    }
}

Here's how you can use the parse method:

public static void main(String[] args) {
    System.out.println(Action.parse('2')); // "PrintAndForward"
    System.out.println(Action.parse('x')); // throws IllegalArgumentException
}


An enum is what you'd want to use for this. If you also need to be able to get the character codes, then you can add that to your enum, like this:

public enum Action {
    DO_NOT_PRINT('0'),
    PRINT('1'),
    PRINT_AND_FORWARD('2'),
    PRINT_AND_REPLY('3'),
    FORWARD('F'),
    REPLY('R');

    private final char code;

    private Action(char code) {
        this.code = code;
    }

    public char getCode() {
        return code;
    }
}

You'd just use the enum constants in your program, and when you need the char code, you call getCode on the enum value:

Action action = Action.DO_NOT_PRINT;
message.setAction(action);

// Suppose you need the char code:
char code = action.getCode();


I believe this is fine. But for simplicity you can use Enum also if you use at least JDK1.5


You could also think a bit more in depth the architecture and have an Action class (which will also avoid the big switch statement later on and decouple some code from the standard and the messages).

I would then get rid of the action types and rather make that easily extensible later on by simply adding Action implementations.

interface Action {
  public void performAction(Standard standard, OutgoingMessage msg);
}

class PrintAction implements Action {
  // Implement the interface methods properly...  
}

class ForwardAction implements Action {
  // Implement the interface methods properly...  
}

Then you simply add action instances to your message:

msg.addAction(new PrintAction());
msg.addAction(new ForwardAction());

If the actions need to be somehow carried with the message, make them Serializable (rather make the Action interface extends Serializable).


What you have is good, but If you just want to declare constants, you can use an interface.

public class OutgoingMessage {
    private char action;

    public final interface ActionTypes {
        public static final char DO_NOT_PRINT = '0';
        public static final char PRINT = '1';
        ...

And, yeah, enums good as well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜