2017-03-26 7 views
3

私は複数の場所でエラーメッセージと成功メッセージを生成できるプロセスを持っているので、それらをすべて1つのクラスで追跡し、プロセスの最後に、さまざまなタイプのメッセージをグループ化したいと思います。 これらの行には、何か:ジェネリックを使用してinstanceofを回避する方法はありますか?

public class Message { 
    String message; 
    public Message(String message) { 
     this.message = message; 
    } 
} 

public class ErrorMessage extends Message {}; 
public class FileErrorMessage extends ErrorMessage {}; 
public class OkMessage extends Message {}; 

などがあります。 (わかりやすくするために派生クラスのコンストラクタをスキップしています)。私はinstanceofオペレータ、しかしを使用してリストの中で区別することができます。ジェネリックスはよりエレガントだと思いますが、どのようにリスト内でそれらを区別しますか?

Message<ErrorMessage> eMsg = new Message<ErrorMessage>("invalid user"); 
Message<FileErrorMessage> feMsg = new Message<FileErrorMessage>("file not found"); 

私は別のクラスの列挙型

enum MessagType { ERROR, FILE_ERROR, OK } 

を使用するのではと思ったが、私は解決策を考え出すことができませんでした。ありがとう。

+3

それらとの差別化*何*?完全に汎用的な解決策を探している場合(先験的な未知のことをする場合など)は、[訪問者パターン](https://en.wikipedia.org/wiki/Visitor_pattern)を使用する必要があります。あなたが先験的に知っていることを特定したいなら、多態性を使うことができます。 –

+1

"私はさまざまなクラスで列挙型[...]を使うことを考えました"列挙型フィールドで単一のクラスを使用できます。 'Message'は' MessageType getType() 'や' String getMessage() 'のようなメソッドを提供します。 – Izruo

+0

さて、これらをすべて1つのリストに追加して、将来定義されるエラーをリストに追加できるようにします。 Java Exceptionクラスは、私が記述したパターンに従っているようです。処理の最後に、ErrorMessagesを1つの場所に送信し、別の場所にOkMessagesを送信したいとします。 – bretter

答えて

3

このような状況で通常できることは、make Messageがサブクラスによってオーバーライドできる関数を持つことです。次に、各サブクラスは、その関数が呼び出されるときに独自の動作を持つことができます。あるいは、Messagesのデフォルト動作を保持することもできます。デフォルトが意味を持たない場合、Messageを抽象クラスにすることができます。

その後することができますリストをループしてのようなものを実行します。これはあなたが探していたされているもの

for (Message m : messages) { 
    m.function(); 
} 

願っています!

編集:以下のコメントを受けて、あなたは(グアバと)このような何かを行うことができます。

SetMultimap<Class, Message> messagesByType = HashMultimap.create(); 
for (Message m : messages) { 
    messagesByType.add(m.getClass(), m); 
} 

その後、一度にそれぞれ異なるタイプのものを処理するためにmessagesByTypeて、ネストされたループを行うことができます。それが言われている、私は実際にこれを行う必要はありませんが、私の最初の応答を与えて、しかしこれはあなたの質問に答えることです。

+0

instanceofを使用せずに、1つのリスト内のすべてのメッセージの違いを知りたいと考えています。もちろん、すべてのクラスにはgetMessage():Stringメソッドがあります。 – bretter

2

この場合、ジェネリックスを使用することは私には意味がありません。異なるタイプのメッセージが異なる動作をしている場合、継承を使用してメッセージのタイプによって区別することは意味がありますが、これは当てはまりません。あなたがKISS principleを参照して、それをシンプルに保つ必要があり、一般的には

enum MessageType { ERROR, FILE_ERROR, OK } 

public class Message { 

    private final String message; 

    private final MessageType type; 

    public Message(String message, MessageType type) { 
     this.message = message; 
     this.type = type; 
    } 

    public MessageType getType() { 
     return this.type; 
    } 

    // getter for message 
} 

だから、私はちょうどMessageクラスの属性として、メッセージの種類を持っているでしょう。

EDIT:あなたはタイプ別にグループメッセージにしたい場合は、次のように

、あなたがそれを行うことができます。

Map<MessageType, Message> messagesByType = messages.stream() 
    .collect(Collectors.groupingBy(Message::getType)); 

messagesは、すべてのメッセージを含むListです。

+0

hmm ... class ErrorMessageはメッセージ{ を拡張します。プライベート最終メッセージタイプtype = MessageType.Error; ... ... } – bretter

+0

@bretter私のポイントは、継承を全く使用すべきではないということです。 –

+0

私は、例外クラスのようなパターンを求めています彼らがリストに入っているときに離れて。 – bretter

関連する問題