
修订模式
这是一个简短的帖子。 我不确定如何启动它。 这是审阅一些现有代码时“为什么我没有想到这一刻”之一。 由于存在NDA,我无法共享实际代码。 它与处理修订有关。 与我最相关的是WordPress(WP)如何处理博客文章和修订。
在WP中, wp_insert_post
函数插入或更新帖子。 它检查ID字段以确定将执行INSERT
还是UPDATE
。 如果帖子正在更新,它将检查是否进行了更改。 如果是这样,则保存修订。 可以设置要保留的修订数量的限制。 如果是这样,最旧的将被删除。
这听起来像可以建模为富域实体的事物。 这是第一次尝试。
@Entity
... class Post {@Id @GeneratedValue ... id;... name;... title;... content;... excerpt;... status; // e.g. 'draft', 'publish', 'inherit'... type; // e.g. 'post', 'revision'@OneToMany @JoinColumn(name="parent_post_id") ... List<Post> revisions;...// setters and getters
}
Post post = new Post();
post.setTitle("Lorem Ipsum");
post.setContent("...");
// save post
...
post = // retrieve existing post for updates
post.setContent("..."); // how can we ensure that revision is created?
在第一次尝试中,setter方法对确保在更新帖子时创建修订版提出了挑战。 让我们再试一次。 这是我们的第二次尝试。
// Immutable class
@Embeddable
... class PostData {... title;... content;... excerpt;// getters only... getTitle() { return title; }... getContent() { return content; }... getExcerpt() { return excerpt; }// equals() method to compare with another post data// to see if there are changes
}@Entity
... class Post {@Id @GeneratedValue ... id;... name; // for a revision, will contain parent ID and revision #@Embedded ... PostData postData; // read-only... status; // e.g. 'draft', 'published', 'inherit'... type; // e.g. 'post', 'revision'@OneToMany @JoinColumn(name="parent_post_id") ... List<Post> revisions;...... getTitle() { return this.postData.getTitle(); }... getContent() { return this.postData.getContent(); }... getExcerpt() { return this.postData.getExcerpt(); }... getName() { return name; }
}
这是我得到“为什么我没有想到那一刻”的时刻!
注意我们如何将发布数据封装为自己的类型PostData
。 这是一成不变的。 这样可以确保在更新帖子时创建修订。
PostData postData = new PostData("Lorem Ipsum", "...", "...");
Post post = new Post(postData);
// save post
...
post = // retrieve existing post for updates
// post.setContent("..."); // not possible
post.updateData(new PostData("...", "...", "...")); // ensure that revision is created
这就是我们创建修订的方式。
@Entity
... class Post {...@Embedded ... PostData postData; // read-only...@OneToMany @JoinColumn(name="parent_post_id") ... List<Post> revisions;...public Post(PostData postData) {this(postData, null);}/* package private */ Post(PostData postData, Post parent) {if (postData == null) {throw new IllegalArgumentException(...);}this.postData = postData;if (parent == null) {this.type = "post";this.status = "draft";this.name = null;this.revisions = new ArrayList<>();} else {this.type = "revision";this.status = "inherit";this.name = "" + parent.getId() + "-revision" + (parent.getRevisionsCount() + 1);this.revisions = null;}...}...... void updateData(PostData newPostData) {if (this.postData.equals(newPostData)) {// no changes, no revisions addedreturn;}...// creates a revisionPostData beforePostData = this.postData;this.revisions.add(0, new Post(beforePostData, this));// store latest changesthis.postData = newPostData;// limit to number of revisions to keepif (this.revisions.size() > ...) {// delete the excess onesfor (...) {this.revisions.remove(this.revisions.size() - 1);}}...}...
}
就像我说的,这是一篇简短的文章。 在下面的评论中让我知道您是否曾经看过它,或者像我一样,它给了您“为什么我没有想到那个”时刻。
翻译自: https://www.javacodegeeks.com/2018/11/revisions-immutability.html
修订模式