我有一个Java客户端,希望通过串行通信的消息与设备通信.客户端应该能够使用干净的API,抽象出串行通信的丑陋细节.客户端可以通过该API发送许多类型的消息并获得响应.我正在寻找建议哪种方式最适合实现此API.
为简单起见,假设我们只有两种消息类型:HelloMessage触发a HelloResponse和InitMessage触发a InitResponse(实际上还有更多)
设计API(即设备的Java抽象)我可以:
每种消息类型一种方法:
public class DeviceAPI {
  public HelloResponse sendHello(HelloMessage){...}
  public InitResponse sendInit(InitMessage){...}
  ... and many more message types ....
这很安全.(它也可能是同send()一种方法的多次重载,但大致相同).但它非常明确,而且不够灵活 - 我们无法在不修改API的情况下添加消息.
我也可以有一个send方法,它接受所有消息类型:
class HelloMessage implements Message
class HelloResponse implements Response   
...
public class DeviceAPI {
  public Response send(Message msg){
    if(msg instanceof HelloMessage){
       // do the sending, get the response
       return theHelloResponse
    } else if(msg instanceof ...
这简化了API(只有一种方法),并允许在以后添加其他消息类型而无需更改API.同时,它要求客户端检查响应类型并将其转换为正确的类型.
客户代码:
DeviceAPI api = new DeviceAPI();
HelloMessage msg = new HelloMessage();
Response rsp = api.send(msg);
if(rsp instanceOf HelloResponse){
    HelloResponse hrsp = (HelloResponse)rsp;
    ... do stuff ...
在我看来,这很难看.
您有什么推荐的吗?还有其他方法可以提供更清晰的结果吗?
参考欢迎!别人怎么解决这个问题?
这是一种使用泛型以类型安全(且可扩展)的方式完成此操作的方法:
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());
    }
}
要添加对新消息类型的支持,请实现MessageType接口以创建新消息类型,为新类实现 和接口Message,并通过调用 注册新消息类型的处理Response程序。MessageHandlerMessageTypeDevice.registerHandler