Вот краткий пост. Я не уверен, как начать это. Это один из тех моментов «почему я не подумал об этом» при просмотре существующего кода. Из-за NDA я не могу поделиться реальным кодом. Это как-то связано с обработкой ревизий. Самое близкое, что я могу сказать, это то, как WordPress (WP) обрабатывает сообщения и ревизии в блоге.
В WP функция wp_insert_post вставляет или обновляет сообщение. Он проверяет поле идентификатора, чтобы определить, будет ли он выполнять INSERT или UPDATE . Если сообщение обновляется, оно проверяет, были ли внесены изменения. Если это так, ревизия сохраняется . Можно установить ограничение на количество сохраняемых ревизий. Если это так, самые старые из них удаляются.
Это звучит как нечто, что можно смоделировать как объект с богатым доменом. Вот первая попытка.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@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} |
|
1
2
3
4
5
6
7
|
Post post = new Post();post.setTitle("Lorem Ipsum");post.setContent("...");// save post...post = // retrieve existing post for updatespost.setContent("..."); // how can we ensure that revision is created? |
С первой попытки методы установки создают проблему для обеспечения создания ревизии при обновлении публикации. Давайте попробуем еще раз. Вот наша вторая попытка.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
// 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 . Это неизменно. Это позволяет гарантировать, что редакция создается при обновлении сообщения.
|
1
2
3
4
5
6
7
|
PostData postData = new PostData("Lorem Ipsum", "...", "...");Post post = new Post(postData);// save post...post = // retrieve existing post for updates// post.setContent("..."); // not possiblepost.updateData(new PostData("...", "...", "...")); // ensure that revision is created |
И вот как мы создаем ревизии.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
@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 added return; } ... // creates a revision PostData beforePostData = this.postData; this.revisions.add(0, new Post(beforePostData, this)); // store latest changes this.postData = newPostData; // limit to number of revisions to keep if (this.revisions.size() > ...) { // delete the excess ones for (...) { this.revisions.remove(this.revisions.size() - 1); } } ... } ...} |
Как я уже сказал, этот краткий пост. Дайте мне знать в комментариях ниже, если это то, что вы видели раньше, или, как и я, это дало вам момент «почему я не подумал об этом».
| Смотрите оригинальную статью здесь: Изменения и неизменность
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |