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

積木

No sub title

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

常用鏈接

留言簿(1)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

轉載自:http://patmusing.blog.163.com/blog/static/13583496020101501825958/


Aka. Token

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

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

動機

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

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

UML類圖:

21. C++實現Behavioral - Memento模式 - 玄機逸士 - 玄機逸士博客

角色

- Memento

1. 保存Originator對象的內部狀態。

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

- Originator

1. 創建一個包含其當前內部狀態快照的Memento對象。

2. 使用Memento對象來恢復其內部狀態。

- Caretaker

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

2. 從不對Memento對象的內容進行檢查或操作。

示例代碼:

// Memento.h

#include <iostream>

#include <stack>

using namespace std;

// CMemento類,用來保存CRectangle的狀態

class CMemento

{

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

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

int topy;

int width;

int height;

private:

CMemento()

{

}

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

// CMemento(const CMemento& memo) // 否則CMementoStack將無法調用該拷貝構造函數。

// { // 2. 如果沒有顯式的拷貝構造函數,那么缺省的拷貝構造函數總是公有的。

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

// topy = memo.topy; // CMementoStack是不必要的,那么拷貝構造函數,可以

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

// height = memo.height; // 成員函數中也會調用CMemento的拷貝構造函數,但CRectangle

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

private:

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

{

this->topx = topx;

this->topy = topy;

this->width = width;

this->height = height;

}

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

};

// CRectangle類。一個矩形,需要保存狀態改變的類

class CRectangle

{

private:

int topx; // 矩形左上角的x坐標

int topy; // 矩形左上角的y坐標

int width; // 矩形的寬

int height; // 矩形的高

public:

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

{

}

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

void move_to(int topx, int topy)

{

this->topx = topx;

this->topy = topy;

}

// 模擬改變矩形的長和寬,即改變了矩形的狀態

void change_width_height(int width, int height)

{

this->width = width;

this->height = height;

}

// 將矩形恢復到memo中所保存的狀態

void set_memento(CMemento memo)

{

this->topx = memo.topx;

this->topy = memo.topy;

this->width = memo.width;

this->height = memo.height;

}

// 將矩形的狀態保存到一個CMemento對象

CMemento create_memento()

{

CMemento cm;

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

return cm;

}

// 輸出矩形的狀態信息

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來實現

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類的拷貝構造函數,

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

// 因此使用默認的拷貝構造函數即可

stk.pop(); // 刪除已經取得的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(); // 將狀態保存到CMemento對象

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

// 第一次改變狀態

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(); // 將狀態保存到CMemento對象

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

// 第二次改變狀態

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

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

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

cr.print_info();

// ... 這里不再壓棧

// 恢復到第一次狀態的改變

cr.set_memento(cs.get_memento());

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

cr.print_info();

// 恢復到初始狀態

cr.set_memento(cs.get_memento());

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

cr.print_info();

}

運行結果:

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

結果符合預期。

補充說明:

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

a. 對于C++,通常使用友元類來實現。

b. 對于C#,使用internal關鍵字。

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

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

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

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

這兩個關鍵字在實際中都是不存在的。在Java中,訪問權限修飾符權限從高到低是public,protected,package

protected,private

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

2. 關于拷貝構造函數,請看:http://patmusing.blog.163.com/blog/static/1358349602009113061024796/

3. 關于友元類,請看:http://patmusing.blog.163.com/blog/static/1358349602010182331153/



posted on 2013-03-08 14:51 Jacc.Kim 閱讀(214) 評論(0)  編輯 收藏 引用 所屬分類: 設計模式
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            先锋影音久久久| 国产精品亚洲人在线观看| 最新亚洲激情| 亚洲性夜色噜噜噜7777| 亚洲国产国产亚洲一二三| 国产午夜精品视频| 国产主播一区二区三区四区| 国产一区二区黄色| 国模叶桐国产精品一区| 亚洲高清资源| av成人激情| 欧美一区二区在线看| 欧美一区二区在线观看| 久久夜色精品亚洲噜噜国产mv| 亚洲午夜精品久久久久久app| 中文在线资源观看网站视频免费不卡 | 欧美激情亚洲自拍| 六月丁香综合| 欧美日韩国产区| 国产精品久久久久一区二区三区| 国产精品护士白丝一区av| 国产一区二区三区四区老人| 亚洲精品一区中文| 小嫩嫩精品导航| 欧美成人一区二区三区| 久久国产精品一区二区| 久久久亚洲欧洲日产国码αv| 午夜国产精品视频| 一本色道久久综合一区| 久久久99爱| 亚洲精品日韩欧美| 午夜在线a亚洲v天堂网2018| 欧美 日韩 国产一区二区在线视频 | 中文精品视频一区二区在线观看| 久久精品国产清自在天天线| 亚洲乱码日产精品bd| 久久国产精彩视频| 欧美四级在线观看| 亚洲日本在线视频观看| 久久精品99久久香蕉国产色戒| 亚洲欧洲日韩综合二区| 新片速递亚洲合集欧美合集| 国产精品福利在线观看| 99re66热这里只有精品3直播| 久久在线精品| 午夜在线电影亚洲一区| 欧美网站在线观看| av成人老司机| 亚洲精品国产日韩| 女女同性女同一区二区三区91| 免费成人av在线看| 一区二区三区高清视频在线观看 | 免费久久99精品国产| 亚洲深夜福利在线| 欧美片网站免费| 亚洲片区在线| 欧美大片免费观看| 久久亚洲捆绑美女| 狠狠色噜噜狠狠色综合久| 午夜精品久久久| 亚洲无限av看| 国产精品一区一区| 欧美专区在线观看| 亚洲欧美中文日韩在线| 国产精品视频一| 久久9热精品视频| 欧美一区不卡| 136国产福利精品导航网址| 美国成人直播| 欧美成人影音| 亚洲无线视频| 亚洲欧美日韩在线观看a三区 | 91久久精品日日躁夜夜躁国产| 蜜臀va亚洲va欧美va天堂| 久久久久久国产精品一区| 在线看片欧美| 亚洲精品视频免费| 欧美三级日本三级少妇99| 亚洲欧美精品suv| 欧美中文字幕视频在线观看| 亚洲电影免费| 日韩一级裸体免费视频| 国产精品一区二区三区乱码 | 国产亚洲一区在线播放| 美女主播一区| 欧美日韩精品是欧美日韩精品| 亚洲一区亚洲二区| 欧美一区二区高清在线观看| 亚洲电影自拍| 中文日韩欧美| 亚洲激情黄色| 亚洲淫性视频| 亚洲美女在线观看| 午夜电影亚洲| 日韩一级在线| 久久精品人人做人人综合 | 亚洲一区激情| 国外成人在线视频| 亚洲人成网在线播放| 国产精品女主播| 欧美激情综合| 国产一区导航| 在线视频亚洲欧美| 亚洲国产成人久久综合一区| 亚洲一区欧美二区| 性感少妇一区| 欧美激情中文字幕一区二区| 午夜视频在线观看一区二区| 巨胸喷奶水www久久久免费动漫| 亚洲午夜精品久久久久久浪潮| 欧美专区亚洲专区| 99精品视频免费| 久久夜色精品国产欧美乱| 亚洲欧美日韩精品久久久| 久久综合九色综合网站| 欧美亚洲在线| 国产精品成人在线观看| 亚洲国产精品一区在线观看不卡| 国产一区二区三区久久久| 99在线热播精品免费| 亚洲国产欧美一区二区三区久久| 欧美一区二区视频观看视频| 亚洲欧美另类国产| 欧美国产高潮xxxx1819| 欧美超级免费视 在线| 国产主播精品在线| 亚洲欧美成人在线| 亚洲欧美国产制服动漫| 欧美日韩在线一二三| 亚洲经典在线看| 亚洲精品久久久久久久久| 老司机午夜精品视频在线观看| 久久夜色精品国产噜噜av| 国产日韩亚洲欧美| 性高湖久久久久久久久| 久久gogo国模裸体人体| 国产精品最新自拍| 亚洲一区二区三区高清| 午夜欧美精品| 亚洲蜜桃精久久久久久久| 亚洲激情视频网站| 日韩系列在线| 久久久久久999| 久久久亚洲综合| 国产私拍一区| 欧美一区二区播放| 久久免费国产精品| 黄色成人在线网站| 久久久之久亚州精品露出| 久久一区二区三区超碰国产精品| 国产一区二区欧美日韩| 欧美一级久久久久久久大片| 久久精品麻豆| 亚洲国产二区| 欧美激情综合五月色丁香| 亚洲精品国产无天堂网2021| 亚洲中字在线| 国产在线拍偷自揄拍精品| 欧美在线播放| 亚洲夫妻自拍| 亚洲一区二区3| 国产美女在线精品免费观看| 欧美在线精品免播放器视频| 免费观看成人www动漫视频| 亚洲欧洲日产国产综合网| 久久国产精品久久w女人spa| 欧美一区二区在线观看| 亚洲国产小视频| 欧美精品一区二区三区在线播放| 一区二区欧美精品| 久久理论片午夜琪琪电影网| 在线免费一区三区| 亚洲国产专区校园欧美| 性刺激综合网| 亚洲三级影片| 久久精品国产久精国产思思| 久久午夜羞羞影院免费观看| 国产九九精品| 亚洲久久成人| 欧美成人午夜激情在线| 午夜精彩视频在线观看不卡| 国产精品国产亚洲精品看不卡15 | 欧美高清在线观看| 精品电影一区| 野花国产精品入口| 国产精品一二一区| 欧美激情精品久久久久久| 狼狼综合久久久久综合网| 亚洲国产成人在线播放| 亚洲自拍偷拍一区| 国产原创一区二区| 一区二区免费在线视频| 韩国美女久久| 亚洲欧美日韩精品一区二区| 国产曰批免费观看久久久| 一二三区精品福利视频| 亚洲久久一区二区| 欧美一区国产在线| 亚洲欧美一区二区精品久久久| 欧美伊人精品成人久久综合97|