Here's how to do it in a safe type (and extensible) way using generics:
public interface MessageType { public static final class HELLO implements MessageType {}; } public interface Message<T extends MessageType> { Class<T> getTypeClass(); } public interface Response<T extends MessageType> { }
public class HelloMessage implements Message<MessageType.HELLO> { private final String name; public HelloMessage(final String name) { this.name = name; } @Override public Class<MessageType.HELLO> getTypeClass() { return MessageType.HELLO.class; } public String getName() { return name; } } public class HelloResponse implements Response<MessageType.HELLO> { private final String name; public HelloResponse(final String name) { this.name = name; } public String getGreeting() { return "hello " + name; } }
public interface MessageHandler<T extends MessageType, M extends Message<T>, R extends Response<T>> { R handle(M message); } public class HelloMessageHandler implements MessageHandler<MessageType.HELLO, HelloMessage, HelloResponse> { @Override public HelloResponse handle(final HelloMessage message) { return new HelloResponse(message.getName()); } }
import java.util.HashMap; import java.util.Map; public class Device { @SuppressWarnings("rawtypes") private final Map<Class<? extends MessageType>, MessageHandler> handlers = new HashMap<Class<? extends MessageType>, MessageHandler>(); public <T extends MessageType, M extends Message<T>, R extends Response<T>> void registerHandler( final Class<T> messageTypeCls, final MessageHandler<T, M, R> handler) { handlers.put(messageTypeCls, handler); } @SuppressWarnings("unchecked") private <T extends MessageType, M extends Message<T>, R extends Response<T>> MessageHandler<T, M, R> getHandler(final Class<T> messageTypeCls) { return handlers.get(messageTypeCls); } public <T extends MessageType, M extends Message<T>, R extends Response<T>> R send(final M message) { MessageHandler<T, M, R> handler = getHandler(message.getTypeClass()); R resposnse = handler.handle(message); return resposnse; } }
public class Main { public static void main(final String[] args) { Device device = new Device(); HelloMessageHandler helloMessageHandler = new HelloMessageHandler(); device.registerHandler(MessageType.HELLO.class, helloMessageHandler); HelloMessage helloMessage = new HelloMessage("abhinav"); HelloResponse helloResponse = device.send(helloMessage); System.out.println(helloResponse.getGreeting()); } }
To add support for the new message type, implement the MessageType interface to create a new message type, implement the Message , Response and MessageHandler interfaces for the new MessageType class and register a handler for the new message type by calling Device.registerHandler .