2016-06-16 9 views
1

私は大学のプロジェクトのコードを書いています。我々は、遠隔地やマルチプレイヤーでプレーするボードゲームを実装しなければならない。Javaのストリームを介したオブジェクトの多型?

現在、要求応答パターンを使用しています。クライアントはIOストリームを通じて要求をサーバーに送信し、サーバーはそれらを分析して正しい応答を返します。

問題は、我々は要求の多くの種類があり、我々は1が受信された要求を理解するために多型を使用していることである。

/** 
* This method is only functional to polymorphism: it should never be invoked. 
* @param request 
* @return only an assertion error 
*/ 
public ResponseMsg handleRequest(RequestMsg request) { 

    throw new AssertionError("It was created a RequestMsg. This should never happen.\n" 
} 

/** 
* The request is to change the map. 
* If the game is not started and the player is the first, the map will be changed and 
* a broadcast with the new map will be sent to all the players. 
* @param request: the request containing the name of the map chosen 
* @return An ack response message 
*/ 
public ResponseMsg handleRequest(ChangeMapRequestMsg request) { 

    if (game != null) 
     return new InvalidRequestMsg("You can't change the map when the game is already started"); 

    else if (request.getToken().getPlayerNumber() != 0) 
     return new InvalidRequestMsg("Only the first player can change the map"); 

    else { 

     this.map = request.getMap(); 

     BroadcastMsg broadcast = new ChangedMapBroadcastMsg(request.getMap()); 
     publisherInterface.publish(broadcast, getLobby()); 

     return new AckResponseMsg("Map changed successfully"); 
    } 
} 

/** 
* Handles a chat message 
* it sends a broadcast containing the message to all the players and an 
* acknowledgement to the player who sent it 
* 
* @param the chat request from the player 
* @return the acknowledgement 
*/ 
public ResponseMsg handleRequest(SendChatRequestMsg request) { 

    ChatBroadcastMsg chatBroadcast = new ChatBroadcastMsg(players.indexOf(request.getToken()), request.getMessage()); 
    publisherInterface.publish(chatBroadcast, getLobby()); 
    return new AckResponseMsg("Chat message sent.");   
} 

問題は、我々はサーバーにリクエストを送信するとき、私たちに必要なことですそれらを出力ストリームに渡し、入力ストリームを通じてそれらを読み込みます。私たちはそれらをObjectとする必要があり、多型を利用する可能性は失っています。

多形性を利用する方法をどのように維持できますか?私たちの教授が決してそれをすることはないと私たちが言ったように、instanceofを要求の動的なタイプを得るために使用しないことを望みます。

+0

オブジェクトを基本リクエストクラス(RequestMsg)にキャストできませんか?特定の要求タイプを知る必要はありません。 – Eran

+0

私たちはそれを行いました。呼び出されたメソッドは、一般的なものでしたが、特定のものが必要でした。 – Luvi

+0

これらのメソッドはすべて同じクラスに定義されていますか?それはどのクラスですか? – Eran

答えて

0

多型メッセージがありますが、メッセージ処理は多型ではありませんです。そのオーバーロード。

メッセージ処理を簡略化する方法があります。

処理をメッセージ自体に移します。次に、サーバーはメッセージベースクラスで定義されたメソッドを呼び出すことができます(おそらくサーバーをパラメーターとして渡します)。その後、方法はサーバのまたはのの正しい方法に代わって処理を行うことができます。

メッセージの処理方法を知らない場合は、何らかの形式のディスパッチが必要です。

public class LoginHandler implements MessageHandler { 
    public void process(MessageBase rawMessage) { 
     LoginMessage msg = (LoginMessage) rawMessage; 
     // handling code 
    } 
} 

:あなたはすべての既存のメッセージタイプのための具体的なハンドルを実装する必要が続いて

public interface MessageHandler { 
    public void process(MessageBase rawMessage); 
} 

:これは、すべてが共通のインタフェースを持っているハンドラあたりメッセージタイプを作成することによって行うことができますメッセージタイプをハンドラに関連付けるマップを作成する場合は、メッセージクラスに従ってメッセージのディスパッチを実行できます。

private Map<Class<?>, MessageHandler> handlerMap = new HashMap<>(); 
{ 
    // register every handler for every message 
    handlerMap.put(LoginMessage.class, new LoginHandler()); 
    // ... more handlers 
} 

public void dispatchMessage(Message message) { 
    MessageHandler handler = handlerMap.get(message.getClass()); 
    if (handler == null) 
     throw new RuntimeException("Unsupported message type"); 
    handler.process(message); 
} 
+0

ありがとう!私はあなたが提案し、メッセージに処理を移したときにしました。出来た! – Luvi

1

ストリームを介して送信されるオブジェクトが特定のクラスのインスタンスであるかどうかを確認し、そのクラスにオブジェクトをキャストする必要があります。私は、ストリーム上Stringオブジェクトを送信した場合

Object obj = ...; // The object sent over the stream 
if(obj instanceof String) { 
    String str = (String) obj; // Cast it to String 
    ... 
} else if(obj instanceof Integer) { 
    Integer i = (Integer) obj; // Cast it to Integer 
    ... 
} 

ので、最初のif文が実行されます。