根据用例,我们这样做:
Async
服务API(例如InputObject1,InputObject2等)。我的代码有两处看起来很脏:
a. How to check the type of object on receiving from the queue? This would be in JSON format and I will have to convert JSON back to object. It will belong to one of the multiple potential objects.
b. Once type is known, how to call class responsible to handle that object?
这个用例的最佳设计是什么?
For a), one option is to create a `RequestWrapper` containing all the objects and populating the one this message belongs to.
我能为b)思考的几种方式如下:
1. Add another parameter to the object and pass it to queue. Use this parameter to identify API called.
2. Use `instanceof` to get exact requestObject using multiple if-else and do the needful.
虽然,这些对我来说似乎不太整齐。还有更好的建议吗?
==Edit==
@ A4L
不,他们不共享任何共同的界面(至少,截至目前)。
是的,我们可以在开始时修改这些对象(如果你的意思是“实现”)。因为,我们可以更改它,如果需要,我可以让它们共享一个公共接口。
谢谢,
答案 0 :(得分:1)
我建议引入至少一个新接口QueueTaskAble
,它将由您的输入对象实现,第二个 - 可选,可以简单地为java.lang.Runnable
- 然后以某种方式执行任务run
或execute
方法。
以下是它的样子:
interface QueueTaskAble {
Runnable getQueueTask();
}
class InputObjectFooQueueTask implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
}
}
class InputObjectFooImpl implements QueueTaskAble {
@Override
public Runnable getQueueTask() {
return new InputObjectFooQueueTask();
}
}
void processQueueInputObject(QueueTaskAble queueObject) {
queueObject.getQueueTask().run();
}
修改强>
不幸的是,使用Gson无法将本地反序列化为接口。为了能够这样做,您需要实现一个类型适配器,您可以将其传递给GsonBuilder#registerTypeAdapter,以便正确地序列化和反序列化您的对象。
以下是你可以采取的措施:
类型适配器
public class GenericGsonTypeAdapter<T> implements JsonSerializer<T>,
JsonDeserializer<T> {
@Override
public JsonElement serialize(T src, Type typeOfSrc,
JsonSerializationContext context) {
JsonObject jo = new JsonObject();
jo.addProperty("className", src.getClass().getName());
jo.add("jsonData", context.serialize(src));
return jo;
}
@Override
public T deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
T obj = null;
if(json instanceof JsonObject) {
JsonObject jo = (JsonObject) json;
JsonElement jeJson = jo.get("jsonData");
if(jeJson != null) {
JsonElement jeClassName = jo.get("className");
try {
obj = context.deserialize(json,
Class.forName(jeClassName.getAsString()));
} catch (ClassNotFoundException e) {
throw new JsonParseException(e);
}
}
}
return obj;
}
}
自定义Gson构建器(不幸的是GsonBuilder是最终的,因此无法扩展,因此作为静态最终成员)
public class InputObjectGsonBuilder {
private final static GsonBuilder gb;
static {
gb = new GsonBuilder();
gb.registerTypeAdapter(QueueTaskAble.class,
new GenericGsonTypeAdapter<QueueTaskAble>());
}
public Gson create() {
return gb.create();
}
}
示例队列
public class InputObjectGsonQueue {
private Queue<String> queue = new ArrayDeque<>();
public boolean pushInputObject(String json) {
return queue.offer(json);
}
public void processQueue() {
InputObjectGsonBuilder gb = new InputObjectGsonBuilder();
String json;
while(null != (json = queue.poll())) {
QueueTaskAble queueTaskAble = gb.create().fromJson(json,
QueueTaskAble.class);
processQueueInputObject(queueTaskAble);
}
}
private void processQueueInputObject(QueueTaskAble queueObject) {
queueObject.getQueueTask().run();
// or for asynchronous processing
// new Thread(queueObject.getQueueTask()).start();
}
}
一些输入对象和任务实现
public class InputObjectFooImpl implements QueueTaskAble {
@Override
public Runnable getQueueTask() {
return new InputObjectFooTaksImpl();
}
}
public class InputObjectBarImpl implements QueueTaskAble {
@Override
public Runnable getQueueTask() {
return new InputObjectBarTaksImpl();
}
}
public class InputObjectFooTaksImpl implements Runnable {
@Override
public void run() {
System.out.println("Foo!");
}
}
public class InputObjectBarTaksImpl implements Runnable {
@Override
public void run() {
System.out.println("Bar!");
}
}
最后是一个示例应用程序
public class App {
public static void main(String... args) {
InputObjectGsonBuilder gb = new InputObjectGsonBuilder();
InputObjectGsonQueue gq = new InputObjectGsonQueue();
gq.pushInputObject(gb.create().toJson(new InputObjectFooImpl(),
QueueTaskAble.class));
gq.pushInputObject(gb.create().toJson(new InputObjectBarImpl(),
QueueTaskAble.class));
gq.processQueue();
}
}
<强>输出强>
Foo!
Bar!