我正在尝试使用 Jumblr 来使用我的 tumblr 数据这是一个 Java 的 Tumblr API 包装客户端。
我研究了源代码,发现由于 Json 响应是动态的,所以有一个 Post POJO 和派生的 POJO,如 TextPost、QuotePost、PhotoPost 等来反序列化为 pojo。它通过使用 Gson 和使用反射的自定义反序列化器以通用方式处理消费。例如,它通过这种方式反序列化对 TextPost 的 Json 响应并将其分配给 Post 对象。
因此,为了获取子类的字段,我需要在 instanceof
检查后向下转换 Post 对象,如下所示:
List<Post> posts = blog.draftPosts();
Post post = posts.get(0); //gets a TextPost
if(post instanceof TextPost) {
System.out.println("title: " + ((TextPost) post).getTitle());
System.out.println("body: " + ((TextPost) post).getBody());
}
else if(post instanceof QuotePost) {
//...
}
else if...
我不确定这是最好的方法。所以我正在从面向对象编程概念(如多态性或其他)的角度寻找更优雅或最好的方法或正确的方法。
获取子类或从父类(super class)访问子类的正确方法是什么?
您如何评估 API 的面向对象设计,该设计通过扩展包含额外状态的特定类来使用继承?这是一种合理的方法吗?从客户的角度来看,还有哪些其他方法可以处理响应?既然不是行为继承,那么使用继承只继承状态是否正确?
来自 API 来源:
public class Post {
protected PostType type;
private Long id;
private String author;
private String reblog_key;
private String blog_name;
//more state and getters/setters
}
public class TextPost extends Post {
//extra fields
private String title;
private String body;
//getters/setters
}
public List<Post> getPosts() {
Gson gson = gsonParser();
JsonObject object = (JsonObject) response;
List<Post> l = gson.fromJson(object.get("posts"), new
TypeToken<List<Post>>() {}.getType());
...
}
private Gson gsonParser() {
return new GsonBuilder().
registerTypeAdapter(Post.class, new PostDeserializer()).
create();
}
public class PostDeserializer implements JsonDeserializer<Object> {
@Override
public Object deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException {
JsonObject jobject = je.getAsJsonObject();
String typeName = jobject.get("type").getAsString();
String className = typeName.substring(0, 1).toUpperCase() + typeName.substring(1) + "Post";
try {
Class<?> clz = Class.forName("com.tumblr.jumblr.types." + className);
return jdc.deserialize(je, clz);
....
}
最佳答案
首先:没有“正确”的做法,只有优雅和不优雅的做法。处理此类问题的常见模式是以下之一:
- 让不同的类根据对象的子类决定如何处理(就像您在示例中所做的那样)。
- 通过抽象基类的(抽象)方法将处理子类状态的责任转移到子类中,每个子类都必须以自己的方式实现该方法。
- 将处理子类状态的责任移交给访问者 ( https://en.wikipedia.org/wiki/Visitor_pattern ),每个子类都会“访问”该访问者,并根据调用对象的类型来实现行为。
关于java - 当派生类主要用于扩展状态而不是行为时,如何动态获取继承层次结构中的子类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57180689/