【发布时间】:2015-02-03 16:19:20
【问题描述】:
我试图找出设计一个类的最佳方法,该类封装了 JSON 派生的 cmets。每条评论都针对特定主题,可以是整个文件,也可以是文件的一行。这是一个示例评论:
{
"text":"This is my favorite line!",
"path":"My file.txt",
"line":42
...
}
如果主题是一个整体的文件,line 就是null。
我希望Comment 类有一个subject() 方法,但我不确定设计CommentSubject 类的最佳方法。到目前为止,这是我所拥有的:
import javax.json.JsonObject;
class Comment {
private final JsonObject json;
private final CommentSubject subject;
public JsonObject json() { return json; }
public CommentSubject subject() { return subject; }
public Comment(JsonObject json) {
...
this.json = json;
subject = json.isNull("line") ? new FileSubject(this) :
new LineSubject(this);
...
}
...
}
abstract class CommentSubject {
enum SubjectType {
FILE, LINE
}
public abstract SubjectType type();
public abstract String path();
protected abstract Comment comment();
}
class FileSubject extends CommentSubject {
private final Comment comment;
private final String path;
public FileSubject(Comment comment) {
this.comment = comment;
path = comment.json().getString("path");
}
public FileSubject(CommentSubject subject) {
this(subject.comment());
}
@Override public SubjectType type() { return SubjectType.FILE; }
@Override public String path() { return path; }
@Override protected Comment comment() { return comment; }
...
}
class LineSubject extends CommentSubject {
private final Comment comment;
private final String path;
private final int line;
public LineSubject(Comment comment) {
this.comment = comment;
path = comment.json().getString("path");
line = comment.json().getInt("line");
}
public LineSubject(CommentSubject subject) {
this(subject.comment());
}
@Override public SubjectType type() { return SubjectType.LINE; }
@Override public String path() { return path; }
@Override protected Comment comment() { return comment; }
public int line() { return line; }
...
}
客户端代码可能如下所示:
doSomething(CommentSubject subject) {
if (subject.type() == SubjectType.LINE) {
LineSubject line = new LineSubject(subject);
...
}
...
}
但是,我不喜欢我当前的设计在客户端代码中需要一个新的 LineSubject 对象:subject 和 line 在上面的示例中是相同的,所以新对象的创建看起来像浪费空间。此外,为了将CommentSubject 对象传递给另一个CommentSubject 构造函数,就像上面的客户端代码一样,所有主体都需要由comment() 方法可访问的注释支持。我也不知道我对SubjectTypeenum的看法。
我想要的是Comment 有一个subject() 方法并且能够区分文件和行主题。有更好的设计吗?
【问题讨论】: