目錄
一、基礎(chǔ)概念
二、UML類圖
三、角色設(shè)計
四、案例分析
五、總結(jié)?
一、基礎(chǔ)概念
備忘錄模式是一種行為型設(shè)計模式,它允許保存一個對象的內(nèi)部狀態(tài)到一個備忘錄對象中,這樣就可以在需要的時候恢復(fù)這個對象的狀態(tài)了,同時又不違反封裝性原則。
這個模式的核心就是備忘錄對象,它負責存儲目標對象的內(nèi)部狀態(tài)信息,并且可以通過方法訪問這些狀態(tài)數(shù)據(jù)。而目標對象負責創(chuàng)建備忘錄對象,并在備忘錄對象中保存自身狀態(tài)。管理者角色負責存儲和恢復(fù)備忘錄對象,但是不能直接看到或者修改備忘錄對象中的狀態(tài)數(shù)據(jù)。?
二、UML類圖
三、角色設(shè)計
角色 | 描述 |
---|---|
發(fā)起人角色 | 負責創(chuàng)建一個備忘錄,記錄自身需要保存的狀態(tài),具備回滾的功能 |
備忘錄角色 | 用于存儲發(fā)起人角色的內(nèi)部狀態(tài),而且可以防止發(fā)起人角色以外的對象訪問權(quán)限 |
管理者角色 | 負責存儲、提供管理備忘錄角色,不可以修改備忘錄角色的內(nèi)容 |
四、案例分析
在我們?nèi)粘i_發(fā)中,必備的版本控制工具就是Git,可以提交版本,回滾到指定版本,下面我們就通過備忘錄設(shè)計模式來實現(xiàn)一個簡單的版本控制功能,代碼如下:
它扮演備忘錄角色,用于存儲某個時刻的狀態(tài)快照。它有兩個成員變量version和content,分別記錄版本號和內(nèi)容:
public class Commit {
private String version;
private String content;
public Commit(String version, String content) {
this.version = version;
this.content = content;
}
public String getVersion() {
return version;
}
public String getContent() {
return content;
}
}
Repository類是發(fā)起人角色,它管理具體的內(nèi)容。該類有一個成員變量content記錄內(nèi)容,以及setContent和getContent方法用于設(shè)置和獲取內(nèi)容。另外還有一個commit方法可以保存一個狀態(tài)快照,和一個rollback方法可以從快照恢復(fù)狀態(tài)。
public class Repository {
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Commit commit(String version) {
return new Commit(version, content);
}
public void rollback(Commit commit) {
content = commit.getContent();
}
}
Git類在這里是管理者角色,它持有一個Commit對象列表來記錄每次提交的備忘錄。該類提供了commit和rollback兩種方法,commit是保存新提交的備忘錄,rollback可以回滾到指定版本。
import java.util.ArrayList;
import java.util.List;
public class Git {
private List<Commit> commits = new ArrayList<>();
public void commit(Repository repo, String version) {
commits.add(repo.commit(version));
}
public void rollback(Repository repo, String version) {
for(Commit commit : commits) {
if(commit.getVersion().equals(version)) {
repo.rollback(commit);
break;
}
}
}
}
模擬一個客戶端,演示了這個存儲庫的基本用法。首先創(chuàng)建Repository和Git對象,然后新增幾個版本到存儲庫,最后回滾到第一個版本,在關(guān)鍵點會打印輸出內(nèi)容,以展示執(zhí)行流程。?
public class Client {
public static void main(String[] args) {
Repository repository = new Repository();
Git git = new Git();
repository.setContent("version 1");
git.commit(repository, "version 1");
repository.setContent("version 2");
git.commit(repository, "version 2");
repository.setContent("version 3");
git.commit(repository, "version 3");
git.rollback(repository, "version 1");
System.out.println(repository.getContent());
}
}
運行結(jié)果如下:?
整體上這個例子使用了備忘錄模式的三個主要角色,將狀態(tài)存入備忘錄對象,發(fā)起人負責狀態(tài)的管理和保存,管理者保存?zhèn)渫浀臍v史,從而實現(xiàn)了版本控制和回滾的功能。這就是一個使用備忘錄模式實現(xiàn)簡單Git版本控制的設(shè)計和執(zhí)行過程。?
五、總結(jié)?
優(yōu)點:
1、提供了保持對象內(nèi)部狀態(tài)歷史的能力,可以方便地將對象恢復(fù)到歷史某個狀態(tài)。
2、實現(xiàn)了內(nèi)部狀態(tài)的封裝,除了創(chuàng)建它的發(fā)起人之外,其他對象都不能訪問這些狀態(tài)信息。
3、簡化了發(fā)起人類,發(fā)起人不需要管理和保存其內(nèi)部狀態(tài)的各個歷史版本,所有狀態(tài)歷史由管理者完成。
缺點:
1、資源消耗大,如果要保存的歷史狀態(tài)很多,會占用較多內(nèi)存資源。
2、破壞了對象的封裝性,其他對象可以通過管理者訪問發(fā)起人的內(nèi)部狀態(tài)。
3、復(fù)雜度較高,需要維護發(fā)起人、備忘錄、管理者三個角色對象。
應(yīng)用場景:
1、需要保存對象在某個時刻的狀態(tài)快照,比如實現(xiàn)撤銷操作。
2、需要對對象的狀態(tài)歷史保持跟蹤,如游戲進度保存。
3、當對象的狀態(tài)變化復(fù)雜時,可以使用備忘錄模式保持對象內(nèi)部狀態(tài)的一致性。
4、當直接訪問封裝的對象需要暴露對象實現(xiàn)細節(jié)時,可以通過備忘錄間接訪問對象狀態(tài)。
符合的設(shè)計原則:
1、開閉原則(Open Close Principle)
開閉原則要求軟件實體應(yīng)對擴展開放,對修改關(guān)閉。備忘錄模式通過創(chuàng)建新的備忘錄類來保存和恢復(fù)對象狀態(tài),擴展了現(xiàn)有類的功能,而無需修改這些類的代碼。符合了對擴展開放的要求。
2、里氏替換原則(Liskov Substitution Principle)
備忘錄模式中,備忘錄類和原發(fā)器類都可以繼承于更通用的基類,符合里氏替換原則。?
3、單一職責原則(Single Responsibility Principle)
單一職責原則要求一個類只有一個引起它變化的原因。備忘錄模式中,原發(fā)器類負責業(yè)務(wù)邏輯,備忘錄類負責存儲狀態(tài),管理者類負責備忘錄的管理,每一個類都只有單一職責。
4、組合復(fù)用原則(Composite Reuse Principle)文章來源:http://www.zghlxwxcb.cn/news/detail-592891.html
備忘錄對象作為原發(fā)器對象狀態(tài)的組合,可以重復(fù)利用,遵守組合復(fù)用原則。?文章來源地址http://www.zghlxwxcb.cn/news/detail-592891.html
到了這里,關(guān)于Java設(shè)計模式之行為型-備忘錄模式(UML類圖+案例分析)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!