我试图通过使用Jumblr来使用我的tumblr数据,这是Java的Tumblr API包装客户端。
我研究了源代码,发现由于Json响应是动态的,因此存在Post POJO和派生的POJO(如TextPost,QuotePost,PhotoPost等)反序列化为pojos。它通过将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...
我不确定这是最好的方法。因此,我从诸如多态或其他类似的面向对象的编程概念的角度寻找更优雅,最好的方法或正确的方法。
什么是从超类获取子类或对其进行访问的正确方法?
您如何通过扩展包含额外状态的特定类来评估使用继承的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)中,该访问者被每个子类“访问”,并且访问者根据调用对象的类型来实现该行为。