中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站建設(shè)制作作業(yè)外鏈優(yōu)化

網(wǎng)站建設(shè)制作作業(yè),外鏈優(yōu)化,紅花崗區(qū)住房和城鄉(xiāng)建設(shè)局網(wǎng)站,該網(wǎng)站的域名為文章目錄 一、什么是備忘錄模式1、備忘錄模式使用場(chǎng)景2、備忘錄模式優(yōu)缺點(diǎn)3、備忘錄模式的三大角色4、白箱備忘錄和黑箱備忘錄5、思考:備份頻率快,備份對(duì)象大的備忘錄應(yīng)該如何設(shè)計(jì) 二、實(shí)例1、備忘錄模式的一般寫法2、使用棧管理富文本編輯器3、游戲狀態(tài)…

文章目錄

  • 一、什么是備忘錄模式
    • 1、備忘錄模式使用場(chǎng)景
    • 2、備忘錄模式優(yōu)缺點(diǎn)
    • 3、備忘錄模式的三大角色
    • 4、白箱備忘錄和黑箱備忘錄
    • 5、思考:備份頻率快,備份對(duì)象大的備忘錄應(yīng)該如何設(shè)計(jì)
  • 二、實(shí)例
    • 1、備忘錄模式的一般寫法
    • 2、使用棧管理富文本編輯器
    • 3、游戲狀態(tài)恢復(fù)案例
      • (1)“白箱”備忘錄模式
      • (2)“黑箱”備忘錄模式

一、什么是備忘錄模式

備忘錄模式(Memento Pattern)又稱為快照模式(Snapshot Pattern)或令牌模式(Token Pattern),是指在不破壞封裝的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在對(duì)象之外保存這個(gè)狀態(tài)。這樣以后就可將該對(duì)象恢復(fù)到原先保存的狀態(tài),屬于行為型模式。

在軟件系統(tǒng)中,備忘錄模式可以為我們提供一種“后悔藥”的機(jī)制,它通過存儲(chǔ)系統(tǒng)各個(gè)歷史狀態(tài)的快照,使得我們可以在任一時(shí)刻將系統(tǒng)回滾到某一個(gè)歷史狀態(tài)。

備忘錄模式本質(zhì)是從發(fā)起人實(shí)體類(Originator)隔離存儲(chǔ)功能,降低實(shí)體類的職責(zé)。同時(shí)由于存儲(chǔ)信息(Memento)獨(dú)立,且存儲(chǔ)信息的實(shí)體交由管理類(Caretaker)管理,則可以通過為管理類擴(kuò)展額外的功能對(duì)存儲(chǔ)信息進(jìn)行擴(kuò)展操作(比如增加歷史快照功能)。

1、備忘錄模式使用場(chǎng)景

  • 需要保存歷史快照的場(chǎng)景。
  • 希望在對(duì)象之外保存狀態(tài),且除了自己其他類對(duì)象無法訪問狀態(tài)保存具體內(nèi)容。

比如,玩游戲時(shí)的中間結(jié)果的存檔功能、如 Word、記事本、Photoshop,idea等軟件在編輯時(shí)按Ctrl+Z 組合鍵,還有數(shù)據(jù)庫中事務(wù)操作。

2、備忘錄模式優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

  • 提供了一種可以恢復(fù)狀態(tài)的機(jī)制。當(dāng)用戶需要時(shí)能夠比較方便地將數(shù)據(jù)恢復(fù)到某個(gè)歷史的狀態(tài)。
  • 實(shí)現(xiàn)了內(nèi)部狀態(tài)的封裝。除了創(chuàng)建它的發(fā)起人之外,其他對(duì)象都不能夠訪問這些狀態(tài)信息。
  • 簡(jiǎn)化了發(fā)起人類。發(fā)起人不需要管理和保存其內(nèi)部狀態(tài)的各個(gè)備份,所有狀態(tài)信息都保存在備忘錄中,并由管理者進(jìn)行管理,這符合單一職責(zé)原則。

缺點(diǎn):

  • 資源消耗大。如果要保存的內(nèi)部狀態(tài)信息過多或者特別頻繁,將會(huì)占用比較大的內(nèi)存資源。
  • 如果需要保存的狀態(tài)過多時(shí),每一次保存都會(huì)消耗很多內(nèi)存。

3、備忘錄模式的三大角色

在這里插入圖片描述
備忘錄模式的主要角色如下:

  • 發(fā)起人(Originator)角色:記錄當(dāng)前時(shí)刻的內(nèi)部狀態(tài)信息,提供創(chuàng)建備忘錄和恢復(fù)備忘錄數(shù)據(jù)的功能,實(shí)現(xiàn)其他業(yè)務(wù)功能,它可以訪問備忘錄里的所有信息。
  • 備忘錄(Memento)角色:負(fù)責(zé)存儲(chǔ)發(fā)起人的內(nèi)部狀態(tài),在需要的時(shí)候提供這些內(nèi)部狀態(tài)給發(fā)起人,且防止發(fā)起人以外的對(duì)象訪問。
  • 管理者(Caretaker)角色:對(duì)備忘錄進(jìn)行管理,提供保存與獲取備忘錄的功能,但其不能對(duì)備忘錄的內(nèi)容進(jìn)行訪問與修改。

4、白箱備忘錄和黑箱備忘錄

備忘錄有兩個(gè)等效的接口:

  • 窄接口:管理者(Caretaker)對(duì)象(和其他發(fā)起人對(duì)象之外的任何對(duì)象)看到的是備忘錄的窄接口(narror Interface),這個(gè)窄接口只允許他把備忘錄對(duì)象傳給其他的對(duì)象。
  • 寬接口:與管理者看到的窄接口相反,發(fā)起人對(duì)象可以看到一個(gè)寬接口(wide Interface),這個(gè)寬接口允許它讀取所有的數(shù)據(jù),以便根據(jù)這些數(shù)據(jù)恢復(fù)這個(gè)發(fā)起人對(duì)象的內(nèi)部狀態(tài)。

白箱備忘錄使用的就是寬接口,白箱備忘錄模式是破壞封裝性的。但是通過程序員自律,同樣可以在一定程度上實(shí)現(xiàn)模式的大部分用意。

黑箱備忘錄使用的是窄接口,將備忘錄角色封裝在發(fā)起人角色的內(nèi)部形成一個(gè)私有的內(nèi)部類,并實(shí)現(xiàn)窄接口。管理者只管理窄接口,這樣可以屏蔽備忘錄角色的細(xì)節(jié)。

5、思考:備份頻率快,備份對(duì)象大的備忘錄應(yīng)該如何設(shè)計(jì)

假設(shè)每當(dāng)有數(shù)據(jù)改動(dòng),我們都需要生成一個(gè)備份,以備之后恢復(fù)。如果需要備份的數(shù)據(jù)很大,這樣高頻率的備份,不管是對(duì)存儲(chǔ)(內(nèi)存或者硬盤)的消耗,還是對(duì)時(shí)間的消耗,都可能是無法接受的。想要解決這個(gè)問題,我們一般會(huì)采用“低頻率全量備份”和“高頻率增量備份”相結(jié)合的方法。

當(dāng)我們需要恢復(fù)到某一時(shí)間點(diǎn)的備份的時(shí)候,如果這一時(shí)間點(diǎn)有做全量備份,我們直接拿來恢復(fù)就可以了。如果這一時(shí)間點(diǎn)沒有對(duì)應(yīng)的全量備份,我們就先找到最近的一次全量備份,然后用它來恢復(fù),之后執(zhí)行此次全量備份跟這一時(shí)間點(diǎn)之間的所有增量備份,也就是對(duì)應(yīng)的操作或者數(shù)據(jù)變動(dòng)。這樣就能減少全量備份的數(shù)量和頻率,減少對(duì)時(shí)間、內(nèi)存的消耗。

其實(shí)很多設(shè)計(jì)原則和設(shè)計(jì)思想都是互通的,mysql的備份與恢復(fù)、redis的備份與恢復(fù)都是參考了這種實(shí)現(xiàn)原理。

二、實(shí)例

1、備忘錄模式的一般寫法

// 發(fā)起人角色
public class Originator {// 內(nèi)部狀態(tài)private String state;public String getState() {return this.state;}public void setState(String state) {this.state = state;}// 創(chuàng)建一個(gè)備忘錄public Memento createMemento() {return new Memento(this.state);}// 從備忘錄恢復(fù)public void restoreMemento(Memento memento) {this.setState(memento.getState());}
}
// 備忘錄角色
public class Memento {private String state;public Memento(String state){this.state = state;}public String getState() {return this.state;}public void setState(String state) {this.state = state;}
}
// 管理者角色
public class Caretaker {// 備忘錄對(duì)象private Memento memento;public Memento getMemento() {return this.memento;}public void storeMemento(Memento memento) {this.memento = memento;}}
// 測(cè)試類
public class Test {public static void main(String[] args) {//來一個(gè)發(fā)起人Originator originator = new Originator();//來一個(gè)備忘錄管理員Caretaker caretaker = new Caretaker();//管理員存儲(chǔ)發(fā)起人的備忘錄caretaker.storeMemento(originator.createMemento());//發(fā)起人從管理員獲取備忘錄進(jìn)行回滾originator.restoreMemento(caretaker.getMemento());}
}

2、使用棧管理富文本編輯器

我們使用富文本編輯器時(shí),會(huì)經(jīng)常寫入、撤銷、修改。因此我們需要將每一時(shí)刻的修改記錄都要保存在草稿箱中。

// 發(fā)起人角色編輯器
public class Editor {private String title;private String content;private String imgs;public Editor(String title, String content, String imgs) {this.title = title;this.content = content;this.imgs = imgs;}public String getTitle() {return title;}public String getContent() {return content;}public String getImgs() {return imgs;}public void setTitle(String title) {this.title = title;}public void setContent(String content) {this.content = content;}public void setImgs(String imgs) {this.imgs = imgs;}public ArticleMemento saveToMemento(){ArticleMemento articleMemento = new ArticleMemento(this.title,this.content,this.imgs);return articleMemento;}public void undoFromMemento(ArticleMemento articleMemento){this.title = articleMemento.getTitle();this.content = articleMemento.getContent();this.imgs = articleMemento.getImgs();}@Overridepublic String toString() {return "Editor{" +"title='" + title + '\'' +", content='" + content + '\'' +", imgs='" + imgs + '\'' +'}';}
}
// 備忘錄角色
public class ArticleMemento {private String title;private String content;private String imgs;public ArticleMemento(String title, String content, String imgs) {this.title = title;this.content = content;this.imgs = imgs;}public String getTitle() {return title;}public String getContent() {return content;}public String getImgs() {return imgs;}@Overridepublic String toString() {return "ArticleMemento{" +"title='" + title + '\'' +", content='" + content + '\'' +", imgs='" + imgs + '\'' +'}';}
}
// 管理角色 草稿箱
public class DraftsBox {private final Stack<ArticleMemento> STACK = new Stack<ArticleMemento>();public ArticleMemento getMemento(){ArticleMemento articleMemento = STACK.pop();return articleMemento;}public void addMemento(ArticleMemento articleMemento){STACK.push(articleMemento);}}

草稿箱中定義的Stack類是Vector的一個(gè)子類,它實(shí)現(xiàn)了一個(gè)標(biāo)準(zhǔn)的后進(jìn)先出的棧。主要定義了以下方法:

方法定義方法描述
boolean empty()測(cè)試棧是否為空
Object peek()查看棧頂對(duì)象,但不從棧中移除它
Object pop()移除棧頂對(duì)象,并作為此函數(shù)的返回值
Object push(Object element)把對(duì)象壓入棧頂
int search(Object element)返回對(duì)象在棧中的位置,以1為基數(shù)
// 測(cè)試類
public class Test {public static void main(String[] args) {DraftsBox draftsBox = new DraftsBox();Editor editor = new Editor("標(biāo)題1","內(nèi)容1","圖片1");ArticleMemento articleMemento = editor.saveToMemento();draftsBox.addMemento(articleMemento);System.out.println("標(biāo)題:" + editor.getTitle() + "\n" +"內(nèi)容:" + editor.getContent() + "\n" +"插圖:" + editor.getImgs() + "\n暫存成功");System.out.println("完整的信息" + editor);System.out.println("==========首次修改文章===========");editor.setTitle("標(biāo)題2");editor.setContent("內(nèi)容2");editor.setImgs("圖片2");System.out.println("==========首次修改文章完成===========");System.out.println("完整的信息" + editor);articleMemento = editor.saveToMemento();draftsBox.addMemento(articleMemento);System.out.println("==========保存到草稿箱===========");System.out.println("==========第2次修改文章===========");editor.setTitle("標(biāo)題3");editor.setContent("內(nèi)容3");editor.setImgs("圖片3");System.out.println("完整的信息" + editor);System.out.println("==========第2次修改文章完成===========");System.out.println("==========第1次撤銷===========");articleMemento = draftsBox.getMemento();editor.undoFromMemento(articleMemento);System.out.println("完整的信息" + editor);System.out.println("==========第1次撤銷完成===========");System.out.println("==========第2次撤銷===========");articleMemento = draftsBox.getMemento();editor.undoFromMemento(articleMemento);System.out.println("完整的信息" + editor);System.out.println("==========第2次撤銷完成===========");}
}

執(zhí)行結(jié)果:
在這里插入圖片描述

3、游戲狀態(tài)恢復(fù)案例

游戲中的某個(gè)場(chǎng)景,一游戲角色有生命力、攻擊力、防御力等數(shù)據(jù),在打Boss前和后一定會(huì)不一樣的,我們?cè)试S玩家如果感覺與Boss決斗的效果不理想可以讓游戲恢復(fù)到?jīng)Q斗之前的狀態(tài)。

(1)“白箱”備忘錄模式

備忘錄角色對(duì)任何對(duì)象都提供一個(gè)接口,即寬接口,備忘錄角色的內(nèi)部所存儲(chǔ)的狀態(tài)就對(duì)所有對(duì)象公開。類圖如下:
在這里插入圖片描述

//游戲角色類
public class GameRole {private int vit; //生命力private int atk; //攻擊力private int def; //防御力//初始化狀態(tài)public void initState() {this.vit = 100;this.atk = 100;this.def = 100;}//戰(zhàn)斗public void fight() {this.vit = 0;this.atk = 0;this.def = 0;}//保存角色狀態(tài)public RoleStateMemento saveState() {return new RoleStateMemento(vit, atk, def);}//回復(fù)角色狀態(tài)public void recoverState(RoleStateMemento roleStateMemento) {this.vit = roleStateMemento.getVit();this.atk = roleStateMemento.getAtk();this.def = roleStateMemento.getDef();}public void stateDisplay() {System.out.println("角色生命力:" + vit);System.out.println("角色攻擊力:" + atk);System.out.println("角色防御力:" + def);}public int getVit() {return vit;}public void setVit(int vit) {this.vit = vit;}public int getAtk() {return atk;}public void setAtk(int atk) {this.atk = atk;}public int getDef() {return def;}public void setDef(int def) {this.def = def;}
}
//游戲狀態(tài)存儲(chǔ)類(備忘錄類)
public class RoleStateMemento {private int vit;private int atk;private int def;public RoleStateMemento(int vit, int atk, int def) {this.vit = vit;this.atk = atk;this.def = def;}public int getVit() {return vit;}public void setVit(int vit) {this.vit = vit;}public int getAtk() {return atk;}public void setAtk(int atk) {this.atk = atk;}public int getDef() {return def;}public void setDef(int def) {this.def = def;}
}
//角色狀態(tài)管理者類
public class RoleStateCaretaker {private RoleStateMemento roleStateMemento;public RoleStateMemento getRoleStateMemento() {return roleStateMemento;}public void setRoleStateMemento(RoleStateMemento roleStateMemento) {this.roleStateMemento = roleStateMemento;}
}
//測(cè)試類
public class Client {public static void main(String[] args) {System.out.println("------------大戰(zhàn)Boss前------------");//大戰(zhàn)Boss前GameRole gameRole = new GameRole();gameRole.initState();gameRole.stateDisplay();//保存進(jìn)度RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();roleStateCaretaker.setRoleStateMemento(gameRole.saveState());System.out.println("------------大戰(zhàn)Boss后------------");//大戰(zhàn)Boss時(shí),損耗嚴(yán)重gameRole.fight();gameRole.stateDisplay();System.out.println("------------恢復(fù)之前狀態(tài)------------");//恢復(fù)之前狀態(tài)gameRole.recoverState(roleStateCaretaker.getRoleStateMemento());gameRole.stateDisplay();}
}

分析:白箱備忘錄模式是破壞封裝性的。但是通過程序員自律,同樣可以在一定程度上實(shí)現(xiàn)模式的大部分用意。

(2)“黑箱”備忘錄模式

備忘錄角色對(duì)發(fā)起人對(duì)象提供一個(gè)寬接口,而為其他對(duì)象提供一個(gè)窄接口。在Java語言中,實(shí)現(xiàn)雙重接口的辦法就是將備忘錄類設(shè)計(jì)成發(fā)起人類的內(nèi)部成員類。

將 RoleStateMemento 設(shè)為 GameRole 的內(nèi)部類,從而將 RoleStateMemento 對(duì)象封裝在GameRole 里面;在外面提供一個(gè)標(biāo)識(shí)接口 Memento 給 RoleStateCaretaker 及其他對(duì)象使用。
這樣 GameRole 類看到的是 RoleStateMemento 所有的接口,而 RoleStateCaretaker 及其他對(duì)象看到的僅僅是標(biāo)識(shí)接口 Memento 所暴露出來的接口,從而維護(hù)了封裝型。類圖如下:
在這里插入圖片描述

// 窄接口 Memento ,這是一個(gè)標(biāo)識(shí)接口,因此沒有定義出任何的方法
public interface Memento {
}
// 定義發(fā)起人類 GameRole ,并在內(nèi)部定義備忘錄內(nèi)部類 RoleStateMemento (該內(nèi)部類設(shè)置為私有的)
//游戲角色類
public class GameRole {private int vit; //生命力private int atk; //攻擊力private int def; //防御力//初始化狀態(tài)public void initState() {this.vit = 100;this.atk = 100;this.def = 100;}//戰(zhàn)斗public void fight() {this.vit = 0;this.atk = 0;this.def = 0;}//保存角色狀態(tài)public Memento saveState() {return new RoleStateMemento(vit, atk, def);}//回復(fù)角色狀態(tài)public void recoverState(Memento memento) {RoleStateMemento roleStateMemento = (RoleStateMemento) memento;this.vit = roleStateMemento.getVit();this.atk = roleStateMemento.getAtk();this.def = roleStateMemento.getDef();}public void stateDisplay() {System.out.println("角色生命力:" + vit);System.out.println("角色攻擊力:" + atk);System.out.println("角色防御力:" + def);}public int getVit() {return vit;}public void setVit(int vit) {this.vit = vit;}public int getAtk() {return atk;}public void setAtk(int atk) {this.atk = atk;}public int getDef() {return def;}public void setDef(int def) {this.def = def;}// 備忘錄角色內(nèi)部類private class RoleStateMemento implements Memento {private int vit;private int atk;private int def;public RoleStateMemento(int vit, int atk, int def) {this.vit = vit;this.atk = atk;this.def = def;}public int getVit() {return vit;}public void setVit(int vit) {this.vit = vit;}public int getAtk() {return atk;}public void setAtk(int atk) {this.atk = atk;}public int getDef() {return def;}public void setDef(int def) {this.def = def;}}
}

負(fù)責(zé)人角色類 RoleStateCaretaker 能夠得到的備忘錄對(duì)象是以 Memento 為接口的,由于這個(gè)接口僅僅是一個(gè)標(biāo)識(shí)接口,因此負(fù)責(zé)人角色不可能改變這個(gè)備忘錄對(duì)象的內(nèi)容

//角色狀態(tài)管理者類
public class RoleStateCaretaker {private Memento memento;public Memento getMemento() {return memento;}public void setMemento(Memento memento) {this.memento = memento;}
}
// 測(cè)試類
public class Client {public static void main(String[] args) {System.out.println("------------大戰(zhàn)Boss前------------");//大戰(zhàn)Boss前GameRole gameRole = new GameRole();gameRole.initState();gameRole.stateDisplay();//保存進(jìn)度RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();roleStateCaretaker.setMemento(gameRole.saveState());System.out.println("------------大戰(zhàn)Boss后------------");//大戰(zhàn)Boss時(shí),損耗嚴(yán)重gameRole.fight();gameRole.stateDisplay();System.out.println("------------恢復(fù)之前狀態(tài)------------");//恢復(fù)之前狀態(tài)gameRole.recoverState(roleStateCaretaker.getMemento());gameRole.stateDisplay();}
}

http://www.risenshineclean.com/news/2705.html

相關(guān)文章:

  • 做網(wǎng)站為什么需要服務(wù)器關(guān)鍵詞歌詞完整版
  • 寶塔建設(shè)網(wǎng)站教程2023必考十大時(shí)政熱點(diǎn)
  • 免費(fèi)建個(gè)網(wǎng)站推廣產(chǎn)品怎么發(fā)朋友圈
  • b站戶外打野如何申請(qǐng)域名
  • 網(wǎng)站建設(shè)與用戶需求分析制作網(wǎng)站費(fèi)用
  • 建站加盟百度注冊(cè)入口
  • 濰坊營(yíng)銷型網(wǎng)站建設(shè)防止惡意點(diǎn)擊軟件管用嗎
  • 做論壇網(wǎng)站要辦理什么證件百度站長(zhǎng)工具抓取診斷
  • 古田住房與建設(shè)局網(wǎng)站aso優(yōu)化違法嗎
  • 用sublime text做網(wǎng)站查詢網(wǎng)站服務(wù)器
  • 哪里做網(wǎng)站比較好關(guān)鍵詞的作用
  • 做網(wǎng)站實(shí)名認(rèn)證總是失敗怎么回事我們seo
  • 北京網(wǎng)站設(shè)計(jì)公司youx成都柚米科技15寧波seo外包推廣排名
  • 門戶網(wǎng)站廣告是什么專門做排名的軟件
  • nba網(wǎng)站建設(shè)營(yíng)銷技巧五步推銷法
  • 做資源網(wǎng)站需要什么seo優(yōu)化關(guān)鍵詞0
  • 深圳建工是國(guó)企還是私企武漢seo公司哪家好
  • 尋找做網(wǎng)站的廣告網(wǎng)站策劃方案
  • 幫你省網(wǎng)站怎么做優(yōu)秀的軟文廣告案例
  • 有贊商城官網(wǎng)登錄旺道seo網(wǎng)站優(yōu)化大師
  • 常平網(wǎng)站仿做百度手機(jī)衛(wèi)士
  • 網(wǎng)站優(yōu)化網(wǎng)千鋒教育培訓(xùn)機(jī)構(gòu)怎么樣
  • 做色情網(wǎng)站多久會(huì)被抓網(wǎng)絡(luò)營(yíng)銷服務(wù)
  • 泉州市住房和城鄉(xiāng)建設(shè)部網(wǎng)站南寧網(wǎng)站優(yōu)化公司電話
  • 自制游戲軟件seo怎樣
  • 網(wǎng)站做維恩圖公司網(wǎng)站制作教程
  • 合肥軟件外包公司關(guān)鍵詞優(yōu)化排名查詢
  • 南寧微信網(wǎng)站制作周口網(wǎng)絡(luò)推廣哪家好
  • 做網(wǎng)站優(yōu)化要多少錢廣州網(wǎng)絡(luò)seo優(yōu)化
  • 網(wǎng)站名字大全有哪些鄭州網(wǎng)站優(yōu)化外包