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

積木

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精品热视频| 免费久久99精品国产自| 欧美高清视频在线| 牛牛国产精品| 久久精品在这里| 香蕉国产精品偷在线观看不卡 | 国产精品99免费看| 欧美精品一区在线发布| 欧美波霸影院| 欧美日韩精品久久久| 欧美日韩调教| 国产日韩一区二区三区在线播放 | 欧美专区在线观看一区| 欧美一级大片在线免费观看| 亚洲乱码一区二区| 一区二区三区欧美成人| 亚洲一二三区视频在线观看| 亚洲大片在线| 亚洲一区二区免费| 久久综合国产精品| 亚洲麻豆视频| 欧美在线视频播放| 欧美电影免费观看高清| 欧美视频在线观看视频极品| 欧美日韩另类综合| 韩国精品在线观看| 亚洲午夜激情网页| 麻豆亚洲精品| 亚洲影院色在线观看免费| 篠田优中文在线播放第一区| 欧美在线视屏| 欧美日韩一二三区| 亚洲福利视频免费观看| 一区二区日韩| 欧美国产亚洲视频| 香蕉久久精品日日躁夜夜躁| 久久久久久久久久久一区| 你懂的视频一区二区| 国产精品v欧美精品v日本精品动漫| 国产日韩在线亚洲字幕中文| 巨胸喷奶水www久久久免费动漫| 欧美伦理a级免费电影| 国产精品久久久对白| 狠狠狠色丁香婷婷综合久久五月| 亚洲国产一区二区三区高清| 亚洲卡通欧美制服中文| 久久精品亚洲乱码伦伦中文| 奶水喷射视频一区| 午夜日韩在线| 国产精品极品美女粉嫩高清在线| 黄色一区三区| 久久大逼视频| 亚洲影视综合| 国产日韩欧美在线一区| 亚洲欧美精品伊人久久| 欧美肥婆在线| 久久综合久久综合这里只有精品 | 欧美绝品在线观看成人午夜影视| 国产农村妇女精品| 亚洲免费在线| 亚洲视频免费在线观看| 免费欧美在线视频| 亚洲国产高清aⅴ视频| 亚洲欧美国产一区二区三区| 久久久综合香蕉尹人综合网| 亚洲精品久久久蜜桃| 亚洲欧美日韩精品| 国产伦理一区| 久久精品在线播放| 久久久999国产| 亚洲人成免费| 欧美日韩免费一区二区三区| 亚洲丁香婷深爱综合| 久久精品首页| 老司机精品视频网站| 国产欧美日韩伦理| 久久精品人人做人人综合 | 最新日韩在线视频| 亚洲第一精品久久忘忧草社区| 久久av老司机精品网站导航| 国产精品99一区二区| 亚洲欧美区自拍先锋| 在线视频中文亚洲| 国产精品一区二区三区观看 | 久久久久久伊人| 久久偷看各类wc女厕嘘嘘偷窃| 国内成+人亚洲+欧美+综合在线| 欧美影视一区| 久久久亚洲国产天美传媒修理工| 精品白丝av| 亚洲国产精品综合| 国产精品久久久久久久久婷婷| 亚洲视频免费看| 亚洲一区二区三区四区中文| 99精品国产一区二区青青牛奶| 亚洲黄色成人网| 欧美视频精品在线观看| 亚洲欧美不卡| 久久久综合精品| 亚洲网站在线播放| 久久成人精品无人区| 亚洲国产成人高清精品| 亚洲日本理论电影| 国产亚洲精品激情久久| 欧美大色视频| 国产欧美日韩激情| 91久久中文| 精品99一区二区| 亚洲一品av免费观看| 在线看欧美视频| 亚洲视频第一页| 亚洲日本欧美天堂| 亚洲欧美日韩在线高清直播| 国产亚洲a∨片在线观看| 亚洲第一成人在线| 国产一区二区剧情av在线| 91久久精品美女| 国语自产在线不卡| 亚洲少妇自拍| 一区二区不卡在线视频 午夜欧美不卡'| 亚洲欧美成人精品| 在线视频你懂得一区二区三区| 久久精品人人做人人爽电影蜜月| 亚洲精品影视在线观看| 亚洲欧美日韩综合| 亚洲一区在线免费| 欧美日韩另类综合| 亚洲日本中文字幕| 亚洲精品日韩精品| 欧美mv日韩mv国产网站app| 国产精品久久久久久久久免费| 亚洲国产激情| 亚洲国产精品一区在线观看不卡 | 欧美成人免费在线观看| 欧美一区二区三区免费观看视频 | 欧美成人午夜激情视频| 午夜久久tv| 国产精品v欧美精品v日韩精品 | 免费h精品视频在线播放| 国产精品v日韩精品| 亚洲国产日韩一级| 亚洲人成网站在线播| 久久久久久久久一区二区| 午夜精品福利在线| 国产精品一区二区在线观看网站| 亚洲毛片av在线| 亚洲欧美激情四射在线日 | 久久久人成影片一区二区三区 | 一区二区三区欧美在线| 久久精品国产综合| 久久女同互慰一区二区三区| 欧美日韩一区二区视频在线观看| 亚洲成人自拍视频| 亚洲精品久久久久久一区二区| 久久久精品动漫| 亚洲高清一二三区| 中国女人久久久| 欧美精品18+| 一区二区日韩欧美| 久久久久久高潮国产精品视| 国产精品―色哟哟| 欧美一区二区视频网站| 久久尤物电影视频在线观看| 国产精品一级在线| 狂野欧美激情性xxxx| 亚洲国产综合在线看不卡| 亚洲精品资源美女情侣酒店| 另类图片综合电影| 日韩一区二区久久| 久久久久久久久久久久久久一区 | 欧美一区二区在线免费播放| 欧美色另类天堂2015| 亚洲一区在线免费观看| 久久久噜噜噜久久久| 亚洲国产一区二区在线| 欧美视频在线观看一区二区| 亚洲手机在线| 欧美福利电影在线观看| 日韩午夜一区| 国产精品美女久久| 久久亚洲综合网| 中文欧美在线视频| 欧美激情精品久久久久久变态 | 国产日韩欧美二区| 欧美国产高清| 欧美一级免费视频| 亚洲精品一区二区三区99| 欧美在线亚洲一区| 一本久久综合亚洲鲁鲁| 国产日韩一区二区三区在线播放 | 午夜欧美不卡精品aaaaa| 精品1区2区| 国产精品区免费视频| 老司机一区二区三区| 亚洲美女在线观看| 亚洲大胆人体在线| 欧美成黄导航| 久久精品国内一区二区三区| 亚洲国产高清视频| 精品成人a区在线观看|