青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

積木

No sub title

  C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
  140 Posts :: 1 Stories :: 11 Comments :: 0 Trackbacks

常用鏈接

留言簿(1)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

轉(zhuǎn)載自:http://patmusing.blog.163.com/blog/static/13583496020101501825958/


Aka. Token

在不破壞封裝性的前提下,捕獲一個對象的內(nèi)部狀態(tài),并在該對象之外保存其狀態(tài)這樣以后就可以將該對象恢復(fù)到原先保存的狀態(tài)。

“Without violating encapsulation, capture and externalize an object’s internal state so that the object can be restored to this state later.” – GoF

動機

有時候需要記錄一個對象的內(nèi)部狀態(tài)。比如要實現(xiàn)checkpoint或者undo這樣的機制,可以讓使用者從臨時性的操作跳出來或者需要修復(fù)錯誤的時候,你必須將狀態(tài)信息保存在某個地方,以便在進行某些操作后,將對象恢復(fù)到原來的狀態(tài)。但通常情況下,對象封裝了狀態(tài)(即私有成員變量),因此其他的對象無法訪問這些狀態(tài),而且也不可能將這些狀態(tài)保存在對象之外。如果將這些狀態(tài)設(shè)置成公有的,又會違反面向?qū)ο蠓庋b性的原則,同時也會削弱應(yīng)用的可靠性和可擴展性。

在軟件構(gòu)建過程中, 某些對象的狀態(tài)在轉(zhuǎn)換過程中,可能由于某種需要,要求程序能夠回溯到對象之前處于某個時刻的狀態(tài)。如果使用一些共有接口來讓其他對象得到對象的狀態(tài),便會暴露對象的細節(jié)實現(xiàn)。Memento設(shè)計模式就可以實現(xiàn)對象狀態(tài)的良好保存與恢復(fù),但同時又不會因此而破壞對象本身的封裝性。

UML類圖:

21. C++實現(xiàn)Behavioral - Memento模式 - 玄機逸士 - 玄機逸士博客

角色

- Memento

1. 保存Originator對象的內(nèi)部狀態(tài)。

2. Originator外,其他對象均不能訪問Memento對象。

- Originator

1. 創(chuàng)建一個包含其當(dāng)前內(nèi)部狀態(tài)快照的Memento對象。

2. 使用Memento對象來恢復(fù)其內(nèi)部狀態(tài)。

- Caretaker

1. Memento對象的容器。在C++中一般用stack來實現(xiàn)。

2. 從不對Memento對象的內(nèi)容進行檢查或操作。

示例代碼:

// Memento.h

#include <iostream>

#include <stack>

using namespace std;

// CMemento類,用來保存CRectangle的狀態(tài)

class CMemento

{

private: // 所有的成員變量和成員函數(shù)都是私有的

int topx; // 因此除友元類CRectangle外,其他對象都無法訪問

int topy;

int width;

int height;

private:

CMemento()

{

}

//private: // 1. 如果編寫了顯式拷貝構(gòu)造函數(shù),那么,它必須是公有的,

// CMemento(const CMemento& memo) // 否則CMementoStack將無法調(diào)用該拷貝構(gòu)造函數(shù)。

// { // 2. 如果沒有顯式的拷貝構(gòu)造函數(shù),那么缺省的拷貝構(gòu)造函數(shù)總是公有的。

// topx = memo.topx; // 3. Memento模式中,如果僅考慮保存一次狀態(tài),則

// topy = memo.topy; // CMementoStack是不必要的,那么拷貝構(gòu)造函數(shù),可以

// width = memo.width; // 顯式地聲明為private的,盡管在CRectanglecreate_memento

// height = memo.height; // 成員函數(shù)中也會調(diào)用CMemento的拷貝構(gòu)造函數(shù),但CRectangle

// } // CMemento的友元類,因此不存在這方面的限制。

private:

void set_state(int topx, int topy, int width, int height) // 保存CRectangle的狀態(tài)

{

this->topx = topx;

this->topy = topy;

this->width = width;

this->height = height;

}

friend class CRectangle; // 友元類CRectangle,可以訪問CMemento中的所有內(nèi)容

};

// CRectangle類。一個矩形,需要保存狀態(tài)改變的類

class CRectangle

{

private:

int topx; // 矩形左上角的x坐標(biāo)

int topy; // 矩形左上角的y坐標(biāo)

int width; // 矩形的寬

int height; // 矩形的高

public:

CRectangle(int topx, int topy, int width, int height):topx(topx), topy(topy), width(width), height(height)

{

}

// 模擬移動矩形的位置到指定的點,即改變了矩形的狀態(tài)

void move_to(int topx, int topy)

{

this->topx = topx;

this->topy = topy;

}

// 模擬改變矩形的長和寬,即改變了矩形的狀態(tài)

void change_width_height(int width, int height)

{

this->width = width;

this->height = height;

}

// 將矩形恢復(fù)到memo中所保存的狀態(tài)

void set_memento(CMemento memo)

{

this->topx = memo.topx;

this->topy = memo.topy;

this->width = memo.width;

this->height = memo.height;

}

// 將矩形的狀態(tài)保存到一個CMemento對象

CMemento create_memento()

{

CMemento cm;

cm.set_state(this->topx, this->topy, this->width, this->height);

return cm;

}

// 輸出矩形的狀態(tài)信息

void print_info()

{

cout << "Top left point's x coordinate: " << topx << endl;

cout << "Top left point's y coordinate: " << topy << endl;

cout << "The width is: " << width << endl;

cout << "The height is: " << height << endl;

}

};

// CMemento對象的容器,可以用來保存多個CMemento對象,通常用stack來實現(xiàn)

class CMementoStack

{

private:

stack<CMemento> stk;

public:

void add_memento(CMemento memo)

{

stk.push(memo); //CMemento對象壓入棧中

}

CMemento get_memento()

{

CMemento cm = stk.top(); // 取得CMemento對象。這個過程會用到CMemento類的拷貝構(gòu)造函數(shù),

// 由于CMemento對象中的成員變量均是普通類型(非指針、非類對象)

// 因此使用默認(rèn)的拷貝構(gòu)造函數(shù)即可

stk.pop(); // 刪除已經(jīng)取得的CMemento對象

return cm;

}

};

// Memento.cpp

#include "Memento.h"

int main(int argc, char **argv)

{

CRectangle cr(10, 10, 100, 100);

CMementoStack cs;

cout << "Initial states: " << endl;

cr.print_info();

CMemento cm0 = cr.create_memento(); // 將狀態(tài)保存到CMemento對象

cs.add_memento(cm0); // CMemento對象壓棧

// 第一次改變狀態(tài)

cr.change_width_height(200, 200); // 改變矩形的高度和寬度

cr.move_to(20, 20); // 改變矩形的位置

cout << "\nAfter 1st states changed: " << endl;

cr.print_info();

CMemento cm1 = cr.create_memento(); // 將狀態(tài)保存到CMemento對象

cs.add_memento(cm1); // CMemento對象壓棧

// 第二次改變狀態(tài)

cr.change_width_height(300, 300); // 改變矩形的高度和寬度

cr.move_to(30, 30); // 改變矩形的位置

cout << "\nAfter 2nd states changed: " << endl;

cr.print_info();

// ... 這里不再壓棧

// 恢復(fù)到第一次狀態(tài)的改變

cr.set_memento(cs.get_memento());

cout << "\nStates restored to 1st change: " << endl;

cr.print_info();

// 恢復(fù)到初始狀態(tài)

cr.set_memento(cs.get_memento());

cout << "\nStates restored to initial: " << endl;

cr.print_info();

}

運行結(jié)果:

Initial states:

Top left point's x coordinate: 10

Top left point's y coordinate: 10

The width is: 100

The height is: 100

After 1st states changed:

Top left point's x coordinate: 20

Top left point's y coordinate: 20

The width is: 200

The height is: 200

After 2nd states changed:

Top left point's x coordinate: 30

Top left point's y coordinate: 30

The width is: 300

The height is: 300

States restored to 1st change:

Top left point's x coordinate: 20

Top left point's y coordinate: 20

The width is: 200

The height is: 200

States restored to initial:

Top left point's x coordinate: 10

Top left point's y coordinate: 10

The width is: 100

The height is: 100

結(jié)果符合預(yù)期。

補充說明:

1. 未設(shè)置其成員變量為public的前提下,在對象的外部保存一個其狀態(tài),頗需技巧,而且用不同語言來實現(xiàn)的時候也有所不同。

a. 對于C++,通常使用友元類來實現(xiàn)。

b. 對于C#,使用internal關(guān)鍵字。

c. 對于Java,使用package protected訪問控制。

與其處于相同包中的子類,和處于相同包中的其它類均可以訪問pakcage protected的對象或變量。

Java中的訪問權(quán)限有public,private,protected和默認(rèn)的包訪問權(quán)限,如果類中的屬性方法沒有顯示的指明訪問權(quán)

限,則具有包訪問權(quán)限,很多人也稱它為friendly訪問權(quán)限,也有人稱為packeged權(quán)限,而packagedfriendly

這兩個關(guān)鍵字在實際中都是不存在的。在Java中,訪問權(quán)限修飾符權(quán)限從高到低是publicprotected,package

protected,private。

d. C++, C#Java均可使用內(nèi)部類的方式來實現(xiàn)類似的功能,不過對于“將狀態(tài)存儲于對象之外”而言,稍嫌勉強。

2. 關(guān)于拷貝構(gòu)造函數(shù),請看:http://patmusing.blog.163.com/blog/static/1358349602009113061024796/

3. 關(guān)于友元類,請看:http://patmusing.blog.163.com/blog/static/1358349602010182331153/



posted on 2013-03-08 14:51 Jacc.Kim 閱讀(218) 評論(0)  編輯 收藏 引用 所屬分類: 設(shè)計模式
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            一本色道久久综合亚洲精品小说| 欧美三日本三级少妇三99| 欧美激情一区二区三区高清视频 | 国产精品一区二区在线观看网站 | 久久久青草婷婷精品综合日韩| 亚洲黄色在线观看| 亚洲精品免费在线观看| 欧美福利视频在线| 久久福利精品| 黄色日韩网站| 午夜亚洲伦理| 91久久精品一区二区别| 欧美激情亚洲另类| 欧美三级电影一区| 亚洲国产电影| 久久天堂精品| 国产亚洲免费的视频看| 亚洲电影成人| 永久免费精品影视网站| 欧美伊人久久| 欧美伊人久久久久久久久影院 | 美女主播视频一区| 亚洲巨乳在线| 亚洲专区在线视频| 久久av一区二区三区| 另类专区欧美制服同性| 亚洲第一网站| 午夜在线a亚洲v天堂网2018| 久久一区中文字幕| 国产精品综合色区在线观看| 91久久精品www人人做人人爽| 亚洲女人天堂av| 亚洲成人自拍视频| 欧美永久精品| 国产精品欧美久久久久无广告| 国内精品久久国产| 亚洲欧美网站| 亚洲人成人一区二区三区| 午夜精品久久久久久久男人的天堂| 噜噜噜久久亚洲精品国产品小说| 国产精品久久久久久久久借妻| 亚洲国产精品久久久久秋霞蜜臀 | 久久久久久久一区二区| 亚洲国产精品热久久| 久久成人人人人精品欧| 欧美小视频在线观看| 亚洲国产一二三| 久久久久国产成人精品亚洲午夜| 日韩一级网站| 欧美成人精品h版在线观看| 国产午夜精品视频| 欧美一区亚洲| 午夜在线一区| 国产日韩精品视频一区| 亚洲视频 欧洲视频| 亚洲人成亚洲人成在线观看| 久久亚洲精品一区| 亚洲第一网站| 欧美激情偷拍| 欧美精品久久久久久久免费观看 | 好看的av在线不卡观看| 性欧美在线看片a免费观看| 99视频+国产日韩欧美| 欧美成人网在线| 最新国产成人在线观看| 欧美成人免费小视频| 欧美在线视频播放| 精品成人一区二区| 美女福利精品视频| 美女任你摸久久| 1024欧美极品| 欧美韩国在线| 欧美日韩ab片| 亚洲欧美清纯在线制服| 亚洲一区二区三区四区视频| 国产伦一区二区三区色一情| 久久九九精品99国产精品| 久久精品中文字幕一区二区三区| 好看的亚洲午夜视频在线| 美国十次成人| 欧美另类一区| 久久精品免费电影| 欧美成人午夜剧场免费观看| 亚洲午夜在线视频| 免费在线欧美视频| 欧美精品一线| 久久国产一区二区| 久久综合成人精品亚洲另类欧美| 亚洲精选大片| 午夜精品福利电影| 亚洲欧洲日韩女同| 在线视频你懂得一区| 国产一区二区三区免费观看| 欧美成人a∨高清免费观看| 欧美日韩三级视频| 久久综合色天天久久综合图片| 欧美sm极限捆绑bd| 欧美一级大片在线观看| 久久综合狠狠综合久久综合88| 一区二区三区产品免费精品久久75 | 国产亚洲午夜高清国产拍精品| 麻豆国产va免费精品高清在线| 欧美精品一区二区三区蜜桃| 欧美怡红院视频一区二区三区| 免费亚洲一区| 欧美在线观看www| 欧美精品大片| 欧美aa国产视频| 国产美女搞久久| 99riav1国产精品视频| 黄色影院成人| 亚洲制服少妇| 这里是久久伊人| 久久综合久久久| 久久精品人人爽| 欧美性开放视频| 亚洲国产mv| 在线电影院国产精品| 亚洲欧美成人| 国产麻豆91精品| 日韩午夜一区| 日韩视频第一页| 美女亚洲精品| 久久综合给合久久狠狠狠97色69| 国产精品免费看久久久香蕉| 亚洲毛片av| 亚洲精品日韩激情在线电影| 欧美在线看片| 久久久久久噜噜噜久久久精品| 国产精品国产成人国产三级| 亚洲人成人一区二区在线观看| 亚洲欧洲一区二区天堂久久| 久久久精品国产免大香伊| 久久久国产精品一区二区三区| 国产精品久久久久久久久免费桃花 | 亚洲人成啪啪网站| 亚洲精品一区二区三区樱花 | 欧美精品一区三区| 国产精品v欧美精品v日韩| 欧美性久久久| 亚洲免费成人av| 免费不卡视频| 午夜在线观看欧美| 欧美视频在线观看视频极品| 欧美视频一区在线观看| 久久久综合激的五月天| 在线一区视频| 亚洲小说欧美另类婷婷| 欧美极品在线播放| 99视频+国产日韩欧美| 亚洲女性裸体视频| 国产精品久久久久久久久免费桃花| 一区二区av在线| 欧美一级精品大片| 国产日韩欧美一区二区三区在线观看| 亚洲一区二区三区四区视频| 欧美亚洲自偷自偷| 国产精品久久久久9999| 欧美在线观看网址综合| 免费观看日韩| 一二三四社区欧美黄| 国产精品久久久久av| 亚洲欧美日韩天堂| 免费成年人欧美视频| 一本色道久久综合亚洲精品婷婷| 欧美色视频一区| 久久精品免费观看| 亚洲第一伊人| 亚洲——在线| 极品日韩久久| 欧美激情视频一区二区三区在线播放| 欧美午夜性色大片在线观看| 欧美日韩和欧美的一区二区| 国产精品一区在线观看| 亚洲黄色尤物视频| 玖玖精品视频| 久久人人精品| 国内精品**久久毛片app| 亚洲综合色自拍一区| 欧美国产日韩一区二区在线观看| 亚洲第一主播视频| 久久av在线| 伊人久久大香线| 欧美日韩成人综合| 欧美伊人影院| 亚洲午夜黄色| 亚洲国产欧洲综合997久久| 亚洲在线中文字幕| 在线观看国产精品网站| 国产精品久久久久77777| 久久中文欧美| 欧美一级大片在线观看| 日韩视频在线观看一区二区| 久久免费精品视频| 午夜精品久久一牛影视| 亚洲欧洲精品一区二区精品久久久| 国产精品自在在线| 欧美午夜精品| 欧美日韩成人网| 欧美国产日韩一区二区|