gpt4 book ai didi

java - 如何在 Java 中设计类型安全的消息 API?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:21:38 25 4
gpt4 key购买 nike

我有一个 Java 客户端,它希望通过串行通信的消息与设备进行通信。客户端应该能够使用干净的 API,抽象串行通信的丑陋细节。客户端可以通过该 API 发送多种类型的消息并获得响应。我正在寻找最适合实现此 API 的建议。

为简单起见,假设我们只有两种消息类型:HelloMessage这会触发 HelloResponseInitMessage这会触发 InitResponse (实际上还有很多)

设计 API(即设备的 Java 抽象)我可以:

每种消息类型一个方法:

public class DeviceAPI {
public HelloResponse sendHello(HelloMessage){...}
public InitResponse sendInit(InitMessage){...}
... and many more message types ....

这是很好的类型安全。 (它也可能多次重载相同的 send() 方法,但大致相同)。但它非常明确,而且不是很灵活 - 我们不能在不修改 API 的情况下添加消息。

我也可以有一个单一的发送方法,它接受所有消息类型:

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接口(interface)来创建新的消息类型,实现MessageResponseMessageHandler 为新的 MessageType 类提供接口(interface),并通过调用 Device.registerHandler 为新消息类型注册处理程序。

关于java - 如何在 Java 中设计类型安全的消息 API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20515720/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com