2016-06-16 3 views
1

저는 대학 프로젝트 코드를 작성하고 있습니다. 우리는 원격 및 멀티 플레이어에서 재생할 보드 게임을 구현해야합니다.자바에서 스트림을 통한 객체의 다형성?

현재 요청 - 응답 패턴을 사용하고 있습니다. 클라이언트는 IO 스트림을 통해 서버에 요청을 보내고 서버는이를 분석하여 올바른 응답을 반환합니다.

/** 
* 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

Object를 기본 요청 클래스 (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 
    ... 
} 

그래서 첫 번째 경우 문이 실행됩니다.

관련 문제