2011-07-21 9 views
4

私はJavaでオブジェクト指向ライブラリとして標準を実装しています。標準には、端末を介してネットワークを経由する多くのメッセージが含まれます。すべてのメッセージは単一のクラスとして実装されています。フィールドの値をJavaで定数として定義する

フィールドのいくつかはchar型として表され、これらのフィールドは標準で定義されている値のいずれかを持ちます。例えば、

public class OutgoingMessage { 
    private char action; 

とアクションは、これらの値を持って、クラスの

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

また、いくつかは、このような2つの以上のフィールドを持っています。これらの状況では、それらをクラスの定数として定義するのは面倒です。

だから私は

public class OutgoingMessage { 
    private char action; 

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

そして、あなたはどう思いますか

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

以下のように使用してこれらの値を実装しようとしていますか?このアプローチに何か問題はありますか?ライブラリでこれらの定数をどのように定義しますか?

どうもありがとうintまたはchar定数に優先して

+1

私には意味がある – RMT

+6

これは問題ありません。あなたは少なくともjdkを使用する場合enumを使用することもできます1.5 – Rudy

+1

私にも完全にうまく見えます。 – Kainsin

答えて

8

使用列挙型:アクションとcharを関連付ける必要がある場合は

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

public class OutgoingMessage { 
    private Action action; 

は、次の操作を行います。

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); 
    } 
} 

がここにあります解析メソッドの使い方:

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

+1、これは定数を実装するための新しい標準です。これはタイプセーフなのでより良いです。 – Moonbeam

+0

あなたはタイプセーフで何を意味しますか? –

+0

@Kit:コンパイル時でも有効な値しか使用できないことを意味します。 –

1

これは問題ないと思います。しかし、簡単にするために、少なくともJDK1.5を使用する場合はEnumを使用することもできます。

2

enumはこれに使用したいものです。

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; 
    } 
} 

あなたは自分のプログラムの中でenum定数を使用したい、とあなたは文字を必要とするとき:あなたはまた、文字コードを取得できるようにする必要がある場合は、このように、あなたのenumにそれを追加することができますコードには、列挙型の値にgetCodeを呼び出す:

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

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

ます。また、深さにもう少しアーキテクチャを考え、また、後に大きなswitch文を避け、からいくつかのコードを切り離すなる(Actionクラスを持つことができます標準とメッセージ)。

私は、アクションの種類を取り除き、後で単純にActionの実装を追加することで、簡単に拡張できるようにします。

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

次に、あなたは単にあなたのメッセージにアクションのインスタンスを追加します。アクションが何とかメッセージで運ばする必要が

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

場合は、(むしろアクションインターフェースはSerializableを拡張します)それらを直列化します。

+0

私は間違った例を与えたことを知っていました:)もちろん、これは正しいですが、いくつかのフィールドは単なるダムデータフィールドです。私はそれらをオブジェクトに収めることができませんでした。とにかくおかげで;) – xelon

+0

うん、その後、列挙型は行く方法です:) –

0

あなたが持っているものは良いですが、定数を宣言するだけの場合は、インターフェイスを使用できます。

public class OutgoingMessage { 
    private char action; 

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

そして、ええ、enumsも良いです。

関連する問題